
This example illustrates how to perform transaction on objects in GizmoDistribution. A publisher client update attributes on objects using transactions and a subscriber client receive the updates in notifications.
The source code can also be found in the examples directory of the GizmoDistribution installation.
.
00001 //***************************************************************************** 00002 // File : transactions.cpp 00003 // Module : transactions 00004 // Description : transactions (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 040421 Created file 00019 // 00020 //***************************************************************************** 00021 00022 // Includes 00023 #include <stdio.h> 00024 #include "gzBaseLibrary.h" 00025 #include "gzDistLibrary.h" 00026 00027 00028 // Common constants 00029 static const gzString EXAMPLE_SESSION = "example"; 00030 static const gzString EXAMPLE_OBJECT = "example"; 00031 00032 00033 //----------------------------------------------------------------------------- 00034 00035 // A client that publish objects 00036 class Publisher : public gzDistClientInterface 00037 { 00038 public: 00039 00040 Publisher(); 00041 00042 virtual ~Publisher(); 00043 00044 00045 private: 00046 00047 // callbacks 00048 00049 gzVoid onClientTick(); 00050 00051 gzVoid onNewObject(gzDistObject* object, gzDistSession* session); 00052 00053 gzVoid onRemoveObject(gzDistObject* object, gzDistSession* session); 00054 00055 gzVoid onSystemShutdown(); 00056 00057 00058 private: 00059 00060 // members 00061 00062 gzDistSessionPtr m_session; 00063 00064 gzDistObjectPtr m_object; 00065 00066 gzULong m_tickCount; 00067 00068 }; 00069 00070 00071 Publisher::Publisher() 00072 : gzDistClientInterface("publisher"), 00073 m_tickCount(0) 00074 { 00075 // initialize client 00076 initialize(2); 00077 00078 // create and join session 00079 m_session = getSession(EXAMPLE_SESSION, TRUE); 00080 joinSession(m_session); 00081 00082 // subscribe for objects 00083 subscribeObjects(gzDistObject::getClassType(), m_session); 00084 00085 // add object 00086 addObject(new gzDistObject(EXAMPLE_OBJECT), m_session); 00087 00088 } 00089 00090 00091 Publisher::~Publisher() 00092 { 00093 // unsubscribe objects 00094 unsubscribeObjects(gzDistObject::getClassType(), m_session); 00095 00096 // resign the session 00097 resignSession(m_session); 00098 00099 // uninitialize client 00100 uninitialize(); 00101 } 00102 00103 00104 gzVoid Publisher::onNewObject(gzDistObject* object, gzDistSession* session) 00105 { 00106 if (!m_object) 00107 { 00108 m_object = object; 00109 } 00110 } 00111 00112 00113 gzVoid Publisher::onRemoveObject(gzDistObject* object, gzDistSession* session) 00114 { 00115 if (object == m_object) 00116 { 00117 m_object = NULL; 00118 } 00119 } 00120 00121 00122 gzVoid Publisher::onClientTick() 00123 { 00124 if (!m_object) 00125 { 00126 return; 00127 } 00128 00129 if (m_tickCount%5 != 0) 00130 { 00131 // add and/or update attributes 00132 00133 // notifications will be received on callbacks 00134 // onNewAttributes() for new attributes and 00135 // onUpdateAttributes for updated attributes 00136 00137 gzDistTransactionPtr transaction = new gzDistTransaction; 00138 00139 gzULong count = (gzULong)(10.0 * gzRandom() + 1.0); 00140 00141 for (gzUInt i = 0; i < count; i++) 00142 { 00143 transaction->setAttributeValue(gzString(i), gzString(m_tickCount)); 00144 } 00145 00146 GZMESSAGE(GZ_MESSAGE_NOTICE, "%u attributes in update transaction", count); 00147 00148 updateObject(transaction, m_object); 00149 00150 } 00151 else 00152 { 00153 // remove attributes 00154 00155 // notification will be received on callback onRemoveAttributes() 00156 00157 gzDistTransactionPtr transaction = new gzDistTransaction; 00158 00159 gzULong count = (gzULong)(10.0 * gzRandom() + 1.0); 00160 00161 for (gzUInt i = 0; i < count; i++) 00162 { 00163 transaction->setAttributeName(gzString(i)); 00164 } 00165 00166 GZMESSAGE(GZ_MESSAGE_NOTICE, "%u attributes in remove transaction", count); 00167 00168 removeAttributes(transaction, m_object); 00169 00170 } 00171 00172 ++m_tickCount; 00173 } 00174 00175 00176 gzVoid Publisher::onSystemShutdown() 00177 { 00178 // GizmoDistribution is shutting down 00179 // free all references to enable the library to be unloaded properly 00180 // it is recommended to always implement this callback 00181 m_object = NULL; 00182 m_session = NULL; 00183 } 00184 00185 00186 //----------------------------------------------------------------------------- 00187 00188 // A client that subscribe for objects and attributes 00189 class Subscriber : public gzDistClientInterface 00190 { 00191 public: 00192 00193 Subscriber(); 00194 00195 virtual ~Subscriber(); 00196 00197 00198 private: 00199 00200 // callbacks 00201 00202 gzVoid onNewObject(gzDistObject* object, gzDistSession* session); 00203 00204 gzVoid onRemoveObject(gzDistObject* object, gzDistSession* session); 00205 00206 gzVoid onNewAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session); 00207 00208 gzVoid onUpdateAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session); 00209 00210 gzVoid onRemoveAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session); 00211 00212 gzVoid onSystemShutdown(); 00213 00214 00215 private: 00216 00217 // members 00218 00219 gzDistSessionPtr m_session; 00220 00221 }; 00222 00223 00224 Subscriber::Subscriber() 00225 : gzDistClientInterface("subscriber") 00226 { 00227 // initialize client 00228 initialize(); 00229 00230 // create and join session 00231 m_session = getSession(EXAMPLE_SESSION, TRUE); 00232 joinSession(m_session); 00233 00234 // subscribe for objects 00235 subscribeObjects(gzDistObject::getClassType(), m_session); 00236 } 00237 00238 00239 Subscriber::~Subscriber() 00240 { 00241 // unsubscribe objects 00242 unsubscribeObjects(gzDistObject::getClassType(), m_session); 00243 00244 // resign the session 00245 resignSession(m_session); 00246 00247 // uninitialize client 00248 uninitialize(); 00249 } 00250 00251 00252 gzVoid Subscriber::onNewObject(gzDistObject* object, gzDistSession* session) 00253 { 00254 GZMESSAGE(GZ_MESSAGE_NOTICE, "New object '%s' on session '%s'", 00255 (const char*)object->getName(), (const char*)object->getSession()->getName()); 00256 00257 // subscribe for attributes on the new object 00258 // notifications will be received in the onNewAttributes() and onRemoveAttributes() 00259 // callbacks when attributes are created or removed from this object 00260 subscribeAttributes(object, TRUE); 00261 00262 } 00263 00264 00265 gzVoid Subscriber::onRemoveObject(gzDistObject* object, gzDistSession* session) 00266 { 00267 // an object was removed 00268 // all subscriptions associated with the object are automatically removed 00269 00270 GZMESSAGE(GZ_MESSAGE_NOTICE, "Removed object '%s' from session '%s'", 00271 (const char*)object->getName(), (const char*)session->getName()); 00272 } 00273 00274 00275 gzVoid Subscriber::onNewAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session) 00276 { 00277 // attributes were added to an object 00278 00279 GZMESSAGE(GZ_MESSAGE_NOTICE, "%u new attributes on object '%s' on session '%s'", 00280 attributes.entries(), (const char*)object->getName(), (const char*)object->getSession()->getName()); 00281 00282 00283 gzDistNotificationSetIterator iter(attributes); 00284 00285 gzDistNotificationData* data; 00286 00287 while (data = iter()) 00288 { 00289 // subscribe for updates of the attribute value 00290 // notifications will be received in the onUpdateAttributes() callback 00291 subscribeAttributeValue(data->getAttributeName(), object); 00292 } 00293 00294 } 00295 00296 00297 gzVoid Subscriber::onRemoveAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session) 00298 { 00299 // attributes were removed form an object 00300 00301 GZMESSAGE(GZ_MESSAGE_NOTICE, "%u removed attributes from object '%s' on session '%s'", 00302 attributes.entries(), (const char*)object->getName(), (const char*)object->getSession()->getName()); 00303 } 00304 00305 00306 gzVoid Subscriber::onUpdateAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session) 00307 { 00308 // attribute values were updated 00309 00310 GZMESSAGE(GZ_MESSAGE_NOTICE, "%u attributes updated on object '%s' on session '%s'", 00311 attributes.entries(), (const char*)object->getName(), (const char*)object->getSession()->getName()); 00312 } 00313 00314 00315 gzVoid Subscriber::onSystemShutdown() 00316 { 00317 // GizmoDistribution is shutting down 00318 // free all references to enable the library to be unloaded properly 00319 // it is recommended to always implement this callback 00320 m_session = NULL; 00321 } 00322 00323 00324 //----------------------------------------------------------------------------- 00325 00326 // Application entry point 00327 int main(int argc, char* argv[]) 00328 { 00329 // setup default message receiver 00330 gzMessage::setMessageLevel(GZ_MESSAGE_NOTICE); 00331 00332 // create manager and start 00333 gzDistManagerPtr manager = gzDistManager::getManager(TRUE); 00334 manager->start(); 00335 00336 GZMESSAGE(GZ_MESSAGE_NOTICE, "Hit return to quit!\n"); 00337 00338 // create publisher and subscriber 00339 Subscriber* subscriberA = new Subscriber; 00340 gzSleep(GZ_SLEEP_SECOND); 00341 Publisher* publisherA = new Publisher; 00342 00343 00344 // wait for return 00345 getchar(); 00346 00347 00348 // delete publisher and subscriber 00349 delete publisherA; 00350 gzSleep(GZ_SLEEP_SECOND); 00351 delete subscriberA; 00352 00353 00354 // shut down and release manager 00355 manager->shutDown(); 00356 manager = NULL; 00357 00358 gzSleep(GZ_SLEEP_SECOND); 00359 00360 return 0; 00361 00362 } 00363