Next: Das Hauptprogramm Up: KPH 11/93Implementation und Testder Previous: Deklaration der Klassenhierarchie

Implementation der Klassen

Zuerst wird mit dem Makro DEF_SERV_CONS der Konstruktor der Serviceklasse TestDev definiert. Hier werden mit dem C++-Operator new Instanzen der drei Aktionen erzeugt und mit der Funktion add in den Service eingegliedert.


DEF_SERV_CONS(TestDev, "TEST")
{
  add(new IstSet(IST, *this));
  add(new IstGet(IST, *this));
  add(new SqrtGet(SQRT, *this));
}

Die Konstruktoren für die drei Aktionen haben mit den Makros DEF_ACT_CONS alle die gleiche Form.


DEF_ACT_CONS(TestDev, IstSet, SET){};
DEV_ACT_CONS(TestDev, IstGet, GET){};
DEV_ACT_CONS(TestDev, SqrtGet, GET){};

Die erste Aktion für das Einstellen des Sollwertes benötigt, wie oben erwähnt, eine Initfunktion. Hier wird mit der Datenbankfunktion getrange der minimal und der maximal zulässige Eingabewert ermittelt.


void TestDev::IstSet::init()
{
  Range range = *db.getrange(get_db_key());

  max = range.maximum;
  min = range.minimum;
}

Die eigentliche Aktion wird in der Funktion run ausgeführt. Diese Funktion erhält als Übergabeparameter die Nachricht. Beim Einstellen des Wertes steht diese Zahl in der Nachricht verpackt und kann mit der Funktion get_aPhysicalData ausgepackt werden. Falls die Nachricht einen falschen Datentyp erhält, wird die Funktion run abgebrochen. Danach wird überprüft, ob die Eingabegrenzen eingehalten wurden. Wenn nicht, wird über die Klasse error eine Fehlermeldung ausgegeben. War alles soweit erfolgreich, wird mit der Methode set_value der Klasse TestDev der Wert gesetzt und ein Statusbericht an den opcon gesendet. Um an diese Methoden heranzukommen, muß mit der Funktion get_service ein Verweis auf den Service geholt werden.


int TestDev::IstSet::run(MpxMessage &message)
{
  TestDev *test = (TestDev *)get_service();

  aPhysicalData *phys_data = message.get_aPhysicalData();
  if (phys_data == NULL)
  {
    error << "invalid data type " << level(0)
          << endl;
    return ERROR;
  }
  if (phys_data->val > max)
  {
    error << "value too high " << phys_data->val << " (" << max
          << ") " << level(0) << endl;
    return ERROR;
  }
  else if (phys_data->val < min)
  {
    error << "value too low " << phys_data->val << " (" << min
          << ") " << level(0) << endl;
    return ERROR;
  }

  test->set_value(phys_data->val);
  test->send_status_report(message);

  return NOERROR;
}

Die Aktion IstGet hat einen ähnlichen Ablauf, nur daß sie keine Nachricht empfängt, sondern eine verschickt. Deshalb wird mit aPhysicalData_new ein Platzhalter für ein Datum erzeugt und mit get_value der Wert eingetragen. phytoi(no) legt fest, daß der Wert keine Einheit hat. Dann werden mit set_aPhysicalData die Daten in die Nachricht verpackt.


int TestDev::IstGet::run(MpxMessage &message)
{
  TestDev *test = (TestDev *)get_service();

  aPhysicalData* phys_data = aPhysicalData_new();
  phys_data->val = test->get_value();
  phys_data->dim = phytoi(no);

  message.set_aPhysicalData(phys_data);
  test->send_status_report(message);

  return NOERROR;
}

Die letzte Aktion unterscheidet sich von der vorherigen nur durch die Zeile, die den Wert einträgt.


  .
  .
  phys_data->val = sqrt(test->get_value());
  .
  .

Damit ist die Implementation der Klassen abgeschlossen, und es fehlt noch das Hauptprogramm.


martin@daisy.zdv.Uni-Mainz.DE
Fri Apr 21 10:02:42 MESZ 1995