Connection.h 31 KB

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