
This example illustrates how to use ownership of attributes in GizmoDistribution. Two clients request ownership and try to update attributes on objects. Only the current owner will succeed in updating attributes.
The source code can also be found in the examples directory of the GizmoDistribution installation.
.
00001 //***************************************************************************** 00002 // File : ownership.cpp 00003 // Module : ownership 00004 // Description : ownership (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_SESSION"; 00030 static const gzString EXAMPLE_ATTRIBUTE = "EXAMPLE_ATTRIB"; 00031 static const gzString NAME_A = "A"; 00032 static const gzString NAME_B = "B"; 00033 static const gzString CLIENT_PREFIX = "CLIENT_"; 00034 static const gzString OBJECT_PREFIX = "OBJECT_"; 00035 00036 00037 //----------------------------------------------------------------------------- 00038 00039 // Example owner client 00040 class Client : public gzDistClientInterface 00041 { 00042 public: 00043 00044 Client(const gzString& name); 00045 00046 virtual ~Client(); 00047 00048 00049 private: 00050 00051 // callbacks 00052 00053 gzVoid onClientTick(); 00054 00055 gzVoid onNewObject(gzDistObject* object, gzDistSession* session); 00056 00057 gzVoid onRemoveObject(gzDistObject* object, gzDistSession* session); 00058 00059 gzVoid onUpdateAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session); 00060 00061 gzVoid onGrantOwnership(const gzString& attributeName, gzDistObject* object, gzDistSession* session); 00062 00063 gzVoid onDropOwnership(const gzString& attributeName, gzDistObject* object, gzDistSession* session); 00064 00065 gzVoid onRequestOwnership(const gzString& attributeName, gzDistObject* object, const gzDistClientID& requester, gzDistSession* session); 00066 00067 gzVoid onSystemShutdown(); 00068 00069 00070 private: 00071 00072 // members 00073 00074 gzDistSessionPtr m_session; 00075 00076 gzRefList<gzDistObject> m_objects; 00077 00078 gzULong m_tickCount; 00079 00080 }; 00081 00082 00083 Client::Client(const gzString& name) 00084 : gzDistClientInterface(CLIENT_PREFIX + name), 00085 m_tickCount(0) 00086 { 00087 // initialize client 00088 initialize(2); 00089 00090 // create and join session 00091 m_session = getSession(EXAMPLE_SESSION, TRUE); 00092 joinSession(m_session); 00093 00094 // subscribe for objects 00095 subscribeObjects(gzDistObject::getClassType(), m_session, TRUE); 00096 00097 // add an object using my own name 00098 gzDistObjectPtr object = new gzDistObject(OBJECT_PREFIX + name); 00099 object->setAttributeValue(EXAMPLE_ATTRIBUTE, GZ_EMPTY_STRING); 00100 addObject(object, m_session); 00101 00102 } 00103 00104 00105 Client::~Client() 00106 { 00107 // unsubscribe objects 00108 unsubscribeObjects(gzDistObject::getClassType(), m_session); 00109 00110 // resign the session 00111 resignSession(m_session); 00112 00113 // uninitialize client 00114 uninitialize(); 00115 } 00116 00117 00118 gzVoid Client::onClientTick() 00119 { 00120 gzListIterator<gzDistObject> iter(m_objects); 00121 gzDistObject* object; 00122 00123 while (object = iter()) 00124 { 00125 if (!updateObject(EXAMPLE_ATTRIBUTE, getID().name + gzString(m_tickCount), object, GZ_DIST_SYNCHRONOUS)) 00126 { 00127 GZMESSAGE(GZ_MESSAGE_NOTICE, "'%s' failed to update '%s' on '%s'", 00128 (const char*)getID().name, (const char*)EXAMPLE_ATTRIBUTE, (const char*)object->getName()); 00129 } 00130 00131 if (!object->isOwnerOf(EXAMPLE_ATTRIBUTE, getID())) 00132 { 00133 requestOwnership(EXAMPLE_ATTRIBUTE, object); 00134 } 00135 00136 } 00137 00138 ++m_tickCount; 00139 00140 } 00141 00142 00143 gzVoid Client::onNewObject(gzDistObject* object, gzDistSession* session) 00144 { 00145 m_objects.insert(object); 00146 00147 if (object->getName() == getID().name) 00148 { 00149 requestOwnership(EXAMPLE_ATTRIBUTE, object); 00150 subscribeAttributeValue(EXAMPLE_ATTRIBUTE, object); 00151 } 00152 } 00153 00154 00155 gzVoid Client::onRemoveObject(gzDistObject* object, gzDistSession* session) 00156 { 00157 m_objects.remove(object); 00158 } 00159 00160 00161 gzVoid Client::onUpdateAttributes(const gzDistNotificationSet& attributes, gzDistObject* object, gzDistSession* session) 00162 { 00163 gzDistNotificationSetIterator iter(attributes); 00164 gzDistNotificationData* data; 00165 00166 while (data = iter()) 00167 { 00168 GZMESSAGE(GZ_MESSAGE_NOTICE, "'%s' on '%s' was updated to '%s'", 00169 (const char*)data->getAttributeName(), (const char*)object->getName(), 00170 (const char*)data->getAttributeValue().getString()); 00171 } 00172 00173 } 00174 00175 00176 gzVoid Client::onGrantOwnership(const gzString& attributeName, gzDistObject* object, gzDistSession* session) 00177 { 00178 // ownership was granted 00179 GZMESSAGE(GZ_MESSAGE_NOTICE, "Ownership of '%s' on '%s' was granted to '%s'", 00180 (const char*)attributeName, (const char*)object->getName(), (const char*)getID().name); 00181 } 00182 00183 00184 gzVoid Client::onDropOwnership(const gzString& attributeName, gzDistObject* object, gzDistSession* session) 00185 { 00186 // ownership was dropped 00187 GZMESSAGE(GZ_MESSAGE_NOTICE, "'%s' dropped ownership of '%s' on '%s'", 00188 (const char*)getID().name, (const char*)attributeName, (const char*)object->getName()); 00189 } 00190 00191 00192 gzVoid Client::onRequestOwnership(const gzString& attributeName, gzDistObject* object, const gzDistClientID& requester, gzDistSession* session) 00193 { 00194 // someone has requested ownership of my attribute 00195 GZMESSAGE(GZ_MESSAGE_NOTICE, "'%s' requested ownership of '%s' on '%s'", 00196 (const char*)requester.name, (const char*)attributeName, (const char*)object->getName()); 00197 } 00198 00199 00200 gzVoid Client::onSystemShutdown() 00201 { 00202 // in case of pre-mature shutdown 00203 m_objects.clear(); 00204 m_session = NULL; 00205 } 00206 00207 00208 //----------------------------------------------------------------------------- 00209 00210 // Application entry point 00211 int main(int argc, char* argv[]) 00212 { 00213 // setup default message receiver 00214 gzMessage::setMessageLevel(GZ_MESSAGE_NOTICE); 00215 00216 // create manager and start 00217 gzDistManagerPtr manager = gzDistManager::getManager(TRUE); 00218 manager->start(); 00219 00220 GZMESSAGE(GZ_MESSAGE_NOTICE, "Hit return to quit!\n"); 00221 00222 // create clients 00223 gzDistClientInterface* clientA = new Client(NAME_A); 00224 gzDistClientInterface* clientB = new Client(NAME_B); 00225 00226 00227 // wait for return 00228 getchar(); 00229 00230 00231 // delete clients 00232 delete clientA; 00233 delete clientB; 00234 00235 // shut down and release manager 00236 manager->shutDown(); 00237 manager = NULL; 00238 00239 gzSleep(GZ_SLEEP_SECOND); 00240 00241 return 0; 00242 00243 } 00244