
This example illustrates how to create custom GizmoDistribution event and object types by inheriting the gzDistEvent and gzDistObject classes. The example also shows how subscriptions are affected by subscribing on different levels in the event and object hierarchies.
The source code can also be found in the examples directory of the GizmoDistribution installation.
.
00001 //***************************************************************************** 00002 // File : hierarchy.cpp 00003 // Module : hierarchy 00004 // Description : hierarchy (example application) 00005 // Author : Anders Sandblad 00006 // Product : GizmoDistribution 00007 // 00008 // Copyright © 2004- Saab Training Systems AB, Sweden 00009 // 00010 // NOTE: GizmoDistribution is a toolkit used for implementing distributed 00011 // objects and events in C++ 00012 // 00013 // 00014 // Revision History... 00015 // 00016 // Who Date Description 00017 // 00018 // XAA 040420 Created file 00019 // 00020 //***************************************************************************** 00021 00022 // Includes 00023 #include "gzBaseLibrary.h" 00024 #include "gzDistLibrary.h" 00025 00026 00027 // Common constants 00028 static const gzString EXAMPLE_SESSION = "example"; 00029 00030 00031 //--------------------------- Object hierarchy -------------------------------- 00032 // 00033 // ---------------- 00034 // | gzDistObject | 00035 // ---------------- 00036 // ^ 00037 // | 00038 // ----------------------------------------- 00039 // | | 00040 // ----------- ----------- 00041 // | ObjectA | | ObjectB | 00042 // ----------- ----------- 00043 // ^ ^ 00044 // | | 00045 // ------------------- ------------------- 00046 // | | | | 00047 // ------------ ------------ ------------ ------------ 00048 // | ObjectA1 | | ObjectA2 | | ObjectB1 | | ObjectB2 | 00049 // ------------ ------------ ------------ ------------ 00050 // 00051 // 00052 00053 class ObjectA : public gzDistObject 00054 { 00055 public: 00056 00057 GZ_DECLARE_TYPE_INTERFACE; 00058 00059 ObjectA(const gzString& name) : gzDistObject(name) { }; 00060 00061 virtual ~ObjectA() { }; 00062 00063 virtual gzReference* clone() const 00064 { 00065 return new ObjectA(*this); 00066 } 00067 00068 }; 00069 00070 GZ_DECLARE_TYPE_CHILD(gzDistObject, ObjectA, "ObjectA"); 00071 00072 00073 class ObjectA1 : public ObjectA 00074 { 00075 public: 00076 00077 GZ_DECLARE_TYPE_INTERFACE; 00078 00079 ObjectA1(const gzString& name) : ObjectA(name) { }; 00080 00081 virtual ~ObjectA1() { }; 00082 00083 virtual gzReference* clone() const 00084 { 00085 return new ObjectA1(*this); 00086 } 00087 00088 }; 00089 00090 GZ_DECLARE_TYPE_CHILD(ObjectA, ObjectA1, "ObjectA1"); 00091 00092 00093 class ObjectA2 : public ObjectA 00094 { 00095 public: 00096 00097 GZ_DECLARE_TYPE_INTERFACE; 00098 00099 ObjectA2(const gzString& name) : ObjectA(name) { }; 00100 00101 virtual ~ObjectA2() { }; 00102 00103 virtual gzReference* clone() const 00104 { 00105 return new ObjectA2(*this); 00106 } 00107 00108 }; 00109 00110 GZ_DECLARE_TYPE_CHILD(ObjectA, ObjectA2, "ObjectA2"); 00111 00112 00113 class ObjectB : public gzDistObject 00114 { 00115 public: 00116 00117 GZ_DECLARE_TYPE_INTERFACE; 00118 00119 ObjectB(const gzString& name) : gzDistObject(name) { }; 00120 00121 virtual ~ObjectB() { }; 00122 00123 virtual gzReference* clone() const 00124 { 00125 return new ObjectB(*this); 00126 } 00127 00128 }; 00129 00130 GZ_DECLARE_TYPE_CHILD(gzDistObject, ObjectB, "ObjectB"); 00131 00132 00133 class ObjectB1 : public ObjectB 00134 { 00135 public: 00136 00137 GZ_DECLARE_TYPE_INTERFACE; 00138 00139 ObjectB1(const gzString& name) : ObjectB(name) { }; 00140 00141 virtual ~ObjectB1() { }; 00142 00143 virtual gzReference* clone() const 00144 { 00145 return new ObjectB1(*this); 00146 } 00147 00148 }; 00149 00150 GZ_DECLARE_TYPE_CHILD(ObjectB, ObjectB1, "ObjectB1"); 00151 00152 00153 class ObjectB2 : public ObjectB 00154 { 00155 public: 00156 00157 GZ_DECLARE_TYPE_INTERFACE; 00158 00159 ObjectB2(const gzString& name) : ObjectB(name) { }; 00160 00161 virtual ~ObjectB2() { }; 00162 00163 virtual gzReference* clone() const 00164 { 00165 return new ObjectB2(*this); 00166 } 00167 00168 }; 00169 00170 GZ_DECLARE_TYPE_CHILD(ObjectB, ObjectB2, "ObjectB2"); 00171 00172 00173 //--------------------------- Event hierarchy --------------------------------- 00174 // 00175 // --------------- 00176 // | gzDistEvent | 00177 // --------------- 00178 // ^ 00179 // | 00180 // --------------------------------------- 00181 // | | 00182 // ---------- ---------- 00183 // | EventA | | EventB | 00184 // ---------- ---------- 00185 // ^ ^ 00186 // | | 00187 // ------------------- ------------------- 00188 // | | | | 00189 // ----------- ----------- ----------- ----------- 00190 // | EventA1 | | EventA2 | | EventB1 | | EventB2 | 00191 // ----------- ----------- ----------- ----------- 00192 // 00193 // 00194 00195 class EventA : public gzDistEvent 00196 { 00197 public: 00198 00199 GZ_DECLARE_TYPE_INTERFACE; 00200 00201 EventA() { }; 00202 00203 virtual ~EventA() { }; 00204 00205 virtual gzReference* clone() const 00206 { 00207 return new EventA(*this); 00208 } 00209 00210 }; 00211 00212 GZ_DECLARE_TYPE_CHILD(gzDistEvent, EventA, "EventA"); 00213 00214 00215 class EventA1 : public EventA 00216 { 00217 public: 00218 00219 GZ_DECLARE_TYPE_INTERFACE; 00220 00221 EventA1() { }; 00222 00223 virtual ~EventA1() { }; 00224 00225 virtual gzReference* clone() const 00226 { 00227 return new EventA1(*this); 00228 } 00229 00230 }; 00231 00232 GZ_DECLARE_TYPE_CHILD(EventA, EventA1, "EventA1"); 00233 00234 00235 class EventA2 : public EventA 00236 { 00237 public: 00238 00239 GZ_DECLARE_TYPE_INTERFACE; 00240 00241 EventA2() { }; 00242 00243 virtual ~EventA2() { }; 00244 00245 virtual gzReference* clone() const 00246 { 00247 return new EventA2(*this); 00248 } 00249 00250 }; 00251 00252 GZ_DECLARE_TYPE_CHILD(EventA, EventA2, "EventA2"); 00253 00254 00255 class EventB : public gzDistEvent 00256 { 00257 public: 00258 00259 GZ_DECLARE_TYPE_INTERFACE; 00260 00261 EventB() { }; 00262 00263 virtual ~EventB() { }; 00264 00265 virtual gzReference* clone() const 00266 { 00267 return new EventB(*this); 00268 } 00269 00270 }; 00271 00272 GZ_DECLARE_TYPE_CHILD(gzDistEvent, EventB, "EventB"); 00273 00274 00275 class EventB1 : public EventB 00276 { 00277 public: 00278 00279 GZ_DECLARE_TYPE_INTERFACE; 00280 00281 EventB1() { }; 00282 00283 virtual ~EventB1() { }; 00284 00285 virtual gzReference* clone() const 00286 { 00287 return new EventB1(*this); 00288 } 00289 00290 }; 00291 00292 GZ_DECLARE_TYPE_CHILD(EventB, EventB1, "EventB1"); 00293 00294 00295 class EventB2 : public EventB 00296 { 00297 public: 00298 00299 GZ_DECLARE_TYPE_INTERFACE; 00300 00301 EventB2() { }; 00302 00303 virtual ~EventB2() { }; 00304 00305 virtual gzReference* clone() const 00306 { 00307 return new EventB2(*this); 00308 } 00309 00310 }; 00311 00312 GZ_DECLARE_TYPE_CHILD(EventB, EventB2, "EventB2"); 00313 00314 00315 //------------------------------- Publisher ----------------------------------- 00316 00317 // A client that publish objects and events of different types 00318 class Publisher : public gzDistClientInterface 00319 { 00320 public: 00321 00322 Publisher(); 00323 00324 virtual ~Publisher(); 00325 00326 00327 private: 00328 00329 // callbacks 00330 00331 gzVoid onClientTick(); 00332 00333 gzVoid onSystemShutdown(); 00334 00335 00336 private: 00337 00338 // members 00339 00340 gzDistSessionPtr m_session; 00341 00342 gzULong m_tickCount; 00343 00344 }; 00345 00346 00347 Publisher::Publisher() 00348 : gzDistClientInterface("publisher"), 00349 m_tickCount(0) 00350 { 00351 // initialize client 00352 initialize(1); 00353 00354 // create and join session 00355 m_session = getSession(EXAMPLE_SESSION, TRUE); 00356 joinSession(m_session); 00357 00358 00359 // add an object of every type 00360 addObject(new gzDistObject("base"), m_session); 00361 addObject(new ObjectA("a"), m_session); 00362 addObject(new ObjectA1("a1"), m_session); 00363 addObject(new ObjectA2("a2"), m_session); 00364 addObject(new ObjectB("b"), m_session); 00365 addObject(new ObjectB1("b1"), m_session); 00366 addObject(new ObjectB2("b2"), m_session); 00367 00368 } 00369 00370 00371 Publisher::~Publisher() 00372 { 00373 // resign the session 00374 resignSession(m_session); 00375 00376 // uninitialize client 00377 uninitialize(); 00378 } 00379 00380 00381 gzVoid Publisher::onClientTick() 00382 { 00383 // send an event of every type 00384 sendEvent(new gzDistEvent, m_session); 00385 sendEvent(new EventA, m_session); 00386 sendEvent(new EventA1, m_session); 00387 sendEvent(new EventA2, m_session); 00388 sendEvent(new EventB, m_session); 00389 sendEvent(new EventB1, m_session); 00390 sendEvent(new EventB2, m_session); 00391 00392 } 00393 00394 00395 gzVoid Publisher::onSystemShutdown() 00396 { 00397 // in case of pre-mature shutdown 00398 m_session = NULL; 00399 } 00400 00401 00402 //------------------------------- Subscriber ---------------------------------- 00403 00404 // A client that subscribe obejects and attributes 00405 class Subscriber : public gzDistClientInterface 00406 { 00407 public: 00408 00409 Subscriber(); 00410 00411 virtual ~Subscriber(); 00412 00413 00414 private: 00415 00416 // callbacks 00417 00418 gzVoid onClientTick(); 00419 00420 gzVoid onEvent(gzDistEvent* event); 00421 00422 gzVoid onNewObject(gzDistObject* object, gzDistSession* session); 00423 00424 gzVoid onRemoveObject(gzDistObject* object, gzDistSession* session); 00425 00426 gzVoid onSystemShutdown(); 00427 00428 00429 private: 00430 00431 // members 00432 00433 gzDistSessionPtr m_session; 00434 00435 gzULong m_tickCount; 00436 00437 }; 00438 00439 00440 Subscriber::Subscriber() 00441 : gzDistClientInterface("subscriber"), 00442 m_tickCount(0) 00443 { 00444 // initialize client 00445 initialize(1); 00446 00447 // create and join session 00448 m_session = getSession(EXAMPLE_SESSION, TRUE); 00449 joinSession(m_session); 00450 00451 } 00452 00453 00454 Subscriber::~Subscriber() 00455 { 00456 // resign the session 00457 resignSession(m_session); 00458 00459 // uninitialize client 00460 uninitialize(); 00461 } 00462 00463 00464 gzVoid Subscriber::onClientTick() 00465 { 00466 if (! m_session) 00467 { 00468 return; 00469 } 00470 00471 switch (m_tickCount) 00472 { 00473 case 0: 00474 { 00475 // EventA and events below will be received 00476 GZMESSAGE(GZ_MESSAGE_NOTICE, "Subcribing EventA"); 00477 subscribeEvents(EventA::getClassType(), m_session); 00478 00479 } 00480 break; 00481 00482 case 2: 00483 { 00484 GZMESSAGE(GZ_MESSAGE_NOTICE, "Unsubcribing EventA"); 00485 unsubscribeEvents(EventA::getClassType(), m_session); 00486 00487 // EventB1 will be received 00488 GZMESSAGE(GZ_MESSAGE_NOTICE, "Subcribing EventB1"); 00489 subscribeEvents(EventB1::getClassType(), m_session); 00490 } 00491 break; 00492 00493 case 4: 00494 { 00495 GZMESSAGE(GZ_MESSAGE_NOTICE, "Unsubcribing EventB1"); 00496 unsubscribeEvents(EventB1::getClassType(), m_session); 00497 00498 // ObjectA and objects below will be received as new 00499 GZMESSAGE(GZ_MESSAGE_NOTICE, "Subcribing ObjectA"); 00500 subscribeObjects(ObjectA::getClassType(), m_session, TRUE); 00501 00502 } 00503 break; 00504 00505 case 6: 00506 { 00507 GZMESSAGE(GZ_MESSAGE_NOTICE, "Unsubcribing ObjectA"); 00508 unsubscribeObjects(ObjectA::getClassType(), m_session); 00509 00510 // ObjectA1 will be received as new 00511 GZMESSAGE(GZ_MESSAGE_NOTICE, "Subcribing ObjectA2"); 00512 subscribeObjects(ObjectA2::getClassType(), m_session, TRUE); 00513 00514 } 00515 break; 00516 00517 case 8: 00518 { 00519 GZMESSAGE(GZ_MESSAGE_NOTICE, "Unsubcribing ObjectA2"); 00520 unsubscribeObjects(ObjectA2::getClassType(), m_session); 00521 00522 // All objects will be received as new 00523 GZMESSAGE(GZ_MESSAGE_NOTICE, "Subcribing gzDistObject"); 00524 subscribeObjects(gzDistObject::getClassType(), m_session, TRUE); 00525 00526 } 00527 break; 00528 00529 } 00530 00531 ++m_tickCount; 00532 00533 } 00534 00535 00536 gzVoid Subscriber::onEvent(gzDistEvent* event) 00537 { 00538 GZMESSAGE(GZ_MESSAGE_NOTICE, "Received event of type '%s'", event->getTypeName()); 00539 } 00540 00541 00542 gzVoid Subscriber::onNewObject(gzDistObject* object, gzDistSession* session) 00543 { 00544 GZMESSAGE(GZ_MESSAGE_NOTICE, "New object of type '%s'", object->getTypeName()); 00545 } 00546 00547 00548 gzVoid Subscriber::onRemoveObject(gzDistObject* object, gzDistSession* session) 00549 { 00550 GZMESSAGE(GZ_MESSAGE_NOTICE, "Removed object of type '%s'", object->getTypeName()); 00551 } 00552 00553 00554 gzVoid Subscriber::onSystemShutdown() 00555 { 00556 // in case of pre-mature shutdown 00557 m_session = NULL; 00558 } 00559 00560 00561 //---------------------------------- main ------------------------------------- 00562 00563 // Application entry point 00564 int main(int argc, char* argv[]) 00565 { 00566 // setup default message receiver 00567 gzMessage::setMessageLevel(GZ_MESSAGE_NOTICE); 00568 00569 // create manager and start 00570 gzDistManagerPtr manager = gzDistManager::getManager(TRUE); 00571 manager->start(); 00572 00573 // register factories for all custom object types 00574 // factories are used by the kernel to create 00575 // new objects on global sessions 00576 manager->registerFactory(new ObjectA(GZ_EMPTY_STRING)); 00577 manager->registerFactory(new ObjectA1(GZ_EMPTY_STRING)); 00578 manager->registerFactory(new ObjectA2(GZ_EMPTY_STRING)); 00579 manager->registerFactory(new ObjectB(GZ_EMPTY_STRING)); 00580 manager->registerFactory(new ObjectB1(GZ_EMPTY_STRING)); 00581 manager->registerFactory(new ObjectB2(GZ_EMPTY_STRING)); 00582 00583 // register factories for all custom event types 00584 // factories are used by the kernel to create 00585 // events on global sessions 00586 manager->registerFactory(new EventA); 00587 manager->registerFactory(new EventA1); 00588 manager->registerFactory(new EventA2); 00589 manager->registerFactory(new EventB); 00590 manager->registerFactory(new EventB1); 00591 manager->registerFactory(new EventB2); 00592 00593 // create clients 00594 Subscriber* subscriber = new Subscriber; 00595 gzSleep(GZ_SLEEP_SECOND); 00596 Publisher* publisher = new Publisher; 00597 00598 00599 // run a while 00600 gzSleep(10 * GZ_SLEEP_SECOND); 00601 00602 00603 // delete clients 00604 delete publisher; 00605 gzSleep(GZ_SLEEP_SECOND); 00606 delete subscriber; 00607 00608 // shut down and release manager 00609 manager->shutDown(); 00610 manager = NULL; 00611 00612 gzSleep(GZ_SLEEP_SECOND); 00613 00614 return 0; 00615 00616 } 00617