Table of Contents

Event-Handler explizit aufrufbar

Informationen

  • Kategorien: Kernel | Klassenformeln
  • Version: 21.0.0.11226
  • Veröffentlichungsdatum: Freitag, 11. November 2016
  • Entwickler: Fischer
  • Benötigt Datenbankänderung: Nein
  • Betreff: Event-Handler sind jetzt Funktionen.

Beschreibung

Event-Handler können jetzt wie jede andere Funktion in Klassenformeln explizit aufgerufen werden. Vorhandene Event-Handler werden im Funktionsauswahl-Dialog unter [Event] aufgelistet.

Allgemeine Beschreibung von Event-Handler:

Event-Handler ermöglichen dem Anpasser auf Ereignisse (Events) im pit-IS Kern zu reagieren. Ihr Name setzt sich aus dem Prefix "onEvent_" und dem Namen des Events zusammen. (Beispiel: Für das Event 'EntityStoring' lautet der Name des Event-Handler 'onEvent_EntityStoring')

Events sind im Kern immer dann implementiert, wenn eine projektspezifisch anpassbare Teilfunktionalität eines im Kern ausgeführten komplexeren Algorithmus aufgerufen werden soll.

Wird das Event ausgelöst sucht der Kern nach einem passenden Event-Handler. Ist das Event Entity-spezifisch, so wird zuerst der Event-Handler der Entity-Klasse gesucht. Ist dieser nicht implementiert, so wird in den Basisklassen gesucht (den Ableitungsbaum absteigend). Wird kein Event-Handler gefunden, erfolgt die (im Kern implementierte) Standard-Reaktion auf das Event.

Ansonsten wird der erste gefundene Event-Handler aufgerufen. Sind weitere Basisklassen-Event-Handler implementiert, so werden diese nicht aufgerufen !

Wichtig: Es liegt in der Verantwortung des Programmierers innerhalb des Event-Handler-Codes bei Bedarf weitere Basisklassen-Event-Handler aufzurufen. Dies kann nicht durch den Kern übernommen werden, da dieser nicht entscheiden kann ob und wann welcher Basisklassen-Event-Handler aufzurufen ist.

In bisherigen Versionen des pit-IS Kern war es nicht möglich innerhalb einer Klassenformeln einen Event-Handler aufzurufen. Nur der Kern konnte Event-Handler aufrufen. Um diese Einschränkung zu umgehen wurde üblicherweise der Code des Event-Handler in eine Funktion ausgelagert. Der Event-Handler selbst ruft nur diese Funktion auf. Sollte nun ein Basisklassen-Event-Handler aufgerufen werden, wurde statt dessen die zugehörige Funktion aufgerufen. (Siehe im Beispielcode ab // similar solution for older kernel versions)

Durch eine Änderung im Design existiert diese Einschränkung nicht mehr, Event-Handler sind jetzt selbst Funktionen.

Aufruf (Syntax): Nicht Entity-spezifisches Event: der Event-Handler wird durch seinen Namen aufgerufen (z.B. 'onEvent_DeletingEntities()'). Entity-spezifisches Event: Aufruf durch Klasse und Namen des Event-Handlers in Form '::::' (z.B. '::Device::onEvent_EntityStoring()').

Es können nur vorhandene Event-Handler aufgerufen werden. Wird z.B. ::Device::onEvent_EntityStoring() aufgerufen und für Klasse 'Device' ist kein Event-Handler implementiert, so wird eine Fehlermeldung ausgegeben (function not found). Es wird nicht in Basisklassen gesucht.

Neue Fehlermeldungen/Warnungen des Compilers: Es wird eine Warnung (warning 20: SuspiciousCallOfEventHandler) ausgegeben, falls aus einem Event-Handler ein Event-Handler desselben Events mit folgender Eigenschaft aufgerufen wird:

  • es ist derselbe Event-Handler (rekursiver Aufruf)
  • es ist ein kein Event-Handler einer Basisklasse.

Zusätzlich finden die bei Funktionsaufrufen üblichen Überprüfungen durch den Compiler statt.

Beispielcode

// event handler for class 'Ventilator' (derivation tree: Ventilator-Device-Inventory-Root)
	
void onEvent_EntityStoring()
{
	// take special actions for 'Ventilator' before any 'Device' actions take place
	//
	// ...
	
	if ( TreatThisVentilatorAsNormalDevice() )
	{
		// call event handler of direct base class 
		//
		::Device::onEvent_EntityStoring();
	}
	else
	{
		// call event handler of indirect base class (skip Device event handler)
		//
		::Inventory::onEvent_EntityStoring();
		
		// take special actions for this device
		//
		// ...
	}

	// take special actions for 'Ventilator' after any 'Device' actions took place
	//
	// ...
}


// similar solution for older kernel versions (by defining a function to every event handler):
//
void onEvent_EntityStoring()
{
	// just call the function to do the work.
	//
	Ventilator_onEvent_EntityStoring( this );
}

// explicit function doing the work of the event handler
//
void Ventilator_onEvent_EntityStoring( entity $This )
{
	// take special actions for 'Ventilator' before any 'Device' actions take place
	//
	// ...
	
	if ( TreatThisVentilatorAsNormalDevice() )
	{
		// call event handler of direct base class 
		//
		Device_onEvent_EntityStoring( $This );
	}
	else
	{
		// call event handler of indirect base class (skip Device event handler)
		//
		Inventory_onEvent_EntityStoring( $This );
		
		// take special actions for this device
		//
		// ...
	}

	// take special actions for 'Ventilator' after any 'Device' actions took place
	//
	// ...
}