GizmoDistribution

hierarchy.cpp

Hierarchy example application.

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 

Documentation for GizmoDistribution generated at Wed Feb 20 11:59:21 2008 by   Saab Training Systems AB, ¸ (c) 2003-and beyond