# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

transport_class.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000-2002 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NeL Network Services.
00010  * NEVRAX NeL Network Services is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NeL Network Services is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NeL Network Services; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef NL_TRANSPORT_CLASS_H
00027 #define NL_TRANSPORT_CLASS_H
00028 
00029 
00030 //
00031 // Includes
00032 //
00033 
00034 #include "nel/misc/types_nl.h"
00035 #include "nel/misc/stream.h"
00036 #include "nel/misc/entity_id.h"
00037 
00038 #include "nel/net/unified_network.h"
00039 #include "nel/net/message.h"
00040 
00041 #include <vector>
00042 #include <string>
00043 
00044 
00045 //
00046 // Macros
00047 //
00048 
00053 #define TRANSPORT_CLASS_REGISTER(_c) \
00054         static _c _c##Instance; \
00055         CTransportClass::registerClass (_c##Instance);
00056 
00057 
00058 //
00059 // Classes
00060 //
00061 
00069 class CTransportClass
00070 {
00071 public:
00072 
00077         enum TProp {
00078                 PropUInt8, PropUInt16, PropUInt32, PropUInt64,
00079                 PropSInt8, PropSInt16, PropSInt32, PropSInt64,
00080                 PropBool, PropFloat, PropDouble, PropString, PropEntityId, PropUKN };
00081 
00082 
00083         //
00084         // Static methods
00085         //
00086 
00088         static void init ();
00089 
00091         static void release ();
00092 
00096         static void registerClass (CTransportClass &instance);
00097 
00099         static void displayLocalRegisteredClass ();
00100 
00101 
00102         //
00103         // Virtual methods
00104         //
00105 
00118         virtual void description () = 0;
00119 
00123         virtual void callback (const std::string &name, uint8 sid) { };
00124 
00125 
00126         //
00127         // Other methods
00128         //
00129 
00131         void send (uint8 sid);
00132 
00134         void send (std::string serviceName);
00135 
00138         void className (const std::string &name);
00139 
00146         template <class T> void property (const std::string &name, TProp type, T defaultValue, T &value)
00147         {
00148                 switch (type)
00149                 {
00150                 case PropUInt8: case PropSInt8: case PropBool: nlassert(sizeof(T) == sizeof (uint8)); break;
00151                 case PropUInt16: case PropSInt16: nlassert(sizeof(T) == sizeof (uint16)); break;
00152                 case PropUInt32: case PropSInt32: nlassert(sizeof(T) == sizeof (uint32)); break;
00153                 case PropUInt64: case PropSInt64: nlassert(sizeof(T) == sizeof (uint64)); break;
00154                 case PropFloat: nlassert(sizeof(T) == sizeof (float)); break;
00155                 case PropDouble: nlassert(sizeof(T) == sizeof (double)); break;
00156                 case PropString: nlassert(sizeof(T) == sizeof (std::string)); break;
00157                 case PropEntityId: nlassert(sizeof(T) == sizeof (NLMISC::CEntityId)); break;
00158                 default: nlerror ("property %s have unknown type %d", name.c_str(), type);
00159                 }
00160 
00161                 if (Mode == 2)                  // write
00162                 {
00163                         // send only if needed
00164                         // todo manage unknown prop
00165                         TempMessage.serial (value);
00166                 }
00167                 else if (Mode == 3)     // register
00168                 {
00169                         // add a new prop to the current class
00170                         nlassert (TempRegisteredClass.Instance != NULL);
00171                         TempRegisteredClass.Instance->Prop.push_back (new CRegisteredProp<T> (name, type, defaultValue, &value));
00172                 }
00173                 else if (Mode == 4)     // display
00174                 {
00175                         std::string val;
00176                         val = "defval: ";
00177                         val += NLMISC::toString (defaultValue);
00178                         val += " val: ";
00179                         val += NLMISC::toString (value);
00180                         nldebug ("NETTC:   prop %s %d: %s", name.c_str(), type, val.c_str());
00181                 }
00182                 else
00183                 {
00184                         nlstop;
00185                 }
00186         }
00187         
00188         template <class T> void propertyCont (const std::string &name, TProp type, T &value)
00189         {
00190                 if (Mode == 2)                  // write
00191                 {
00192                         // send only if needed
00193                         // todo manage unknown prop
00194                         TempMessage.serialCont (value);
00195                 }
00196                 else if (Mode == 3)     // register
00197                 {
00198                         // add a new prop to the current class
00199                         nlassert (TempRegisteredClass.Instance != NULL);
00200                         TempRegisteredClass.Instance->Prop.push_back (new CRegisteredPropCont<T> (name, type, &value));
00201                 }
00202                 else if (Mode == 4)     // display
00203                 {
00204                         typedef typename T::iterator __iterator;
00205                         std::string val;
00206                         for (__iterator it = value.begin (); it != value.end(); it++)
00207                         {
00208                                 val += NLMISC::toString (*it);
00209                                 val += " ";
00210                         }
00211                         nldebug ("NETTC:   prop %s %d: %d elements ( %s)", name.c_str(), type, value.size(), val.c_str());
00212                 }
00213                 else
00214                 {
00215                         nlstop;
00216                 }
00217         }
00218 
00219         
00221         void display ();
00222 
00223 private:
00224 
00225         //
00226         // Structures
00227         //
00228 
00229         struct CRegisteredBaseProp
00230         {
00231                 CRegisteredBaseProp () : Type(PropUKN) { }
00232 
00233                 CRegisteredBaseProp (const std::string &name, TProp type) : Name(name), Type(type) { }
00234                 
00235                 std::string     Name;
00236                 TProp Type;
00237 
00238                 virtual void serialDefaultValue (NLMISC::IStream &f) { }
00239 
00240                 virtual void serialValue (NLMISC::IStream &f) { }
00241 
00242                 virtual void setDefaultValue () { }
00243         };
00244 
00245         typedef std::vector<std::pair<std::string, std::vector <CRegisteredBaseProp> > > TOtherSideRegisteredClass;
00246 
00247         struct CRegisteredClass
00248         {
00249                 CTransportClass *Instance;
00250 
00251                 CRegisteredClass () { clear (); }
00252 
00253                 void clear () { Instance = NULL; }
00254         };
00255 
00256         typedef std::map<std::string, CRegisteredClass> TRegisteredClass;
00257 
00258         template <class T> struct CRegisteredProp : public CRegisteredBaseProp
00259         {
00260                 CRegisteredProp () : Value(NULL) { }
00261 
00262                 CRegisteredProp (const std::string &name, TProp type, T defaultValue, T *value = NULL) :
00263                         CRegisteredBaseProp (name, type), DefaultValue(defaultValue), Value (value) { }
00264                 
00265                 T DefaultValue, *Value;
00266 
00267                 virtual void serialDefaultValue (NLMISC::IStream &f)
00268                 {
00269                         f.serial (DefaultValue);
00270                 }
00271 
00272                 virtual void serialValue (NLMISC::IStream &f)
00273                 {
00274                         nlassert (Value != NULL);
00275                         f.serial (*Value);
00276                 }
00277 
00278                 virtual void setDefaultValue ()
00279                 {
00280                         nlassert (Value != NULL);
00281                         *Value = DefaultValue;
00282                 }
00283         };
00284 
00285         template <class T> struct CRegisteredPropCont : public CRegisteredBaseProp
00286         {
00287                 CRegisteredPropCont () : Value(NULL) { }
00288 
00289                 CRegisteredPropCont (const std::string &name, TProp type, T *value = NULL) :
00290                         CRegisteredBaseProp (name, type), Value (value) { }
00291                 
00292                 T *Value;
00293 
00294                 virtual void serialDefaultValue (NLMISC::IStream &f)
00295                 {
00296                         // nothing
00297                 }
00298 
00299                 virtual void serialValue (NLMISC::IStream &f)
00300                 {
00301                         nlassert (Value != NULL);
00302                         f.serialCont (*Value);
00303                 }
00304 
00305                 virtual void setDefaultValue ()
00306                 {
00307                         nlassert (Value != NULL);
00308                         Value->clear ();
00309                 }
00310         };
00311 
00312 
00313         //
00314         // Variables
00315         //
00316 
00317         // Name of the class
00318         std::string     Name;
00319 
00320         // States to decode the stream from the network
00321         std::vector<std::vector<std::pair<sint, TProp> > > States;
00322 
00323         // Contains all propterties for this class
00324         std::vector<CRegisteredBaseProp *> Prop;
00325 
00326 
00327         //
00328         // Methods
00329         //
00330         
00331         // Read the TempMessage and call the callback
00332         void read (const std::string &name, uint8 sid);
00333 
00334         // Used to create a TempMessage with this class
00335         NLNET::CMessage &write ();
00336         
00337 
00338         //
00339         // Static Variables
00340         //
00341 
00342         // Used to serialize unused properties from the TempMessage
00343         static std::vector<CRegisteredBaseProp *>       DummyProp;
00344 
00345         // Select what the description() must do
00346         static uint                                                                     Mode;   // 0=nothing 1=read 2=write 3=register 4=display
00347 
00348         // Contains all registered transport class
00349         static TRegisteredClass                                         LocalRegisteredClass;   // registered class that are in my program
00350 
00351         // The registered class that is currently filled (before put in LocalRegisteredClass)
00352         static CRegisteredClass                                         TempRegisteredClass;
00353 
00354         // The message that is currently filled/emptyed
00355         static NLNET::CMessage                                          TempMessage;
00356 
00357         static bool                                                                     Init;
00358 
00359         //
00360         // Static methods
00361         //
00362 
00363         // Called by release() to delete all structures
00364         static void unregisterClass ();
00365 
00366         // Fill the States merging local and other side class
00367         static void registerOtherSideClass (uint8 sid, TOtherSideRegisteredClass &osrc);
00368 
00369         // Create a message with local transport classes to send to the other side
00370         static void createLocalRegisteredClassMessage ();
00371 
00372         // Send the local transport classes to another service using the service id
00373         static void sendLocalRegisteredClass (uint8 sid)
00374         {
00375                 nlassert (Init);
00376                 nldebug ("NETTC: sendLocalRegisteredClass to %d", sid);
00377                 createLocalRegisteredClassMessage ();
00378                 NLNET::CUnifiedNetwork::getInstance()->send (sid, TempMessage);
00379         }
00380 
00381         // Display a specific registered class (debug purpose)
00382         static void displayLocalRegisteredClass (CRegisteredClass &c);
00383         static void displayDifferentClass (uint8 sid, const std::string &className, const std::vector<CRegisteredBaseProp> &otherClass, const std::vector<CRegisteredBaseProp *> &myClass);
00384 
00385 
00386         //
00387         // Friends
00388         //
00389 
00390         friend void cbTCReceiveMessage (NLNET::CMessage &msgin, const std::string &name, uint16 sid);
00391         friend void cbTCUpService (const std::string &serviceName, uint16 sid, void *arg);
00392         friend void cbTCReceiveOtherSideClass (NLNET::CMessage &msgin, const std::string &name, uint16 sid);
00393 };
00394 
00395 
00396 //
00397 // Inlines
00398 //
00399 
00400 inline void CTransportClass::className (const std::string &name)
00401 {
00402         if (Mode == 2)          // write
00403         {
00404                 TempMessage.serial (const_cast<std::string &> (name));
00405         }
00406         else if (Mode == 3) // register
00407         {
00408                 // add a new entry in my registered class
00409                 nlassert (TempRegisteredClass.Instance != NULL);
00410                 TempRegisteredClass.Instance->Name = name;
00411         }
00412         else if (Mode == 4) // display
00413         {
00414                 nldebug ("NETTC: class %s:", name.c_str());
00415         }
00416         else
00417         {
00418                 nlstop;
00419         }
00420 }
00421 
00422 
00423 inline void CTransportClass::send (uint8 sid)
00424 {
00425         nlassert (Init);
00426         NLNET::CUnifiedNetwork::getInstance()->send (sid, write ());
00427 }
00428 
00429 
00430 inline void CTransportClass::send (std::string serviceName)
00431 {
00432         nlassert (Init);
00433         NLNET::CUnifiedNetwork::getInstance()->send (serviceName, write ());
00434 }
00435 
00436 inline void CTransportClass::display ()
00437 {
00438         nlassert (Mode == 0);
00439 
00440         // set the mode to register
00441         Mode = 4;
00442         
00443         description ();
00444 
00445         // set to mode none
00446         Mode = 0;
00447 }
00448 
00449 inline NLNET::CMessage &CTransportClass::write ()
00450 {
00451         nlassert (Init);
00452         nlassert (Mode == 0);
00453 
00454         // set the mode to register
00455         Mode = 2;
00456 
00457         TempMessage.clear ();
00458         if (TempMessage.isReading())
00459                 TempMessage.invert();
00460         TempMessage.setType ("CT_MSG");
00461 
00462         description ();
00463 
00464         // set to mode none
00465         Mode = 0;
00466 
00467         display ();
00468 
00469         return TempMessage;
00470 }
00471 
00472 inline void CTransportClass::read (const std::string &name, uint8 sid)
00473 {
00474         nlassert (Init);
00475         nlassert (Mode == 0);
00476         nlassert (States.size() > sid);
00477 
00478         // set flag of all prop
00479 
00480         std::vector<uint8> bitfield;
00481         bitfield.resize (Prop.size(), 0);
00482 
00483         // init prop from the stream
00484         uint i;
00485         for (i = 0; i < States[sid].size(); i++)
00486         {
00487                 if (States[sid][i].first == -1)
00488                 {
00489                         // skip the value from the stream
00490                         DummyProp[States[sid][i].second]->serialDefaultValue (TempMessage);
00491                 }
00492                 else
00493                 {
00494                         // get the good value
00495                         Prop[States[sid][i].first]->serialValue (TempMessage);
00496                         bitfield[States[sid][i].first] = 1;
00497                 }
00498         }
00499 
00500         // set default value for unknown prop
00501         for (i = 0; i < Prop.size(); i++)
00502         {
00503                 if (bitfield[i] == 0)
00504                 {
00505                         Prop[i]->setDefaultValue ();
00506                 }
00507         }
00508 
00509         display ();
00510 
00511         // call the user callback
00512         callback (name, sid);
00513 }
00514 
00515 
00516 #endif // NL_TRANSPORT_CLASS_H
00517 
00518 /* End of transport_class.h */