00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "stdnet.h"
00036
00037 #include "nel/misc/types_nl.h"
00038 #include "nel/misc/debug.h"
00039 #include "nel/misc/entity_id.h"
00040 #include "nel/misc/sheet_id.h"
00041
00042 #include "nel/net/unified_network.h"
00043
00044 #include "nel/net/transport_class.h"
00045
00046
00047
00048
00049
00050 using namespace std;
00051 using namespace NLMISC;
00052 using namespace NLNET;
00053
00054 namespace NLNET {
00055
00056
00057
00058
00059
00060 uint CTransportClass::Mode = 0;
00061
00062 map<string, CTransportClass::CRegisteredClass> CTransportClass::LocalRegisteredClass;
00063
00064 CTransportClass::CRegisteredClass CTransportClass::TempRegisteredClass;
00065
00066 NLNET::CMessage CTransportClass::TempMessage;
00067
00068 vector<CTransportClass::CRegisteredBaseProp *> CTransportClass::DummyProp;
00069
00070 bool CTransportClass::Init = false;
00071
00072
00073
00074
00075
00076
00077 string typeToString (CTransportClass::TProp type)
00078 {
00079 string conv[] = {
00080 "PropUInt8", "PropUInt16", "PropUInt32", "PropUInt64",
00081 "PropSInt8", "PropSInt16", "PropSInt32", "PropSInt64",
00082 "PropBool", "PropFloat", "PropDouble", "PropString", "PropEntityId", "PropSheetId", "PropUKN" };
00083
00084 if (type > CTransportClass::PropUKN)
00085 return "<InvalidType>";
00086 return conv[type];
00087 }
00088
00089 void CTransportClass::displayDifferentClass (uint8 sid, const string &className, const vector<CRegisteredBaseProp> &otherClass, const vector<CRegisteredBaseProp *> &myClass)
00090 {
00091 nlinfo ("Service with sid %u send me the TransportClass '%s' with differents properties:", sid, className.c_str());
00092 uint i;
00093 nlinfo (" My local TransportClass is:");
00094 for (i = 0; i < myClass.size(); i++)
00095 {
00096 nlinfo (" Property: %d Name: '%s' type: '%s'", i, myClass[i]->Name.c_str(), typeToString(myClass[i]->Type).c_str());
00097 }
00098
00099 nlinfo (" The other side TransportClass is:");
00100 for (i = 0; i < otherClass.size(); i++)
00101 {
00102 nlinfo (" Property: %d Name: '%s' type: '%s'", i, otherClass[i].Name.c_str(), typeToString(otherClass[i].Type).c_str());
00103 }
00104 }
00105
00106 void CTransportClass::registerOtherSideClass (uint8 sid, TOtherSideRegisteredClass &osrc)
00107 {
00108 for (TOtherSideRegisteredClass::iterator it = osrc.begin(); it != osrc.end (); it++)
00109 {
00110
00111
00112 TRegisteredClass::iterator res = LocalRegisteredClass.find ((*it).first);
00113 if (res == LocalRegisteredClass.end ())
00114 {
00115
00116 nlwarning ("CTransportClass::registerOtherSideClass(): the other side class '%s' is not registered in my system, skip it", (*it).first.c_str());
00117 continue;
00118 }
00119
00120 if (sid >= (*res).second.Instance->States.size ())
00121 (*res).second.Instance->States.resize (sid+1);
00122
00123 (*res).second.Instance->States[sid].clear ();
00124
00125 for (sint j = 0; j < (sint)(*it).second.size (); j++)
00126 {
00127
00128
00129
00130 uint k;
00131 for (k = 0; k < (*res).second.Instance->Prop.size(); k++)
00132 {
00133 if ((*it).second[j].Name == (*res).second.Instance->Prop[k]->Name)
00134 {
00135 if ((*it).second[j].Type != (*res).second.Instance->Prop[k]->Type)
00136 {
00137 nlwarning ("Property '%s' of the class '%s' have not the same type in the 2 sides (%s %s)", (*it).second[j].Name.c_str(), (*it).first.c_str(), typeToString((*it).second[j].Type).c_str(), typeToString((*res).second.Instance->Prop[k]->Type).c_str());
00138 }
00139 break;
00140 }
00141 }
00142 if (k == (*res).second.Instance->Prop.size())
00143 {
00144
00145 (*res).second.Instance->States[sid].push_back (make_pair (-1, (*it).second[j].Type));
00146 }
00147 else
00148 {
00149
00150 (*res).second.Instance->States[sid].push_back (make_pair (k, PropUKN));
00151 }
00152 }
00153
00154
00155 if ((*it).second.size () != (*res).second.Instance->Prop.size ())
00156 {
00157
00158 displayDifferentClass (sid, (*it).first.c_str(), (*it).second, (*res).second.Instance->Prop);
00159 }
00160 else
00161 {
00162
00163 for (uint i = 0; i < (*res).second.Instance->Prop.size (); i++)
00164 {
00165 if ((*res).second.Instance->Prop[i]->Name != (*it).second[i].Name)
00166 {
00167
00168 displayDifferentClass (sid, (*it).first.c_str(), (*it).second, (*res).second.Instance->Prop);
00169 break;
00170 }
00171 else if ((*res).second.Instance->Prop[i]->Type != (*it).second[i].Type)
00172 {
00173
00174 displayDifferentClass (sid, (*it).first.c_str(), (*it).second, (*res).second.Instance->Prop);
00175 break;
00176 }
00177 }
00178 }
00179 }
00180
00181 displayLocalRegisteredClass ();
00182 }
00183
00184
00185 void CTransportClass::registerClass (CTransportClass &instance)
00186 {
00187 nlassert (Init);
00188 nlassert (Mode == 0);
00189
00190
00191 Mode = 3;
00192
00193
00194 TempRegisteredClass.clear ();
00195
00196
00197 TempRegisteredClass.Instance = &instance;
00198
00199
00200 TempRegisteredClass.Instance->description ();
00201
00202
00203 LocalRegisteredClass[TempRegisteredClass.Instance->Name] = TempRegisteredClass;
00204
00205
00206 Mode = 0;
00207 }
00208
00209 void CTransportClass::unregisterClass ()
00210 {
00211 for (TRegisteredClass::iterator it = LocalRegisteredClass.begin(); it != LocalRegisteredClass.end (); it++)
00212 {
00213 for (uint j = 0; j < (*it).second.Instance->Prop.size (); j++)
00214 {
00215 delete (*it).second.Instance->Prop[j];
00216 }
00217 (*it).second.Instance->Prop.clear ();
00218 (*it).second.Instance = NULL;
00219 }
00220 LocalRegisteredClass.clear ();
00221 }
00222
00223 void CTransportClass::displayLocalRegisteredClass (CRegisteredClass &c)
00224 {
00225 nldebug ("NETTC: > %s", c.Instance->Name.c_str());
00226 for (uint j = 0; j < c.Instance->Prop.size (); j++)
00227 {
00228 nldebug ("NETTC: > %s %s", c.Instance->Prop[j]->Name.c_str(), typeToString(c.Instance->Prop[j]->Type).c_str());
00229 }
00230
00231 for (uint l = 0; l < c.Instance->States.size (); l++)
00232 {
00233 if (c.Instance->States[l].size () != 0)
00234 {
00235 nldebug ("NETTC: > sid: %u", l);
00236 for (uint k = 0; k < c.Instance->States[l].size (); k++)
00237 {
00238 nldebug ("NETTC: - %d type : %s", c.Instance->States[l][k].first, typeToString(c.Instance->States[l][k].second).c_str());
00239 }
00240 }
00241 }
00242 }
00243
00244 void CTransportClass::displayLocalRegisteredClass ()
00245 {
00246 nldebug ("NETTC:> LocalRegisteredClass:");
00247 for (TRegisteredClass::iterator it = LocalRegisteredClass.begin(); it != LocalRegisteredClass.end (); it++)
00248 {
00249 displayLocalRegisteredClass ((*it).second);
00250 }
00251 }
00252
00253 void cbTCReceiveMessage (CMessage &msgin, const string &name, uint16 sid)
00254 {
00255 nldebug ("NETTC: cbReceiveMessage");
00256
00257 CTransportClass::TempMessage = msgin;
00258
00259 string className;
00260 CTransportClass::TempMessage.serial (className);
00261
00262 CTransportClass::TRegisteredClass::iterator it = CTransportClass::LocalRegisteredClass.find (className);
00263 if (it == CTransportClass::LocalRegisteredClass.end ())
00264 {
00265 nlwarning ("receive unknown class '%s', skip it", className.c_str());
00266 return;
00267 }
00268
00269 nlassert ((*it).second.Instance != NULL);
00270 (*it).second.Instance->read (name, (uint8)sid);
00271 }
00272
00273 void cbTCReceiveOtherSideClass (CMessage &msgin, const string &name, uint16 sid)
00274 {
00275 nldebug ("NETTC: cbReceiveOtherSideClass");
00276
00277 CTransportClass::TOtherSideRegisteredClass osrc;
00278
00279 uint32 nbClass;
00280 msgin.serial (nbClass);
00281
00282 nldebug ("NETTC: %d class", nbClass);
00283
00284 for (uint i = 0; i < nbClass; i++)
00285 {
00286 string className;
00287 msgin.serial (className);
00288
00289 osrc.push_back(make_pair (className, vector<CTransportClass::CRegisteredBaseProp>()));
00290
00291 uint32 nbProp;
00292 msgin.serial (nbProp);
00293
00294 nldebug ("NETTC: %s (%d prop)", className.c_str(), nbProp);
00295
00296 for (uint j = 0; j < nbProp; j++)
00297 {
00298 CTransportClass::CRegisteredBaseProp prop;
00299 msgin.serial (prop.Name);
00300 msgin.serialEnum (prop.Type);
00301 nldebug ("NETTC: %s %s", prop.Name.c_str(), typeToString(prop.Type).c_str());
00302 osrc[osrc.size()-1].second.push_back (prop);
00303 }
00304 }
00305
00306
00307 CTransportClass::registerOtherSideClass ((uint8)sid, osrc);
00308 }
00309
00310 static TUnifiedCallbackItem CallbackArray[] =
00311 {
00312 { "CT_LRC", cbTCReceiveOtherSideClass },
00313 { "CT_MSG", cbTCReceiveMessage },
00314 };
00315
00316 void cbTCUpService (const std::string &serviceName, uint16 sid, void *arg)
00317 {
00318 nldebug ("NETTC: CTransportClass Service %s %d is up", serviceName.c_str(), sid);
00319 if (sid >= 256)
00320 return;
00321 CTransportClass::sendLocalRegisteredClass ((uint8)sid);
00322 }
00323
00324 void CTransportClass::init ()
00325 {
00326
00327 if (Init) return;
00328
00329
00330 DebugLog->addNegativeFilter ("NETTC");
00331
00332
00333 CUnifiedNetwork::getInstance()->addCallbackArray (CallbackArray, sizeof (CallbackArray) / sizeof (CallbackArray[0]));
00334
00335
00336
00337 DummyProp.resize (PropUKN);
00338
00339 nlassert (PropUInt8 < PropUKN); DummyProp[PropUInt8] = new CTransportClass::CRegisteredProp<uint8>;
00340 nlassert (PropUInt16 < PropUKN); DummyProp[PropUInt16] = new CTransportClass::CRegisteredProp<uint16>;
00341 nlassert (PropUInt32 < PropUKN); DummyProp[PropUInt32] = new CTransportClass::CRegisteredProp<uint32>;
00342 nlassert (PropUInt64 < PropUKN); DummyProp[PropUInt64] = new CTransportClass::CRegisteredProp<uint64>;
00343 nlassert (PropSInt8 < PropUKN); DummyProp[PropSInt8] = new CTransportClass::CRegisteredProp<sint8>;
00344 nlassert (PropSInt16 < PropUKN); DummyProp[PropSInt16] = new CTransportClass::CRegisteredProp<sint16>;
00345 nlassert (PropSInt32 < PropUKN); DummyProp[PropSInt32] = new CTransportClass::CRegisteredProp<sint32>;
00346 nlassert (PropSInt64 < PropUKN); DummyProp[PropSInt64] = new CTransportClass::CRegisteredProp<sint64>;
00347 nlassert (PropBool < PropUKN); DummyProp[PropBool] = new CTransportClass::CRegisteredProp<bool>;
00348 nlassert (PropFloat < PropUKN); DummyProp[PropFloat] = new CTransportClass::CRegisteredProp<float>;
00349 nlassert (PropDouble < PropUKN); DummyProp[PropDouble] = new CTransportClass::CRegisteredProp<double>;
00350 nlassert (PropString < PropUKN); DummyProp[PropString] = new CTransportClass::CRegisteredProp<string>;
00351 nlassert (PropEntityId < PropUKN); DummyProp[PropEntityId] = new CTransportClass::CRegisteredProp<CEntityId>;
00352 nlassert (PropSheetId < PropUKN); DummyProp[PropSheetId] = new CTransportClass::CRegisteredProp<CSheetId>;
00353
00354
00355 CUnifiedNetwork::getInstance()->setServiceUpCallback("*", cbTCUpService, NULL, false);
00356
00357 Init = true;
00358 }
00359
00360 void CTransportClass::release ()
00361 {
00362 unregisterClass ();
00363
00364 for (uint i = 0; i < DummyProp.size (); i++)
00365 {
00366 delete DummyProp[i];
00367 }
00368 DummyProp.clear ();
00369 }
00370
00371 void CTransportClass::createLocalRegisteredClassMessage ()
00372 {
00373 TempMessage.clear ();
00374 if (TempMessage.isReading())
00375 TempMessage.invert();
00376 TempMessage.setType ("CT_LRC");
00377
00378 uint32 nbClass = LocalRegisteredClass.size ();
00379 TempMessage.serial (nbClass);
00380
00381 for (TRegisteredClass::iterator it = LocalRegisteredClass.begin(); it != LocalRegisteredClass.end (); it++)
00382 {
00383 nlassert ((*it).first == (*it).second.Instance->Name);
00384
00385 TempMessage.serial ((*it).second.Instance->Name);
00386
00387 uint32 nbProp = (*it).second.Instance->Prop.size ();
00388 TempMessage.serial (nbProp);
00389
00390 for (uint j = 0; j < (*it).second.Instance->Prop.size (); j++)
00391 {
00392
00393 TempMessage.serial ((*it).second.Instance->Prop[j]->Name);
00394 TempMessage.serialEnum ((*it).second.Instance->Prop[j]->Type);
00395 }
00396 }
00397 }
00398
00399 }