summaryrefslogtreecommitdiff
path: root/TAO/examples/OBV/Typed_Events/Event_Types.idl
blob: 40c167d1250239c286b9b0c37a130f019389b2f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// Event_Types.idl
// Simple demonstration of typed events in a distributed system.
//
// Author:
//   Torsten Kuepper
//

// $Id$

// Event inheritance hierarchy  ===========================

// Base class  --------------------------------------------

valuetype Event
{
  void do_print ();

  // An operation. In some implementations (e.g. operator terminal)
  // the event should visualize itself. That is of no use at the
  // event producing sensor. So, the declaration of do_print ()
  // could be deferred to the implementation classes, but then you need
  // to downcast from the pointer to the event valuetype to your
  // implementation. Another solution is perhaps to inherit do_print ()
  // through an additional abstract valuetype base only in that
  // IDL that a visualizing implementation sees. But this would change
  // the type and this is a bad thing. The cleanest thing to do may be
  // to apply the visitor pattern. Event::accept (visitor) would be
  // implemented as null-op in the measurement device, if you take this
  // example.


  public long time_;

  // A state member. Don't confuse with attributes, which are
  // ok here too, but they do only map to a pair of local operations,
  // in opposite to (public/private) state members they haven't got no
  // implementation for the state data and finally they are not transmitted
  // over the wire.


  public unsigned long origin_id_;

  // This id should identify the origin (e.g. sensor) in the system.
  // This makes an id-space beside the object references which has to be
  // maintained. It would be useful to implement some consistency check
  // protocol (as CORBA interfaces) to verify that the suppliers and
  // consumers are connected (through some event channel) in the
  // right way.

};


// Derived Events  ----------------------------------------


valuetype Temperature : Event
{
  // do_print () is overridden in the implementation. We can't
  // tell this in IDL, because operations can't be declared again.
  // They are implicit assumed to be polymorph.

  public float temperature_;
  // Extends Event with the state member for the temperature.
};


typedef float Point[3];
// (anonymous arrays are not yet working in this OBV ...%!)
// (( BTW %! <- no emoticon, this is my to do mark))

valuetype Position : Event
{
  attribute float x, y, z;
  // The Position can be accessed both through the coordinates ...

  public Point xyz;
  // ... or as a whole array, which is a state member.
};


valuetype Log_Msg : Event
{
  public short  urgency;
  public string message;
};

// (Valuetypes which hold other types as shown are not yet tested %!)

// You may extend the system with aggregated events, such the status
// message of a boiler, which has temperature and a pressure valuetype
// as state member (recall: unshared valuetypes are well at this time.
// But a shared valuetype splits at the receiving end of an invocation
// in two or more instances, dependend on the number of references on it
// (in the argument list plus in the members of compound types). This
// misbehaviour will go away once valuetype sharing is implemented %!
// But to do this in an efficient and thread safe manner seems a little tricky)


// Passing back the critical events in a list  ----------------------------

// This is the link, that is used internally -----
// (should come after Event_List, but forward decl. is not yet complete %!)

valuetype Event_List_Link
{
  Event get_event ();
  // get the event

  Event_List_Link get_next_link ();
  // get the event

  void attach_next_link (in Event_List_Link chain);
  // Link a chain at the end.

  private Event my_event;
  // event which is held

  private Event_List_Link next;
  // link to the next event container
};

// 'private' state member are mapped to 'protected' in C++, so
// they can be accessed from the implementation class, which should
// be derived from OBV_Event_chain.


// The event list uses links as declared above. But its implementation
// could be changed 'under the hood' to use e.g. a CORBA sequence.
// (This doesn't go yet, because valuetype is only allowed
// as an operation argument for now. Just impl. the visitors in tao_idl %!)

valuetype Event_List
{
  void store_event (in Event e);
  // Attach an event at the lists's end.

  public Event_List_Link first_link;
  // Should better be private, but then the iterator can't access it.
};


// Interface to access the "event server" ------------------

// A client (e.g. sensor) delivers the events via put_event ().
// The server checks against alarm conditions and memorizes
// critical events, which can be passed back
// to a client (e.g. operator terminal) with get_critical_events ().

interface Checkpoint
{
  void  put_event (in Event e);
  // Put event in the server. If it exceeds an alarm criterion
  // it will be stored.

  Event_List  get_critical_events ();
  // Ask for a list of critical events.

  oneway void shutdown ();
  // This operation will shutdown the server.
};


// Checkpoint server side --------------------------------------------
// The Checkpoint should compare the incoming event against a
// criterion for the specific event type. My approach is the following
// (to facilitate separation of application logic and event specific
// code): An abstract valuetype Criterion provides is_critical () to check
// against a boundary. Concrete alarm boundaries for any existing
// event derive from this class and perform the check. Thats's it for
// the event type maintainer --- the customs that use this 'framework'.

// The concrete criterions inherit from Event too. I wanted to reuse
// the list which works on events. The wrapper Criterion_List makes it safe
// that only criterions are accepted to this list. Templates would be fine,
// but currently I have no idea how to apply them to a valuetype. Perhaps
// there is no way to get around custom marshalling [n.y.avail.%!] in the
// area of containers.
// Finally the concrete criterions must have a suitable implementation for
// is_critical ().

// Now the internals of the server which shouldn't need to be touched by
// the final implementer: The above mentioned wrapper Criterion_List
// uses an Event_List to compare an incoming event against the
// boundaries. In this simple example it will just apply the event to
// is_critical () of any criterion, which origin id matches.
// The criterion checks with
// valuetype's _downcast () if the event matches its event type and then
// performs the alarm check. A real world approach with many event types
// and criterions could better use a hash map for the criterions. The
// external map index would be the repository id of the event.

abstract valuetype Criterion
{
  boolean is_critical (in Event e);
  // Check against alarm boundaries.
};


// The specialized criterions. Note: A valuetype can only inherit
// from one non-abstract other valuetype (which then must be the first
// one listed). Further Criterions may only be abstract valuetypes
// without the ability to contain state members. (The support of
// a CORBA interface is not yet supported.)
// P.S. Please don't bother about the class hierarchy
// (Criterion inherits from Event _and_ has some Events as boundary values
// aggregated). I just wanted to reuse the code for the list of events.
// Certainly not an example of good OO design.


valuetype Temperature_Criterion : Event, Criterion
{
  private Temperature meltingpoint;
  // The boundary is stored in a state member.
};


valuetype Position_Criterion : Event, Criterion
{
  private Position leftbottom, topright;
  // Any position should be contained in a box.
};


valuetype Log_Msg_Criterion : Event, Criterion
{
  // No state member. All Log_Msg which have urgency
  // greater zero meet the criterion.
};



// The Criterion_List  ===========================================

valuetype Criterion_List
{
  void store_criterion (in Criterion c);
  // Attach an criterion at the lists's end.

  boolean is_critical (in Event e);
  // Check with the listmembers if e should raise an alarm.

  public Event_List my_list;
  // Used in the implementation. Is public for allowing
  // access to the iterator.
};