3D PLM Enterprise Architecture |
Middleware Abstraction - ENOVIA Event Model |
The ENOVIA Event ModelImportant concepts about publishing events in ENOVIA V5 |
Technical Article |
AbstractThis article describes, in the ENOVIA V5 event model context, the methodology to declare and raise events (Publisher side). |
Each domain in ENOVIA (PRODUCT, CONFIG, etc.) declares its data strucutre in a XML file,named "DomainName".metadata.
In the same way, all the specific events that objects of that domain will raise are described in another XML file: "DomainName".event.
Note: By convention, the name of the event will be the same as the C++ method name in which the event is really raised.
Examples:
[Top]
When you want an object to raise event, you have to describe a set of attributes:
Added to those definitions, people may want to transmit additional information when an event is raised, or getting information from subscribers : this can be done by datastreams. The format of such entities is also described in the XML file,before declaration of events.
[Top]
A data stream is a set of ordered attributes which will be filled before raising the event in the C++ code. The declaration consists in a Name, then a list of attributes determined by their name and type.
Example: If you define an event "MoveFile", raised in a method MoveFile (moving a file from one directory to another, you want to send also 3 data:
This can be done by declaring a stream MoveFileStream which contains 3 string arguments FileName,SourceDir,TargetDir to the event the 3 data : name of the file to be moved, source directory and target directory, and then referencing that stream in the "MoveFile" event declaration.
[Top]
An event declaration file generally has the following format:
<Package Name="..."> <DataStream Name="..."> <DataStreamArg Name="..." Type="..."> </DataStreamArg>.... </DataStream> <Class Name="..." Type="..."> <Event Name="..." ...> <DataStreamRef Name="..." <!-- if a stream is associated with the event --> Type="..." </DataStreamRef> </Event> </Class> </Package> |
[Top]
Attribute Name | Value | Meaning |
---|---|---|
Name | mandatory attribute | Domain name |
Attribute Name | Value | Meaning |
---|---|---|
Name | mandatory attribute | Name given to the data stream |
Attribute Name | Value | Meaning |
---|---|---|
Name | mandatory attribute | Name given to the argument |
Type | mandatory attribute Byte Short Int Float Double String ObjRef FixedByteArray FixedShortArray FixedIntArray FixedFloatArray FixedDoubleArray FixedStringArray FixedObjRefArray |
Type of the argument. |
Attribute Name | Value | Meaning |
---|---|---|
Name | mandatory attribute | Type of object raising events |
Type | Real Late [default value] |
Type coming from a true C++ class or from an Enovia Late Type |
Attribute Name | Value | Meaning |
---|---|---|
Name | mandatory attribute | Name of event to be raised by the object class. |
Mode | Private Protected Public [default] |
This is the visibility of the event towards subscription : Is
the event visible: - only inside the domain - by subscribers coming from "inheriting" domains - by any subscriber class |
Before | Yes [default] No |
Is there a step "before" in the event raise (when entering the object's method)? |
After | Yes [default] No |
Is there a step "after" in the event raise (when exiting the object's method)? |
Veto | mandatory attribute Yes [implies Before=Yes] No |
Can the event be vetoed by a subscriber? |
Persistent | Yes [defaut] No |
Will the event be saved in a database at login session save? |
EventInterface | mandatory attribute | Name of the callback interface that a client object must implement to be able to subscribe to that event |
Attribute Name | Value | Meaning |
---|---|---|
Name | mandatory attribute | Name of the data stream referenced previously in the same XML file |
Type | Publisher/Client | Is the stream filled by the publisher or by the clients ? |
[Top]
The subscription of a client is done by calling one of the dedicated methods of the event manager associated with each session. The mandatory argument in those methods is a pointer on an interface, implemented by the client object. When the event occurs, the system calls,for each client which subscribed to that event, the right method of the interface associated with that event (see 2.2).
Two kinds of "callback" interfaces are available:
onBefore"EventName"(...)
onAfter"EventName"(...)
for an event which has been declared with two steps.
So the client object which implements such an interface knows exactly for which event and at which step it is called.
The domains design the grouping of their event callback methods. They can choose to group all the methods in one single interface, or create several interfaces with a small number of events concerned with each interface.
[Top]
The rules are the following:
onBeforeMyEvent(const ENOVIEvent_var& iEvent, HRESULT&
ioReturnCode)
onAfterMyEvent(const ENOVIEvent_var& iEvent, HRESULT&
ioReturnCode)
onKO(ENOVIEvent_var iEvent, HRESULT
ioRetCode)
method used for event management: when something wrong
occurs during the event emission, the subscriber is called back using this
method.Note: A client object will always be able to subscribe to the event by implementing the generic interface ENOVISubscriberEvent.>
[Top]
The emission of events is rather simple to do, and based on Macros delivered by the event model. in each cpp file where there are "event" methods, you must insert an include :
#include ENOVEventFireMacro.h |
Then,in each method which has to raise an event , you insert the macro EVENT_FIRE(...) 2 times, one at the beginning of the method, the second one at the end of the method.By doing that, at run time, the event will be raised in its step before when entering the method, and the step after will be sent when exiting the method.
Example
Let's take a class SamplePublisher which has declared a new
event SampleEvent.
This event is declared before/after and the associated callback interface is SampleInterface.
In the cpp code SamplePublisher.cpp, there will be a method SampleEvent
.
The code could as follows.
#include ENOVEventFireMacro.h ... HRESULT SamplePublisher::SampleEvent(...) { HRESULT rc=S_OK,oNotify=S_OK; ENOVIStream_var spClientStream=NULL_var; //event [before step] EVENT_FIRE(SamplePublisher,SampleEvent,IID_SampleInterface,Before,spClientStream,oNotify); // code of the method ... // event [after step] EVENT_FIRE(SamplePublisher,SampleEvent,IID_SampleInterface,After,oStream,oNotify); return rc; } |
The arguments of the macro are:
If the event is declared with a reference on a publisher data stream, this stream must be filled before the first macro EVENT_FIRE insertion.
To do that , use the DATA_EVENT_INIT macro, which gives back a smart pointer on ENOVIStream, already dimensioned according to the data stream definition in the XML declaration file. Then, the code fills the stream using the methods of the ENOVIStream interface. When the event is raised, the system automatically associates the stream and the event.
Example
Let's take the same example as above. The method has 3 string arguments iA iB iC, and a stream SamplePStream,declared with 3 string arguments "Arg1" "Arg2" "Arg3" was associated with event SampleEvent.
In the cpp code SamplePublisher.cpp, the code could be as follows.
#include ENOVEventFireMacro.h ... HRESULT SamplePublisher::SampleEvent(const CATUnicodeString& iA, const CATUnicodeString& iB, const CATUnicodeString& iC) { HRESULT rc=S_OK,oNotify=S_OK; ENOVIStream_var spPublihStream=NULL_var,spClientStream=NULL_var; // instantiation of a well dimensionned stream, according to // the declaration in XML event files... EVENT_DATA_INIT(SamplePSStream,spPublishStream); ...// checks the smart pointer... //fill the stream will the data sPublishStream->AddArgumentValue("Arg1",iA); sPublishStream->AddArgumentValue("Arg2",iB); sPublishStream->AddArgumentValue("Arg3",iC); //raise the event. The stream is automatically linked with the event EVENT_FIRE(SamplePublisher,SampleEvent,IID_SampleInterface,Before,spClientStream,oNotify); ... } |
[Top]
The Event Model use cases accompanying this technical article illustrate the 2 different mechanisms for automatic subscription at the creation of an ENOVIA login session.
1. | CAAVpiAutomaticSubscription |
1. | CAAVpiAutomaticSubscription2 |
2. | CAAVpiPackageSubscription |
[Top]
In this article you have learned how the events are declared and raised, from the publisher point of view, and how it's able to subscribe to those events and be called back when an event occurs.
[Top]
Version: 1 [Oct 2001] | Document created |
[Top] |
Copyright © 2001, Dassault Systèmes. All rights reserved.