GizmoDistribution

subscriptions.cpp

Subscriptions example application.

This example illustrates how to use different types of subscriptions in GizmoDistribution clients. A subscriber client start by subscribing for sessions and a publisher client perform actions. When a new session is created, the subscriber will join and subscribe for new events and objects. When a new object is added, the subscriber will subscribe for new attributes. When new attributes are added, the subscriber will subscribe for value updates, etc.

The source code can also be found in the examples directory of the GizmoDistribution installation.

.

00001 //*****************************************************************************
00002 // File         : subscriptions.cpp
00003 // Module       : subscriptions
00004 // Description  : subscriptions (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  040419  Created file    
00019 //
00020 //*****************************************************************************
00021 
00022 // Includes
00023 #include <stdio.h>
00024 #include "gzBaseLibrary.h"
00025 #include "gzDistLibrary.h"
00026 
00027 // Session name
00028 static const gzString A_SESSION = "A";
00029 static const gzString B_SESSION = "B";
00030 static const gzString C_SESSION = "C";
00031 
00032 
00033 //----------------------------- Publisher -------------------------------
00034 
00035 // A client that publish events, objects and attribute updates
00036 class Publisher : public gzDistClientInterface
00037 {
00038     public:
00039 
00040         explicit Publisher(const gzString& sessionName);
00041 
00042         virtual ~Publisher();
00043 
00044 
00045     private:
00046 
00047         // thread ticker callback
00048                 
00049         gzVoid onClientTick();
00050 
00051 
00052         // notification callbacks
00053 
00054         gzVoid onNewObject(gzDistObject* object, gzDistSession* session);
00055 
00056         gzVoid onRemoveObject(gzDistObject* object, gzDistSession* session);
00057 
00058         gzVoid onSystemShutdown();
00059 
00060 
00061     private:
00062 
00063         // members
00064 
00065         gzULong m_tickCount;
00066 
00067         gzBool m_add;
00068 
00069         gzString m_sessionName;
00070 
00071         gzDistSessionPtr m_session;
00072 
00073         gzRefList<gzDistObject> m_objects;
00074 
00075 };
00076 
00077 
00078 Publisher::Publisher(const gzString& sessionName)
00079  :  gzDistClientInterface(sessionName + gzString("_publisher")),
00080     m_tickCount(0),
00081     m_add(FALSE),
00082     m_sessionName(sessionName)
00083 {
00084     // initialize client
00085     initialize(2);
00086 
00087     // create session
00088     m_session = getSession(sessionName, TRUE);
00089     joinSession(m_session);
00090     subscribeObjects(gzDistObject::getClassType(), m_session);
00091 
00092 }
00093 
00094 
00095 Publisher::~Publisher()
00096 {
00097     // uninitialize client
00098     uninitialize();
00099 }
00100 
00101 
00102 gzVoid Publisher::onClientTick()
00103 {
00104     if (!m_session)
00105     {
00106         return;
00107     }
00108 
00109     if (m_tickCount%5 == 0)
00110     {
00111         // add / remove objects
00112 
00113         if (m_add)
00114         {
00115             // first add 4 objects...
00116 
00117             if (m_objects.entries() < 5)
00118             {
00119                 gzDistObjectPtr object = new gzDistObject(m_sessionName + gzString(m_objects.entries()));
00120                 object->setAttributeValue(gzString(m_tickCount%5), gzString(m_tickCount));
00121                 addObject(object, m_session);
00122             }
00123             else
00124             {
00125                 m_add = FALSE;
00126             }
00127         }
00128         else
00129         {
00130             // and then remove them
00131 
00132             if (m_objects.entries())
00133             {
00134                 gzDistObjectPtr object = m_objects.first();
00135                 removeObject(object);
00136             }
00137             else
00138             {
00139                 m_add = TRUE;
00140             }
00141         }
00142     }
00143     else
00144     {
00145         // add / update attributes of the current objects
00146 
00147         gzListIterator<gzDistObject> iter(m_objects);
00148         
00149         gzDistObject* object;
00150         
00151         while (object = iter())
00152         {
00153             updateObject(gzString(m_tickCount%5), gzString(m_tickCount), object);
00154         }
00155     }
00156 
00157 
00158     // send an event
00159     gzDistEventPtr event = new gzDistEvent;
00160     sendEvent(event, m_session);
00161 
00162 
00163     // increment tick counter
00164     ++m_tickCount;
00165 
00166 }
00167 
00168 
00169 gzVoid Publisher::onNewObject(gzDistObject* object, gzDistSession* session)
00170 {
00171     m_objects.insert(object);
00172 }
00173 
00174 
00175 gzVoid Publisher::onRemoveObject(gzDistObject* object, gzDistSession* session)
00176 {
00177     m_objects.remove(object);
00178 }
00179 
00180 
00181 gzVoid Publisher::onSystemShutdown()
00182 {
00183     // GizmoDistribution is shutting down
00184     // free all references to enable the library to be unloaded properly
00185     // it is recommended to always implement this callback
00186     m_session = NULL;
00187     m_objects.clear();
00188 }
00189 
00190 
00191 //------------------------------- Subscriber ----------------------------------
00192 
00193 // A client that subscribe for events, objects and attributes
00194 class Subscriber : public gzDistClientInterface
00195 {
00196     public:
00197 
00198         Subscriber(const gzString& sessionName);
00199 
00200         virtual ~Subscriber();
00201 
00202 
00203     private:
00204 
00205         // notification callbacks
00206 
00207         gzVoid onNewSession(gzDistSession* session);
00208 
00209         gzVoid onRemoveSession(gzDistSession* session);
00210 
00211         gzVoid onEvent(gzDistEvent* event);
00212         
00213         gzVoid onNewObject(gzDistObject* object, gzDistSession* session);
00214         
00215         gzVoid onRemoveObject(gzDistObject* object, gzDistSession* session);
00216 
00217         gzVoid onNewAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session);
00218 
00219         gzVoid onRemoveAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session);
00220 
00221         gzVoid onUpdateAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session);
00222 
00223         gzVoid onSystemShutdown();
00224 
00225 
00226     private:
00227 
00228         // members
00229 
00230         gzString m_sessionName;
00231 
00232         gzDistSessionPtr m_session;
00233 
00234 };
00235 
00236 
00237 Subscriber::Subscriber(const gzString& sessionName)
00238  :  gzDistClientInterface(sessionName + gzString("_subscriber")),
00239     m_sessionName(sessionName)
00240 {
00241     // initialize client
00242     initialize();
00243 
00244     // subscribe for sessions
00245     // notifications will be received in onNewSession() and onRemoveSession()
00246     // callbacks when sessions are created or removed from this process
00247     subscribeSessions();
00248 
00249 }
00250 
00251 
00252 Subscriber::~Subscriber()
00253 {
00254     // uninitialize client
00255     uninitialize();
00256 }
00257 
00258 
00259 gzVoid Subscriber::onNewSession(gzDistSession* session)
00260 {
00261     GZMESSAGE(GZ_MESSAGE_NOTICE, "New session '%s'", (const char*)session->getName());
00262 
00263     
00264     if (session->getName() == m_sessionName)
00265     {
00266         // join the new session
00267         joinSession(session);
00268 
00269         // subscribe for objects on the session
00270         // notifications will be received in onNewObject() and onRemoveObject()
00271         // callbacks when objects are created or removed from this session
00272         subscribeObjects(gzDistObject::getClassType(), session);
00273 
00274         // subscribe for events on the session
00275         // notifications will be received in the onEvent() callback
00276         // when events are sent on this session
00277         subscribeEvents(gzDistEvent::getClassType(), session);
00278 
00279         m_session = session;
00280 
00281     }
00282 }
00283 
00284 
00285 gzVoid Subscriber::onRemoveSession(gzDistSession* session)
00286 {
00287     // a session was removed from this process
00288     // this will happen when a session no longer has
00289     // any local clients joined to it
00290 
00291     GZMESSAGE(GZ_MESSAGE_NOTICE, "Removed session '%s'", (const char*)session->getName());
00292 }
00293 
00294 
00295 gzVoid Subscriber::onEvent(gzDistEvent* event)
00296 {
00297     // an event was received
00298 
00299     GZMESSAGE(GZ_MESSAGE_NOTICE, "Event received on sessions '%s'",
00300                 (const char*)event->getSession()->getName());
00301 }
00302 
00303 
00304 gzVoid Subscriber::onNewObject(gzDistObject* object, gzDistSession* session)
00305 {
00306     // an object has been added
00307 
00308     GZMESSAGE(GZ_MESSAGE_NOTICE, "New object '%s' on session '%s'",
00309                 (const char*)object->getName(), (const char*)object->getSession()->getName());
00310     
00311     // subscribe for attributes on the new object
00312     // notifications will be received in the onNewAttributes() and onRemoveAttributes()
00313     // callbacks when attributes are created or removed from this object
00314     subscribeAttributes(object);
00315 }
00316 
00317 
00318 gzVoid Subscriber::onRemoveObject(gzDistObject* object, gzDistSession* session)
00319 {
00320     // an object was removed
00321     // all subscriptions associated with the object are automatically removed
00322 
00323     GZMESSAGE(GZ_MESSAGE_NOTICE, "Removed object '%s' from session '%s'",
00324                 (const char*)object->getName(), (const char*)session->getName());
00325 }
00326 
00327 
00328 gzVoid Subscriber::onNewAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session)
00329 {
00330     // attributes were added to an object
00331 
00332     GZMESSAGE(GZ_MESSAGE_NOTICE, "%u new attributes on object '%s' on session '%s'",
00333                 attributes.entries(), (const char*)object->getName(), (const char*)object->getSession()->getName());
00334 
00335 
00336     gzDistNotificationSetIterator iter(attributes);
00337 
00338     gzDistNotificationData* data;
00339 
00340     while (data = iter())
00341     {
00342         // subscribe for updates of the attribute value
00343         // notifications will be received in the onUpdateAttributes() callback
00344         subscribeAttributeValue(data->getAttributeName(), object);
00345     }
00346     
00347 }
00348 
00349 
00350 gzVoid Subscriber::onRemoveAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session)
00351 {
00352     // attributes were removed form an object
00353 
00354     GZMESSAGE(GZ_MESSAGE_NOTICE, "%u removed attributes from object '%s' on session '%s'",
00355                 attributes.entries(), (const char*)object->getName(), (const char*)object->getSession()->getName());
00356 }
00357 
00358 
00359 gzVoid Subscriber::onUpdateAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session)
00360 {
00361     // attribute values were updated
00362 
00363     GZMESSAGE(GZ_MESSAGE_NOTICE, "%u attributes updated on object '%s' on session '%s'",
00364                 attributes.entries(), (const char*)object->getName(), (const char*)object->getSession()->getName());
00365 }
00366 
00367 
00368 gzVoid Subscriber::onSystemShutdown()
00369 {
00370     // GizmoDistribution is shutting down
00371     // free all references to enable the library to be unloaded properly
00372     // it is recommended to always implement this callback
00373     m_session = NULL;
00374 }
00375 
00376 
00377 //--------------------------------- main --------------------------------------
00378 
00379 // Application entry point
00380 int main(int argc, char* argv[])
00381 {
00382     // setup default message receiver
00383     gzMessage::setMessageLevel(GZ_MESSAGE_NOTICE);
00384 
00385     // create manager and start
00386     gzDistManagerPtr manager = gzDistManager::getManager(TRUE);
00387     manager->start();
00388 
00389     GZMESSAGE(GZ_MESSAGE_NOTICE, "Hit return to quit!\n");
00390 
00391     // create publisher and subscriber
00392     Subscriber* subscriberA =  new Subscriber(A_SESSION);
00393     gzSleep(GZ_SLEEP_SECOND);
00394     Publisher* publisherA =  new Publisher(A_SESSION);
00395 
00396 
00397     // wait for return
00398     getchar();
00399 
00400 
00401     // delete publisher and subscriber
00402     delete publisherA;
00403     gzSleep(GZ_SLEEP_SECOND);
00404     delete subscriberA;
00405 
00406 
00407     // shut down and release manager
00408     manager->shutDown();
00409     manager = NULL;
00410 
00411     gzSleep(GZ_SLEEP_SECOND);
00412 
00413     return 0;
00414 
00415 }
00416 

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