Connection.h 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  1. /*
  2. * Connection.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include <typeinfo> //XXX this is in namespace std if you want w/o use typeinfo.h?
  12. #include <boost/type_traits/is_fundamental.hpp>
  13. #include <boost/type_traits/is_enum.hpp>
  14. #include <boost/type_traits/is_pointer.hpp>
  15. #include <boost/type_traits/is_class.hpp>
  16. #include <boost/type_traits/is_base_of.hpp>
  17. #include <boost/type_traits/is_array.hpp>
  18. #include <boost/type_traits/remove_pointer.hpp>
  19. #include <boost/type_traits/remove_const.hpp>
  20. #include <boost/variant.hpp>
  21. #include <boost/mpl/eval_if.hpp>
  22. #include <boost/mpl/equal_to.hpp>
  23. #include <boost/mpl/int.hpp>
  24. #include <boost/mpl/identity.hpp>
  25. #include <boost/any.hpp>
  26. #include "ConstTransitivePtr.h"
  27. #include "CCreatureSet.h" //for CStackInstance
  28. #include "CObjectHandler.h" //for CArmedInstance
  29. #include "Mapping/CCampaignHandler.h" //for CCampaignState
  30. const ui32 version = 737;
  31. const TSlot COMMANDER_SLOT_PLACEHOLDER = -2;
  32. class CConnection;
  33. class CGObjectInstance;
  34. class CStackInstance;
  35. class CGameState;
  36. class CCreature;
  37. class LibClasses;
  38. class CHero;
  39. struct CPack;
  40. extern DLL_LINKAGE LibClasses * VLC;
  41. namespace mpl = boost::mpl;
  42. namespace boost
  43. {
  44. namespace asio
  45. {
  46. namespace ip
  47. {
  48. class tcp;
  49. }
  50. class io_service;
  51. template <typename Protocol> class stream_socket_service;
  52. template <typename Protocol,typename StreamSocketService>
  53. class basic_stream_socket;
  54. template <typename Protocol> class socket_acceptor_service;
  55. template <typename Protocol,typename SocketAcceptorService>
  56. class basic_socket_acceptor;
  57. }
  58. class mutex;
  59. }
  60. enum SerializationLvl
  61. {
  62. Wrong=0,
  63. Boolean,
  64. Primitive,
  65. Array,
  66. Pointer,
  67. Enum,
  68. Serializable,
  69. BooleanVector
  70. };
  71. struct TypeComparer
  72. {
  73. bool operator()(const std::type_info *a, const std::type_info *b) const
  74. {
  75. return a->before(*b);
  76. }
  77. };
  78. class DLL_LINKAGE CTypeList
  79. {
  80. typedef std::multimap<const std::type_info *,ui16,TypeComparer> TTypeMap;
  81. TTypeMap types;
  82. public:
  83. CTypeList();
  84. ui16 registerType(const std::type_info *type);
  85. template <typename T> ui16 registerType(const T * t = NULL)
  86. {
  87. return registerType(getTypeInfo(t));
  88. }
  89. ui16 getTypeID(const std::type_info *type);
  90. template <typename T> ui16 getTypeID(const T * t = NULL)
  91. {
  92. return getTypeID(getTypeInfo(t));
  93. }
  94. template <typename T> const std::type_info * getTypeInfo(const T * t = NULL)
  95. {
  96. if(t)
  97. return &typeid(*t);
  98. else
  99. return &typeid(T);
  100. }
  101. };
  102. extern DLL_LINKAGE CTypeList typeList;
  103. template<typename Ser>
  104. struct SaveBoolean
  105. {
  106. static void invoke(Ser &s, const bool &data)
  107. {
  108. s.saveBoolean(data);
  109. }
  110. };
  111. template<typename Ser>
  112. struct LoadBoolean
  113. {
  114. static void invoke(Ser &s, bool &data)
  115. {
  116. s.loadBoolean(data);
  117. }
  118. };
  119. template<typename Ser>
  120. struct SaveBooleanVector
  121. {
  122. static void invoke(Ser &s, const std::vector<bool> &data)
  123. {
  124. s.saveBooleanVector(data);
  125. }
  126. };
  127. template<typename Ser>
  128. struct LoadBooleanVector
  129. {
  130. static void invoke(Ser &s, std::vector<bool> &data)
  131. {
  132. s.loadBooleanVector(data);
  133. }
  134. };
  135. template<typename Ser,typename T>
  136. struct SavePrimitive
  137. {
  138. static void invoke(Ser &s, const T &data)
  139. {
  140. s.savePrimitive(data);
  141. }
  142. };
  143. template<typename Ser,typename T>
  144. struct SaveSerializable
  145. {
  146. static void invoke(Ser &s, const T &data)
  147. {
  148. s.saveSerializable(data);
  149. }
  150. };
  151. template<typename Ser,typename T>
  152. struct SaveEnum
  153. {
  154. static void invoke(Ser &s, const T &data)
  155. {
  156. s.saveEnum(data);
  157. }
  158. };
  159. template<typename Ser,typename T>
  160. struct LoadEnum
  161. {
  162. static void invoke(Ser &s, T &data)
  163. {
  164. s.loadEnum(data);
  165. }
  166. };
  167. template<typename Ser,typename T>
  168. struct LoadPrimitive
  169. {
  170. static void invoke(Ser &s, T &data)
  171. {
  172. s.loadPrimitive(data);
  173. }
  174. };
  175. template<typename Ser,typename T>
  176. struct SavePointer
  177. {
  178. static void invoke(Ser &s, const T &data)
  179. {
  180. s.savePointer(data);
  181. }
  182. };
  183. template<typename Ser,typename T>
  184. struct LoadPointer
  185. {
  186. static void invoke(Ser &s, T &data)
  187. {
  188. s.loadPointer(data);
  189. }
  190. };
  191. template<typename Ser,typename T>
  192. struct SaveArray
  193. {
  194. static void invoke(Ser &s, const T &data)
  195. {
  196. s.saveArray(data);
  197. }
  198. };
  199. template<typename Ser,typename T>
  200. struct LoadArray
  201. {
  202. static void invoke(Ser &s, T &data)
  203. {
  204. s.loadArray(data);
  205. }
  206. };
  207. template<typename Ser,typename T>
  208. struct LoadSerializable
  209. {
  210. static void invoke(Ser &s, T &data)
  211. {
  212. s.loadSerializable(data);
  213. }
  214. };
  215. template<typename Ser,typename T>
  216. struct SaveWrong
  217. {
  218. static void invoke(Ser &s, const T &data)
  219. {
  220. throw std::runtime_error("Wrong save serialization call!");
  221. }
  222. };
  223. template<typename Ser,typename T>
  224. struct LoadWrong
  225. {
  226. static void invoke(Ser &s, const T &data)
  227. {
  228. throw std::runtime_error("Wrong load serialization call!");
  229. }
  230. };
  231. template<typename T>
  232. struct SerializationLevel
  233. {
  234. typedef mpl::integral_c_tag tag;
  235. typedef
  236. typename mpl::eval_if<
  237. boost::is_same<T, bool>,
  238. mpl::int_<Boolean>,
  239. //else
  240. typename mpl::eval_if<
  241. boost::is_same<T, std::vector<bool> >,
  242. mpl::int_<BooleanVector>,
  243. //else
  244. typename mpl::eval_if<
  245. boost::is_fundamental<T>,
  246. mpl::int_<Primitive>,
  247. //else
  248. typename mpl::eval_if<
  249. boost::is_enum<T>,
  250. mpl::int_<Enum>,
  251. //else
  252. typename mpl::eval_if<
  253. boost::is_class<T>,
  254. mpl::int_<Serializable>,
  255. //else
  256. typename mpl::eval_if<
  257. boost::is_array<T>,
  258. mpl::int_<Array>,
  259. //else
  260. typename mpl::eval_if<
  261. boost::is_pointer<T>,
  262. mpl::int_<Pointer>,
  263. //else
  264. typename mpl::eval_if<
  265. boost::is_enum<T>,
  266. mpl::int_<Primitive>,
  267. //else
  268. mpl::int_<Wrong>
  269. >
  270. >
  271. >
  272. >
  273. >
  274. >
  275. >
  276. >::type type;
  277. static const int value = SerializationLevel::type::value;
  278. };
  279. template <typename T, typename U>
  280. struct VectorisedObjectInfo
  281. {
  282. const std::vector<ConstTransitivePtr<T> > *vector; //pointer to the appropriate vector
  283. const U T::*idPtr; //pointer to the field representing the position in the vector
  284. VectorisedObjectInfo(const std::vector< ConstTransitivePtr<T> > *Vector, const U T::*IdPtr)
  285. :vector(Vector), idPtr(IdPtr)
  286. {
  287. }
  288. };
  289. /// Class which is responsible for storing and loading data.
  290. class DLL_LINKAGE CSerializer
  291. {
  292. public:
  293. typedef std::map<const std::type_info *, boost::any, TypeComparer> TTypeVecMap;
  294. TTypeVecMap vectors; //entry must be a pointer to vector containing pointers to the objects of key type
  295. bool smartVectorMembersSerialization;
  296. bool sendStackInstanceByIds;
  297. CSerializer();
  298. ~CSerializer();
  299. virtual void reportState(CLogger &out){};
  300. template <typename T, typename U>
  301. void registerVectoredType(const std::vector<T*> *Vector, const U T::*IdPtr)
  302. {
  303. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, IdPtr);
  304. }
  305. template <typename T, typename U>
  306. void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const U T::*IdPtr)
  307. {
  308. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, IdPtr);
  309. }
  310. template <typename T, typename U>
  311. const VectorisedObjectInfo<T, U> *getVectorisedTypeInfo()
  312. {
  313. const std::type_info *myType = NULL;
  314. //
  315. // if(boost::is_base_of<CGObjectInstance, T>::value) //ugly workaround to support also types derived from CGObjectInstance -> if we encounter one, treat it aas CGObj..
  316. // myType = &typeid(CGObjectInstance);
  317. // else
  318. myType = &typeid(T);
  319. TTypeVecMap::iterator i = vectors.find(myType);
  320. if(i == vectors.end())
  321. return NULL;
  322. else
  323. {
  324. assert(!i->second.empty());
  325. assert(i->second.type() == typeid(VectorisedObjectInfo<T, U>));
  326. VectorisedObjectInfo<T, U> *ret = &(boost::any_cast<VectorisedObjectInfo<T, U>&>(i->second));
  327. return ret;
  328. }
  329. }
  330. template <typename T, typename U>
  331. T* getVectorItemFromId(const VectorisedObjectInfo<T, U> &oInfo, U id) const
  332. {
  333. /* if(id < 0)
  334. return NULL;*/
  335. si32 idAsNumber = idToNumber(id);
  336. assert(oInfo.vector);
  337. assert(oInfo.vector->size() > idAsNumber);
  338. return const_cast<T*>((*oInfo.vector)[idAsNumber].get());
  339. }
  340. template <typename T, typename U>
  341. U getIdFromVectorItem(const VectorisedObjectInfo<T, U> &oInfo, const T* obj) const
  342. {
  343. if(!obj)
  344. return U(-1);
  345. return obj->*oInfo.idPtr;
  346. }
  347. void addStdVecItems(CGameState *gs, LibClasses *lib = VLC);
  348. };
  349. class DLL_LINKAGE CSaverBase : public virtual CSerializer
  350. {
  351. };
  352. class CBasicPointerSaver
  353. {
  354. public:
  355. virtual void savePtr(CSaverBase &ar, const void *data) const =0;
  356. virtual ~CBasicPointerSaver(){}
  357. };
  358. template <typename Serializer, typename T> class CPointerSaver : public CBasicPointerSaver
  359. {
  360. public:
  361. void savePtr(CSaverBase &ar, const void *data) const
  362. {
  363. Serializer &s = static_cast<Serializer&>(ar);
  364. const T *ptr = static_cast<const T*>(data);
  365. //T is most derived known type, it's time to call actual serialize
  366. const_cast<T&>(*ptr).serialize(s,version);
  367. }
  368. };
  369. template <typename T> //metafunction returning CGObjectInstance if T is its derivate or T elsewise
  370. struct VectorisedTypeFor
  371. {
  372. typedef typename
  373. //if
  374. mpl::eval_if<boost::is_base_of<CGObjectInstance,T>,
  375. mpl::identity<CGObjectInstance>,
  376. //else
  377. mpl::identity<T>
  378. >::type type;
  379. };
  380. template <typename U>
  381. struct VectorizedIDType
  382. {
  383. typedef typename
  384. //if
  385. mpl::eval_if<boost::is_same<CArtifact,U>,
  386. mpl::identity<ArtifactID>,
  387. //else if
  388. mpl::eval_if<boost::is_same<CCreature,U>,
  389. mpl::identity<CreatureID>,
  390. //else if
  391. mpl::eval_if<boost::is_same<CArtifactInstance,U>,
  392. mpl::identity<ArtifactInstanceID>,
  393. //else if
  394. mpl::eval_if<boost::is_base_of<CGObjectInstance,U>,
  395. mpl::identity<ObjectInstanceID>,
  396. //else
  397. mpl::identity<si32>
  398. > > > >::type type;
  399. };
  400. template<typename T>
  401. si32 idToNumber(const T &t, typename boost::enable_if<boost::is_convertible<T,si32> >::type * dummy = 0)
  402. {
  403. return t;
  404. }
  405. template<typename T>
  406. si32 idToNumber(const BaseForID<T> &t)
  407. {
  408. return t.getNum();
  409. }
  410. template <typename Handler>
  411. struct VariantVisitorSaver : boost::static_visitor<>
  412. {
  413. Handler &h;
  414. VariantVisitorSaver(Handler &H):h(H)
  415. {
  416. }
  417. template <typename T>
  418. void operator()(const T &t)
  419. {
  420. h << t;
  421. }
  422. };
  423. template<typename Ser,typename T>
  424. struct SaveIfStackInstance
  425. {
  426. static bool invoke(Ser &s, const T &data)
  427. {
  428. return false;
  429. }
  430. };
  431. template<typename Ser>
  432. struct SaveIfStackInstance<Ser, CStackInstance *>
  433. {
  434. static bool invoke(Ser &s, const CStackInstance* const &data)
  435. {
  436. assert(data->armyObj);
  437. TSlot slot = -1;
  438. if(data->getNodeType() == CBonusSystemNode::COMMANDER)
  439. slot = COMMANDER_SLOT_PLACEHOLDER;
  440. else
  441. slot = data->armyObj->findStack(data);
  442. assert(slot != -1);
  443. s << data->armyObj << slot;
  444. return true;
  445. }
  446. };
  447. template<typename Ser,typename T>
  448. struct LoadIfStackInstance
  449. {
  450. static bool invoke(Ser &s, T &data)
  451. {
  452. return false;
  453. }
  454. };
  455. template<typename Ser>
  456. struct LoadIfStackInstance<Ser, CStackInstance *>
  457. {
  458. static bool invoke(Ser &s, CStackInstance* &data)
  459. {
  460. CArmedInstance *armedObj;
  461. TSlot slot;
  462. s >> armedObj >> slot;
  463. if(slot != COMMANDER_SLOT_PLACEHOLDER)
  464. {
  465. assert(armedObj->hasStackAtSlot(slot));
  466. data = armedObj->stacks[slot];
  467. }
  468. else
  469. {
  470. auto hero = dynamic_cast<CGHeroInstance *>(armedObj);
  471. assert(hero);
  472. assert(hero->commander);
  473. data = hero->commander;
  474. }
  475. return true;
  476. }
  477. };
  478. /// The class which manages saving objects.
  479. template <typename Serializer> class DLL_LINKAGE COSer : public CSaverBase
  480. {
  481. public:
  482. bool saving;
  483. std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type>
  484. std::map<const void*, ui32> savedPointers;
  485. bool smartPointerSerialization;
  486. COSer()
  487. {
  488. saving=true;
  489. smartPointerSerialization = true;
  490. }
  491. ~COSer()
  492. {
  493. std::map<ui16,CBasicPointerSaver*>::iterator iter;
  494. for(iter = savers.begin(); iter != savers.end(); iter++)
  495. delete iter->second;
  496. }
  497. template<typename T> void registerType(const T * t=NULL)
  498. {
  499. ui16 ID = typeList.registerType(t);
  500. savers[ID] = new CPointerSaver<COSer<Serializer>,T>;
  501. }
  502. Serializer * This()
  503. {
  504. return static_cast<Serializer*>(this);
  505. }
  506. template<class T>
  507. Serializer & operator<<(const T &t)
  508. {
  509. this->This()->save(t);
  510. return * this->This();
  511. }
  512. template<class T>
  513. COSer & operator&(const T & t)
  514. {
  515. return * this->This() << t;
  516. }
  517. int write(const void * data, unsigned size);
  518. template <typename T>
  519. void savePrimitive(const T &data)
  520. {
  521. this->This()->write(&data,sizeof(data));
  522. }
  523. template <typename T>
  524. void savePointer(const T &data)
  525. {
  526. //write if pointer is not NULL
  527. ui8 hlp = (data!=NULL);
  528. *this << hlp;
  529. //if pointer is NULL then we don't need anything more...
  530. if(!hlp)
  531. return;
  532. if(smartVectorMembersSerialization)
  533. {
  534. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType;
  535. typedef typename VectorisedTypeFor<TObjectType>::type VType;
  536. typedef typename VectorizedIDType<TObjectType>::type IDType;
  537. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  538. {
  539. IDType id = getIdFromVectorItem<VType>(*info, data);
  540. *this << id;
  541. if(id != IDType(-1)) //vector id is enough
  542. return;
  543. }
  544. }
  545. if(sendStackInstanceByIds)
  546. {
  547. const bool gotSaved = SaveIfStackInstance<Serializer,T>::invoke(*This(), data);
  548. if(gotSaved)
  549. return;
  550. }
  551. if(smartPointerSerialization)
  552. {
  553. std::map<const void*,ui32>::iterator i = savedPointers.find(data);
  554. if(i != savedPointers.end())
  555. {
  556. //this pointer has been already serialized - write only it's id
  557. *this << i->second;
  558. return;
  559. }
  560. //give id to this pointer
  561. ui32 pid = (ui32)savedPointers.size();
  562. savedPointers[data] = pid;
  563. *this << pid;
  564. }
  565. //write type identifier
  566. ui16 tid = typeList.getTypeID(data);
  567. *this << tid;
  568. This()->savePointerHlp(tid, data);
  569. }
  570. //that part of ptr serialization was extracted to allow customization of its behavior in derived classes
  571. template <typename T>
  572. void savePointerHlp(ui16 tid, const T &data)
  573. {
  574. if(!tid)
  575. *this << *data; //if type is unregistered simply write all data in a standard way
  576. else
  577. savers[tid]->savePtr(*this,data); //call serializer specific for our real type
  578. }
  579. template <typename T>
  580. void saveArray(const T &data)
  581. {
  582. ui32 size = ARRAY_COUNT(data);
  583. for(ui32 i=0; i < size; i++)
  584. *this << data[i];
  585. }
  586. template <typename T>
  587. void save(const T &data)
  588. {
  589. typedef
  590. //if
  591. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  592. mpl::identity<SaveBoolean<Serializer> >,
  593. //else if
  594. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  595. mpl::identity<SaveBooleanVector<Serializer> >,
  596. //else if
  597. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  598. mpl::identity<SavePrimitive<Serializer,T> >,
  599. //else if
  600. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  601. mpl::identity<SaveEnum<Serializer,T> >,
  602. //else if
  603. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  604. mpl::identity<SavePointer<Serializer,T> >,
  605. //else if
  606. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  607. mpl::identity<SaveArray<Serializer,T> >,
  608. //else if
  609. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  610. mpl::identity<SaveSerializable<Serializer,T> >,
  611. //else
  612. mpl::identity<SaveWrong<Serializer,T> >
  613. >
  614. >
  615. >
  616. >
  617. >
  618. >
  619. >::type typex;
  620. typex::invoke(* this->This(), data);
  621. }
  622. template <typename T>
  623. void saveSerializable(const T &data)
  624. {
  625. const_cast<T&>(data).serialize(*this,version);
  626. }
  627. template <typename T>
  628. void saveSerializable(const shared_ptr<T> &data)
  629. {
  630. T *internalPtr = data.get();
  631. *this << internalPtr;
  632. }
  633. template <typename T>
  634. void saveSerializable(const unique_ptr<T> &data)
  635. {
  636. T *internalPtr = data.get();
  637. *this << internalPtr;
  638. }
  639. template <typename T>
  640. void saveSerializable(const std::vector<T> &data)
  641. {
  642. ui32 length = data.size();
  643. *this << length;
  644. for(ui32 i=0;i<length;i++)
  645. *this << data[i];
  646. }
  647. template <typename T>
  648. void saveSerializable(const std::set<T> &data)
  649. {
  650. std::set<T> &d = const_cast<std::set<T> &>(data);
  651. ui32 length = d.size();
  652. *this << length;
  653. for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
  654. *this << *i;
  655. }
  656. template <typename T, typename U>
  657. void saveSerializable(const boost::unordered_set<T, U> &data)
  658. {
  659. boost::unordered_set<T, U> &d = const_cast<boost::unordered_set<T, U> &>(data);
  660. ui32 length = d.size();
  661. *this << length;
  662. for(typename boost::unordered_set<T, U>::iterator i=d.begin();i!=d.end();i++)
  663. *this << *i;
  664. }
  665. template <typename T>
  666. void saveSerializable(const std::list<T> &data)
  667. {
  668. std::list<T> &d = const_cast<std::list<T> &>(data);
  669. ui32 length = d.size();
  670. *this << length;
  671. for(typename std::list<T>::iterator i=d.begin();i!=d.end();i++)
  672. *this << *i;
  673. }
  674. void saveSerializable(const std::string &data)
  675. {
  676. *this << ui32(data.length());
  677. this->This()->write(data.c_str(),data.size());
  678. }
  679. template <typename T1, typename T2>
  680. void saveSerializable(const std::pair<T1,T2> &data)
  681. {
  682. *this << data.first << data.second;
  683. }
  684. template <typename T1, typename T2>
  685. void saveSerializable(const std::map<T1,T2> &data)
  686. {
  687. *this << ui32(data.size());
  688. for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
  689. *this << i->first << i->second;
  690. }
  691. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  692. void saveSerializable(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  693. {
  694. si32 which = data.which();
  695. *this << which;
  696. VariantVisitorSaver<Serializer> visitor(*this->This());
  697. boost::apply_visitor(visitor, data);
  698. }
  699. template <typename T>
  700. void saveSerializable(const boost::optional<T> &data)
  701. {
  702. if(data)
  703. {
  704. *this << (ui8)1;
  705. *this << *data;
  706. }
  707. else
  708. {
  709. *this << (ui8)0;
  710. }
  711. }
  712. template <typename E>
  713. void saveEnum(const E &data)
  714. {
  715. si32 writ = static_cast<si32>(data);
  716. *this << writ;
  717. }
  718. void saveBoolean(const bool & data)
  719. {
  720. ui8 writ = static_cast<ui8>(data);
  721. *this << writ;
  722. }
  723. void saveBooleanVector(const std::vector<bool> & data)
  724. {
  725. std::vector<ui8> convData;
  726. std::copy(data.begin(), data.end(), std::back_inserter(convData));
  727. saveSerializable(convData);
  728. }
  729. };
  730. class DLL_LINKAGE CLoaderBase : public virtual CSerializer
  731. {};
  732. class CBasicPointerLoader
  733. {
  734. public:
  735. virtual void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
  736. virtual ~CBasicPointerLoader(){}
  737. };
  738. template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
  739. {
  740. public:
  741. void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const //data is pointer to the ACTUAL POINTER
  742. {
  743. Serializer &s = static_cast<Serializer&>(ar);
  744. T *&ptr = *static_cast<T**>(data);
  745. //create new object under pointer
  746. typedef typename boost::remove_pointer<T>::type npT;
  747. ptr = new npT;
  748. s.ptrAllocated(ptr, pid);
  749. //T is most derived known type, it's time to call actual serialize
  750. ptr->serialize(s,version);
  751. }
  752. };
  753. /// The class which manages loading of objects.
  754. template <typename Serializer> class DLL_LINKAGE CISer : public CLoaderBase
  755. {
  756. public:
  757. bool saving;
  758. std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
  759. ui32 fileVersion;
  760. bool reverseEndianess; //if source has different endianess than us, we reverse bytes
  761. std::map<ui32, void*> loadedPointers;
  762. bool smartPointerSerialization;
  763. CISer()
  764. {
  765. saving = false;
  766. fileVersion = 0;
  767. smartPointerSerialization = true;
  768. reverseEndianess = false;
  769. }
  770. ~CISer()
  771. {
  772. std::map<ui16,CBasicPointerLoader*>::iterator iter;
  773. for(iter = loaders.begin(); iter != loaders.end(); iter++)
  774. delete iter->second;
  775. }
  776. template<typename T> void registerType(const T * t=NULL)
  777. {
  778. ui16 ID = typeList.registerType(t);
  779. loaders[ID] = new CPointerLoader<CISer<Serializer>,T>;
  780. }
  781. Serializer * This()
  782. {
  783. return static_cast<Serializer*>(this);
  784. }
  785. template<class T>
  786. Serializer & operator>>(T &t)
  787. {
  788. this->This()->load(t);
  789. return * this->This();
  790. }
  791. template<class T>
  792. CISer & operator&(T & t)
  793. {
  794. return * this->This() >> t;
  795. }
  796. int write(const void * data, unsigned size);
  797. template <typename T>
  798. void load(T &data)
  799. {
  800. typedef
  801. //if
  802. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  803. mpl::identity<LoadBoolean<Serializer> >,
  804. //else if
  805. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  806. mpl::identity<LoadBooleanVector<Serializer> >,
  807. //else if
  808. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  809. mpl::identity<LoadPrimitive<Serializer,T> >,
  810. //else if
  811. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  812. mpl::identity<LoadEnum<Serializer,T> >,
  813. //else if
  814. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  815. mpl::identity<LoadPointer<Serializer,T> >,
  816. //else if
  817. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  818. mpl::identity<LoadArray<Serializer,T> >,
  819. //else if
  820. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  821. mpl::identity<LoadSerializable<Serializer,T> >,
  822. //else
  823. mpl::identity<LoadWrong<Serializer,T> >
  824. >
  825. >
  826. >
  827. >
  828. >
  829. >
  830. >::type typex;
  831. typex::invoke(* this->This(), data);
  832. }
  833. template <typename T>
  834. void loadPrimitive(T &data)
  835. {
  836. if(0) //for testing #989
  837. {
  838. this->This()->read(&data,sizeof(data));
  839. }
  840. else
  841. {
  842. unsigned length = sizeof(data);
  843. char* dataPtr = (char*)&data;
  844. this->This()->read(dataPtr,length);
  845. if(reverseEndianess)
  846. std::reverse(dataPtr, dataPtr + length);
  847. }
  848. }
  849. template <typename T>
  850. void loadSerializableBySerializeCall(T &data)
  851. {
  852. ////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
  853. typedef typename boost::remove_const<T>::type nonConstT;
  854. nonConstT &hlp = const_cast<nonConstT&>(data);
  855. hlp.serialize(*this,fileVersion);
  856. //data.serialize(*this,myVersion);
  857. }
  858. template <typename T>
  859. void loadSerializable(T &data)
  860. {
  861. loadSerializableBySerializeCall(data);
  862. }
  863. template <typename T>
  864. void loadArray(T &data)
  865. {
  866. ui32 size = ARRAY_COUNT(data);
  867. for(ui32 i = 0; i < size; i++)
  868. *this >> data[i];
  869. }
  870. template <typename T>
  871. void loadPointer(T &data)
  872. {
  873. ui8 hlp;
  874. *this >> hlp;
  875. if(!hlp)
  876. {
  877. data = NULL;
  878. return;
  879. }
  880. if(smartVectorMembersSerialization)
  881. {
  882. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
  883. typedef typename VectorisedTypeFor<TObjectType>::type VType; //eg: CGHeroInstance -> CGobjectInstance
  884. typedef typename VectorizedIDType<TObjectType>::type IDType;
  885. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  886. {
  887. IDType id;
  888. *this >> id;
  889. if(id != IDType(-1))
  890. {
  891. data = static_cast<T>(getVectorItemFromId<VType, IDType>(*info, id));
  892. return;
  893. }
  894. }
  895. }
  896. if(sendStackInstanceByIds)
  897. {
  898. bool gotLoaded = LoadIfStackInstance<Serializer,T>::invoke(*This(), data);
  899. if(gotLoaded)
  900. return;
  901. }
  902. ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id)
  903. if(smartPointerSerialization)
  904. {
  905. *this >> pid; //get the id
  906. std::map<ui32, void*>::iterator i = loadedPointers.find(pid); //lookup
  907. if(i != loadedPointers.end())
  908. {
  909. //we already got this pointer
  910. data = static_cast<T>(i->second);
  911. return;
  912. }
  913. }
  914. //get type id
  915. ui16 tid;
  916. *this >> tid;
  917. This()->loadPointerHlp(tid, data, pid);
  918. }
  919. //that part of ptr deserialization was extracted to allow customization of its behavior in derived classes
  920. template <typename T>
  921. void loadPointerHlp( ui16 tid, T & data, ui32 pid )
  922. {
  923. if(!tid)
  924. {
  925. typedef typename boost::remove_pointer<T>::type npT;
  926. typedef typename boost::remove_const<npT>::type ncpT;
  927. data = new ncpT;
  928. ptrAllocated(data, pid);
  929. *this >> *data;
  930. }
  931. else
  932. {
  933. loaders[tid]->loadPtr(*this,&data, pid);
  934. }
  935. }
  936. template <typename T>
  937. void ptrAllocated(const T *ptr, ui32 pid)
  938. {
  939. if(smartPointerSerialization && pid != 0xffffffff)
  940. loadedPointers[pid] = (void*)ptr; //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
  941. }
  942. #define READ_CHECK_U32(x) \
  943. ui32 length; \
  944. *this >> length; \
  945. if(length > 500000) \
  946. { \
  947. tlog2 << "Warning: very big length: " << length << "\n" ;\
  948. reportState(tlog2); \
  949. };
  950. template <typename T>
  951. void loadSerializable(shared_ptr<T> &data)
  952. {
  953. T *internalPtr;
  954. *this >> internalPtr;
  955. data.reset(internalPtr);
  956. }
  957. template <typename T>
  958. void loadSerializable(unique_ptr<T> &data)
  959. {
  960. T *internalPtr;
  961. *this >> internalPtr;
  962. data.reset(internalPtr);
  963. }
  964. template <typename T>
  965. void loadSerializable(std::vector<T> &data)
  966. {
  967. READ_CHECK_U32(length);
  968. data.resize(length);
  969. for(ui32 i=0;i<length;i++)
  970. *this >> data[i];
  971. }
  972. template <typename T>
  973. void loadSerializable(std::set<T> &data)
  974. {
  975. READ_CHECK_U32(length);
  976. T ins;
  977. for(ui32 i=0;i<length;i++)
  978. {
  979. *this >> ins;
  980. data.insert(ins);
  981. }
  982. }
  983. template <typename T, typename U>
  984. void loadSerializable(boost::unordered_set<T, U> &data)
  985. {
  986. READ_CHECK_U32(length);
  987. T ins;
  988. for(ui32 i=0;i<length;i++)
  989. {
  990. *this >> ins;
  991. data.insert(ins);
  992. }
  993. }
  994. template <typename T>
  995. void loadSerializable(std::list<T> &data)
  996. {
  997. READ_CHECK_U32(length);
  998. T ins;
  999. for(ui32 i=0;i<length;i++)
  1000. {
  1001. *this >> ins;
  1002. data.push_back(ins);
  1003. }
  1004. }
  1005. template <typename T1, typename T2>
  1006. void loadSerializable(std::pair<T1,T2> &data)
  1007. {
  1008. *this >> data.first >> data.second;
  1009. }
  1010. template <typename T1, typename T2>
  1011. void loadSerializable(std::map<T1,T2> &data)
  1012. {
  1013. READ_CHECK_U32(length);
  1014. T1 t;
  1015. for(ui32 i=0;i<length;i++)
  1016. {
  1017. *this >> t;
  1018. *this >> data[t];
  1019. }
  1020. }
  1021. void loadSerializable(std::string &data)
  1022. {
  1023. READ_CHECK_U32(length);
  1024. data.resize(length);
  1025. this->This()->read((void*)data.c_str(),length);
  1026. }
  1027. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  1028. void loadSerializable(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  1029. {
  1030. si32 which;
  1031. *this >> which;
  1032. if(which == 0)
  1033. {
  1034. T0 obj;
  1035. *this >> obj;
  1036. data = obj;
  1037. }
  1038. else if(which == 1)
  1039. {
  1040. T1 obj;
  1041. *this >> obj;
  1042. data = obj;
  1043. }
  1044. else
  1045. assert(0);
  1046. //TODO write more if needed, general solution would be much longer
  1047. }
  1048. template <typename T>
  1049. void loadSerializable(boost::optional<T> & data)
  1050. {
  1051. ui8 present;
  1052. *this >> present;
  1053. if(present)
  1054. {
  1055. T t;
  1056. *this >> t;
  1057. data = t;
  1058. }
  1059. else
  1060. {
  1061. data = boost::optional<T>();
  1062. }
  1063. }
  1064. void loadSerializable(CStackInstance *&s)
  1065. {
  1066. if(sendStackInstanceByIds)
  1067. {
  1068. CArmedInstance *armed;
  1069. TSlot slot;
  1070. *this >> armed >> slot;
  1071. assert(armed->hasStackAtSlot(slot));
  1072. s = armed->stacks[slot];
  1073. }
  1074. else
  1075. loadSerializableBySerializeCall(s);
  1076. }
  1077. template <typename E>
  1078. void loadEnum(E &data)
  1079. {
  1080. si32 read;
  1081. *this >> read;
  1082. data = static_cast<E>(read);
  1083. }
  1084. void loadBoolean(bool &data)
  1085. {
  1086. ui8 read;
  1087. *this >> read;
  1088. data = static_cast<bool>(read);
  1089. }
  1090. void loadBooleanVector(std::vector<bool> & data)
  1091. {
  1092. std::vector<ui8> convData;
  1093. loadSerializable(convData);
  1094. std::copy(convData.begin(), convData.end(), std::back_inserter(data));
  1095. }
  1096. };
  1097. class DLL_LINKAGE CSaveFile
  1098. : public COSer<CSaveFile>
  1099. {
  1100. void dummyMagicFunction()
  1101. {
  1102. *this << std::string("This function makes stuff working.");
  1103. }
  1104. public:
  1105. std::string fName;
  1106. unique_ptr<std::ofstream> sfile;
  1107. CSaveFile(const std::string &fname); //throws!
  1108. ~CSaveFile();
  1109. int write(const void * data, unsigned size);
  1110. void openNextFile(const std::string &fname); //throws!
  1111. void clear();
  1112. void reportState(CLogger &out);
  1113. };
  1114. class DLL_LINKAGE CLoadFile
  1115. : public CISer<CLoadFile>
  1116. {
  1117. void dummyMagicFunction()
  1118. {
  1119. std::string dummy = "This function makes stuff working.";
  1120. *this >> dummy;
  1121. }
  1122. public:
  1123. std::string fName;
  1124. unique_ptr<std::ifstream> sfile;
  1125. CLoadFile(const std::string &fname, int minimalVersion = version); //throws!
  1126. ~CLoadFile();
  1127. int read(const void * data, unsigned size); //throws!
  1128. void openNextFile(const std::string &fname, int minimalVersion); //throws!
  1129. void clear();
  1130. void reportState(CLogger &out);
  1131. };
  1132. typedef boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > TSocket;
  1133. typedef boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > TAcceptor;
  1134. class DLL_LINKAGE CConnection
  1135. :public CISer<CConnection>, public COSer<CConnection>
  1136. {
  1137. //CGameState *gs;
  1138. CConnection(void);
  1139. void init();
  1140. void reportState(CLogger &out);
  1141. public:
  1142. boost::mutex *rmx, *wmx; // read/write mutexes
  1143. TSocket * socket;
  1144. bool logging;
  1145. bool connected;
  1146. bool myEndianess, contactEndianess; //true if little endian, if endianess is different we'll have to revert received multi-byte vars
  1147. boost::asio::io_service *io_service;
  1148. std::string name; //who uses this connection
  1149. int connectionID;
  1150. boost::thread *handler;
  1151. bool receivedStop, sendStop;
  1152. CConnection(std::string host, std::string port, std::string Name);
  1153. CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name);
  1154. CConnection(TSocket * Socket, std::string Name); //use immediately after accepting connection into socket
  1155. int write(const void * data, unsigned size);
  1156. int read(void * data, unsigned size);
  1157. void close();
  1158. bool isOpen() const;
  1159. template<class T>
  1160. CConnection &operator&(const T&);
  1161. virtual ~CConnection(void);
  1162. CPack *retreivePack(); //gets from server next pack (allocates it with new)
  1163. void sendPackToServer(const CPack &pack, TPlayerColor player, ui32 requestID);
  1164. void disableStackSendingByID();
  1165. void enableStackSendingByID();
  1166. void disableSmartPointerSerialization();
  1167. void enableSmartPointerSerializatoin();
  1168. void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache
  1169. };
  1170. DLL_LINKAGE std::ostream &operator<<(std::ostream &str, const CConnection &cpc);
  1171. template<typename T>
  1172. class CApplier
  1173. {
  1174. public:
  1175. std::map<ui16,T*> apps;
  1176. ~CApplier()
  1177. {
  1178. typename std::map<ui16, T*>::iterator iter;
  1179. for(iter = apps.begin(); iter != apps.end(); iter++)
  1180. delete iter->second;
  1181. }
  1182. template<typename U> void registerType(const U * t=NULL)
  1183. {
  1184. ui16 ID = typeList.registerType(t);
  1185. apps[ID] = T::getApplier(t);
  1186. }
  1187. };