2
0

Connection.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  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 = 741;
  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 = nullptr)
  80. {
  81. return registerType(getTypeInfo(t));
  82. }
  83. ui16 getTypeID(const std::type_info *type);
  84. template <typename T> ui16 getTypeID(const T * t = nullptr)
  85. {
  86. return getTypeID(getTypeInfo(t));
  87. }
  88. template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr)
  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 ObjType, typename IdType>
  274. struct VectorisedObjectInfo
  275. {
  276. const std::vector<ConstTransitivePtr<ObjType> > *vector; //pointer to the appropriate vector
  277. std::function<IdType(const ObjType &)> idRetriever;
  278. //const IdType ObjType::*idPtr; //pointer to the field representing the position in the vector
  279. VectorisedObjectInfo(const std::vector< ConstTransitivePtr<ObjType> > *Vector, std::function<IdType(const ObjType &)> IdGetter)
  280. :vector(Vector), idRetriever(IdGetter)
  281. {
  282. }
  283. };
  284. template<typename T>
  285. si32 idToNumber(const T &t, typename boost::enable_if<boost::is_convertible<T,si32> >::type * dummy = 0)
  286. {
  287. return t;
  288. }
  289. template<typename T, typename NT>
  290. NT idToNumber(const BaseForID<T, NT> &t)
  291. {
  292. return t.getNum();
  293. }
  294. /// Class which is responsible for storing and loading data.
  295. class DLL_LINKAGE CSerializer
  296. {
  297. public:
  298. typedef std::map<const std::type_info *, boost::any, TypeComparer> TTypeVecMap;
  299. TTypeVecMap vectors; //entry must be a pointer to vector containing pointers to the objects of key type
  300. bool smartVectorMembersSerialization;
  301. bool sendStackInstanceByIds;
  302. CSerializer();
  303. ~CSerializer();
  304. virtual void reportState(CLogger * out){};
  305. template <typename T, typename U>
  306. void registerVectoredType(const std::vector<T*> *Vector, const std::function<U(const T&)> &idRetriever)
  307. {
  308. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, idRetriever);
  309. }
  310. template <typename T, typename U>
  311. void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const std::function<U(const T&)> &idRetriever)
  312. {
  313. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, idRetriever);
  314. }
  315. template <typename T, typename U>
  316. const VectorisedObjectInfo<T, U> *getVectorisedTypeInfo()
  317. {
  318. const std::type_info *myType = nullptr;
  319. //
  320. // 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..
  321. // myType = &typeid(CGObjectInstance);
  322. // else
  323. myType = &typeid(T);
  324. TTypeVecMap::iterator i = vectors.find(myType);
  325. if(i == vectors.end())
  326. return nullptr;
  327. else
  328. {
  329. assert(!i->second.empty());
  330. assert(i->second.type() == typeid(VectorisedObjectInfo<T, U>));
  331. VectorisedObjectInfo<T, U> *ret = &(boost::any_cast<VectorisedObjectInfo<T, U>&>(i->second));
  332. return ret;
  333. }
  334. }
  335. template <typename T, typename U>
  336. T* getVectorItemFromId(const VectorisedObjectInfo<T, U> &oInfo, U id) const
  337. {
  338. /* if(id < 0)
  339. return nullptr;*/
  340. si32 idAsNumber = idToNumber(id);
  341. assert(oInfo.vector);
  342. assert(static_cast<si32>(oInfo.vector->size()) > idAsNumber);
  343. return const_cast<T*>((*oInfo.vector)[idAsNumber].get());
  344. }
  345. template <typename T, typename U>
  346. U getIdFromVectorItem(const VectorisedObjectInfo<T, U> &oInfo, const T* obj) const
  347. {
  348. if(!obj)
  349. return U(-1);
  350. return oInfo.idRetriever(*obj);
  351. }
  352. void addStdVecItems(CGameState *gs, LibClasses *lib = VLC);
  353. };
  354. class DLL_LINKAGE CSaverBase : public virtual CSerializer
  355. {
  356. };
  357. class CBasicPointerSaver
  358. {
  359. public:
  360. virtual void savePtr(CSaverBase &ar, const void *data) const =0;
  361. virtual ~CBasicPointerSaver(){}
  362. };
  363. template <typename Serializer, typename T> class CPointerSaver : public CBasicPointerSaver
  364. {
  365. public:
  366. void savePtr(CSaverBase &ar, const void *data) const
  367. {
  368. Serializer &s = static_cast<Serializer&>(ar);
  369. const T *ptr = static_cast<const T*>(data);
  370. //T is most derived known type, it's time to call actual serialize
  371. const_cast<T&>(*ptr).serialize(s,version);
  372. }
  373. };
  374. template <typename T> //metafunction returning CGObjectInstance if T is its derivate or T elsewise
  375. struct VectorisedTypeFor
  376. {
  377. typedef typename
  378. //if
  379. mpl::eval_if<boost::is_same<CGHeroInstance,T>,
  380. mpl::identity<CGHeroInstance>,
  381. //else if
  382. mpl::eval_if<boost::is_base_of<CGObjectInstance,T>,
  383. mpl::identity<CGObjectInstance>,
  384. //else
  385. mpl::identity<T>
  386. > >::type type;
  387. };
  388. template <typename U>
  389. struct VectorizedIDType
  390. {
  391. typedef typename
  392. //if
  393. mpl::eval_if<boost::is_same<CArtifact,U>,
  394. mpl::identity<ArtifactID>,
  395. //else if
  396. mpl::eval_if<boost::is_same<CCreature,U>,
  397. mpl::identity<CreatureID>,
  398. //else if
  399. mpl::eval_if<boost::is_same<CHero,U>,
  400. mpl::identity<HeroTypeID>,
  401. //else if
  402. mpl::eval_if<boost::is_same<CArtifactInstance,U>,
  403. mpl::identity<ArtifactInstanceID>,
  404. //else if
  405. mpl::eval_if<boost::is_same<CGHeroInstance,U>,
  406. mpl::identity<HeroTypeID>,
  407. //else if
  408. mpl::eval_if<boost::is_base_of<CGObjectInstance,U>,
  409. mpl::identity<ObjectInstanceID>,
  410. //else
  411. mpl::identity<si32>
  412. > > > > > >::type type;
  413. };
  414. template <typename Handler>
  415. struct VariantVisitorSaver : boost::static_visitor<>
  416. {
  417. Handler &h;
  418. VariantVisitorSaver(Handler &H):h(H)
  419. {
  420. }
  421. template <typename T>
  422. void operator()(const T &t)
  423. {
  424. h << t;
  425. }
  426. };
  427. template<typename Ser,typename T>
  428. struct SaveIfStackInstance
  429. {
  430. static bool invoke(Ser &s, const T &data)
  431. {
  432. return false;
  433. }
  434. };
  435. template<typename Ser>
  436. struct SaveIfStackInstance<Ser, CStackInstance *>
  437. {
  438. static bool invoke(Ser &s, const CStackInstance* const &data)
  439. {
  440. assert(data->armyObj);
  441. SlotID slot;
  442. if(data->getNodeType() == CBonusSystemNode::COMMANDER)
  443. slot = SlotID::COMMANDER_SLOT_PLACEHOLDER;
  444. else
  445. slot = data->armyObj->findStack(data);
  446. assert(slot != SlotID());
  447. s << data->armyObj << slot;
  448. return true;
  449. }
  450. };
  451. template<typename Ser,typename T>
  452. struct LoadIfStackInstance
  453. {
  454. static bool invoke(Ser &s, T &data)
  455. {
  456. return false;
  457. }
  458. };
  459. template<typename Ser>
  460. struct LoadIfStackInstance<Ser, CStackInstance *>
  461. {
  462. static bool invoke(Ser &s, CStackInstance* &data)
  463. {
  464. CArmedInstance *armedObj;
  465. SlotID slot;
  466. s >> armedObj >> slot;
  467. if(slot != SlotID::COMMANDER_SLOT_PLACEHOLDER)
  468. {
  469. assert(armedObj->hasStackAtSlot(slot));
  470. data = armedObj->stacks[slot];
  471. }
  472. else
  473. {
  474. auto hero = dynamic_cast<CGHeroInstance *>(armedObj);
  475. assert(hero);
  476. assert(hero->commander);
  477. data = hero->commander;
  478. }
  479. return true;
  480. }
  481. };
  482. /// The class which manages saving objects.
  483. template <typename Serializer> class DLL_LINKAGE COSer : public CSaverBase
  484. {
  485. public:
  486. bool saving;
  487. std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type>
  488. std::map<const void*, ui32> savedPointers;
  489. bool smartPointerSerialization;
  490. COSer()
  491. {
  492. saving=true;
  493. smartPointerSerialization = true;
  494. }
  495. ~COSer()
  496. {
  497. std::map<ui16,CBasicPointerSaver*>::iterator iter;
  498. for(iter = savers.begin(); iter != savers.end(); iter++)
  499. delete iter->second;
  500. }
  501. template<typename T> void registerType(const T * t=nullptr)
  502. {
  503. ui16 ID = typeList.registerType(t);
  504. savers[ID] = new CPointerSaver<COSer<Serializer>,T>;
  505. }
  506. Serializer * This()
  507. {
  508. return static_cast<Serializer*>(this);
  509. }
  510. template<class T>
  511. Serializer & operator<<(const T &t)
  512. {
  513. this->This()->save(t);
  514. return * this->This();
  515. }
  516. template<class T>
  517. COSer & operator&(const T & t)
  518. {
  519. return * this->This() << t;
  520. }
  521. int write(const void * data, unsigned size);
  522. template <typename T>
  523. void savePrimitive(const T &data)
  524. {
  525. this->This()->write(&data,sizeof(data));
  526. }
  527. template <typename T>
  528. void savePointer(const T &data)
  529. {
  530. //write if pointer is not nullptr
  531. ui8 hlp = (data!=nullptr);
  532. *this << hlp;
  533. //if pointer is nullptr then we don't need anything more...
  534. if(!hlp)
  535. return;
  536. if(smartVectorMembersSerialization)
  537. {
  538. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType;
  539. typedef typename VectorisedTypeFor<TObjectType>::type VType;
  540. typedef typename VectorizedIDType<TObjectType>::type IDType;
  541. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  542. {
  543. IDType id = getIdFromVectorItem<VType>(*info, data);
  544. *this << id;
  545. if(id != IDType(-1)) //vector id is enough
  546. return;
  547. }
  548. }
  549. if(sendStackInstanceByIds)
  550. {
  551. const bool gotSaved = SaveIfStackInstance<Serializer,T>::invoke(*This(), data);
  552. if(gotSaved)
  553. return;
  554. }
  555. if(smartPointerSerialization)
  556. {
  557. std::map<const void*,ui32>::iterator i = savedPointers.find(data);
  558. if(i != savedPointers.end())
  559. {
  560. //this pointer has been already serialized - write only it's id
  561. *this << i->second;
  562. return;
  563. }
  564. //give id to this pointer
  565. ui32 pid = (ui32)savedPointers.size();
  566. savedPointers[data] = pid;
  567. *this << pid;
  568. }
  569. //write type identifier
  570. ui16 tid = typeList.getTypeID(data);
  571. *this << tid;
  572. This()->savePointerHlp(tid, data);
  573. }
  574. //that part of ptr serialization was extracted to allow customization of its behavior in derived classes
  575. template <typename T>
  576. void savePointerHlp(ui16 tid, const T &data)
  577. {
  578. if(!tid)
  579. *this << *data; //if type is unregistered simply write all data in a standard way
  580. else
  581. savers[tid]->savePtr(*this,data); //call serializer specific for our real type
  582. }
  583. template <typename T>
  584. void saveArray(const T &data)
  585. {
  586. ui32 size = ARRAY_COUNT(data);
  587. for(ui32 i=0; i < size; i++)
  588. *this << data[i];
  589. }
  590. template <typename T>
  591. void save(const T &data)
  592. {
  593. typedef
  594. //if
  595. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  596. mpl::identity<SaveBoolean<Serializer> >,
  597. //else if
  598. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  599. mpl::identity<SaveBooleanVector<Serializer> >,
  600. //else if
  601. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  602. mpl::identity<SavePrimitive<Serializer,T> >,
  603. //else if
  604. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  605. mpl::identity<SaveEnum<Serializer,T> >,
  606. //else if
  607. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  608. mpl::identity<SavePointer<Serializer,T> >,
  609. //else if
  610. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  611. mpl::identity<SaveArray<Serializer,T> >,
  612. //else if
  613. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  614. mpl::identity<SaveSerializable<Serializer,T> >,
  615. //else
  616. mpl::identity<SaveWrong<Serializer,T> >
  617. >
  618. >
  619. >
  620. >
  621. >
  622. >
  623. >::type typex;
  624. typex::invoke(* this->This(), data);
  625. }
  626. template <typename T>
  627. void saveSerializable(const T &data)
  628. {
  629. const_cast<T&>(data).serialize(*this,version);
  630. }
  631. template <typename T>
  632. void saveSerializable(const shared_ptr<T> &data)
  633. {
  634. T *internalPtr = data.get();
  635. *this << internalPtr;
  636. }
  637. template <typename T>
  638. void saveSerializable(const unique_ptr<T> &data)
  639. {
  640. T *internalPtr = data.get();
  641. *this << internalPtr;
  642. }
  643. template <typename T>
  644. void saveSerializable(const std::vector<T> &data)
  645. {
  646. ui32 length = data.size();
  647. *this << length;
  648. for(ui32 i=0;i<length;i++)
  649. *this << data[i];
  650. }
  651. template <typename T, size_t N>
  652. void saveSerializable(const std::array<T, N> &data)
  653. {
  654. for(ui32 i=0; i < N; i++)
  655. *this << data[i];
  656. }
  657. template <typename T>
  658. void saveSerializable(const std::set<T> &data)
  659. {
  660. std::set<T> &d = const_cast<std::set<T> &>(data);
  661. ui32 length = d.size();
  662. *this << length;
  663. for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
  664. *this << *i;
  665. }
  666. template <typename T, typename U>
  667. void saveSerializable(const boost::unordered_set<T, U> &data)
  668. {
  669. boost::unordered_set<T, U> &d = const_cast<boost::unordered_set<T, U> &>(data);
  670. ui32 length = d.size();
  671. *this << length;
  672. for(typename boost::unordered_set<T, U>::iterator i=d.begin();i!=d.end();i++)
  673. *this << *i;
  674. }
  675. template <typename T>
  676. void saveSerializable(const std::list<T> &data)
  677. {
  678. std::list<T> &d = const_cast<std::list<T> &>(data);
  679. ui32 length = d.size();
  680. *this << length;
  681. for(typename std::list<T>::iterator i=d.begin();i!=d.end();i++)
  682. *this << *i;
  683. }
  684. void saveSerializable(const std::string &data)
  685. {
  686. *this << ui32(data.length());
  687. this->This()->write(data.c_str(),data.size());
  688. }
  689. template <typename T1, typename T2>
  690. void saveSerializable(const std::pair<T1,T2> &data)
  691. {
  692. *this << data.first << data.second;
  693. }
  694. template <typename T1, typename T2>
  695. void saveSerializable(const std::map<T1,T2> &data)
  696. {
  697. *this << ui32(data.size());
  698. for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
  699. *this << i->first << i->second;
  700. }
  701. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  702. void saveSerializable(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  703. {
  704. si32 which = data.which();
  705. *this << which;
  706. VariantVisitorSaver<Serializer> visitor(*this->This());
  707. boost::apply_visitor(visitor, data);
  708. }
  709. template <typename T>
  710. void saveSerializable(const boost::optional<T> &data)
  711. {
  712. if(data)
  713. {
  714. *this << (ui8)1;
  715. *this << *data;
  716. }
  717. else
  718. {
  719. *this << (ui8)0;
  720. }
  721. }
  722. template <typename E>
  723. void saveEnum(const E &data)
  724. {
  725. si32 writ = static_cast<si32>(data);
  726. *this << writ;
  727. }
  728. void saveBoolean(const bool & data)
  729. {
  730. ui8 writ = static_cast<ui8>(data);
  731. *this << writ;
  732. }
  733. void saveBooleanVector(const std::vector<bool> & data)
  734. {
  735. std::vector<ui8> convData;
  736. std::copy(data.begin(), data.end(), std::back_inserter(convData));
  737. saveSerializable(convData);
  738. }
  739. };
  740. class DLL_LINKAGE CLoaderBase : public virtual CSerializer
  741. {};
  742. class CBasicPointerLoader
  743. {
  744. public:
  745. virtual void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
  746. virtual ~CBasicPointerLoader(){}
  747. };
  748. template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
  749. {
  750. public:
  751. void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const //data is pointer to the ACTUAL POINTER
  752. {
  753. Serializer &s = static_cast<Serializer&>(ar);
  754. T *&ptr = *static_cast<T**>(data);
  755. //create new object under pointer
  756. typedef typename boost::remove_pointer<T>::type npT;
  757. ptr = new npT;
  758. s.ptrAllocated(ptr, pid);
  759. //T is most derived known type, it's time to call actual serialize
  760. ptr->serialize(s,version);
  761. }
  762. };
  763. /// The class which manages loading of objects.
  764. template <typename Serializer> class DLL_LINKAGE CISer : public CLoaderBase
  765. {
  766. public:
  767. bool saving;
  768. std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
  769. ui32 fileVersion;
  770. bool reverseEndianess; //if source has different endianess than us, we reverse bytes
  771. std::map<ui32, void*> loadedPointers;
  772. std::map<const void*, boost::any> loadedSharedPointers;
  773. bool smartPointerSerialization;
  774. CISer()
  775. {
  776. saving = false;
  777. fileVersion = 0;
  778. smartPointerSerialization = true;
  779. reverseEndianess = false;
  780. }
  781. ~CISer()
  782. {
  783. std::map<ui16,CBasicPointerLoader*>::iterator iter;
  784. for(iter = loaders.begin(); iter != loaders.end(); iter++)
  785. delete iter->second;
  786. }
  787. template<typename T> void registerType(const T * t=nullptr)
  788. {
  789. ui16 ID = typeList.registerType(t);
  790. loaders[ID] = new CPointerLoader<CISer<Serializer>,T>;
  791. }
  792. Serializer * This()
  793. {
  794. return static_cast<Serializer*>(this);
  795. }
  796. template<class T>
  797. Serializer & operator>>(T &t)
  798. {
  799. this->This()->load(t);
  800. return * this->This();
  801. }
  802. template<class T>
  803. CISer & operator&(T & t)
  804. {
  805. return * this->This() >> t;
  806. }
  807. int write(const void * data, unsigned size);
  808. template <typename T>
  809. void load(T &data)
  810. {
  811. typedef
  812. //if
  813. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  814. mpl::identity<LoadBoolean<Serializer> >,
  815. //else if
  816. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  817. mpl::identity<LoadBooleanVector<Serializer> >,
  818. //else if
  819. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  820. mpl::identity<LoadPrimitive<Serializer,T> >,
  821. //else if
  822. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  823. mpl::identity<LoadEnum<Serializer,T> >,
  824. //else if
  825. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  826. mpl::identity<LoadPointer<Serializer,T> >,
  827. //else if
  828. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  829. mpl::identity<LoadArray<Serializer,T> >,
  830. //else if
  831. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  832. mpl::identity<LoadSerializable<Serializer,T> >,
  833. //else
  834. mpl::identity<LoadWrong<Serializer,T> >
  835. >
  836. >
  837. >
  838. >
  839. >
  840. >
  841. >::type typex;
  842. typex::invoke(* this->This(), data);
  843. }
  844. template <typename T>
  845. void loadPrimitive(T &data)
  846. {
  847. if(0) //for testing #989
  848. {
  849. this->This()->read(&data,sizeof(data));
  850. }
  851. else
  852. {
  853. unsigned length = sizeof(data);
  854. char* dataPtr = (char*)&data;
  855. this->This()->read(dataPtr,length);
  856. if(reverseEndianess)
  857. std::reverse(dataPtr, dataPtr + length);
  858. }
  859. }
  860. template <typename T>
  861. void loadSerializableBySerializeCall(T &data)
  862. {
  863. ////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
  864. typedef typename boost::remove_const<T>::type nonConstT;
  865. nonConstT &hlp = const_cast<nonConstT&>(data);
  866. hlp.serialize(*this,fileVersion);
  867. //data.serialize(*this,myVersion);
  868. }
  869. template <typename T>
  870. void loadSerializable(T &data)
  871. {
  872. loadSerializableBySerializeCall(data);
  873. }
  874. template <typename T>
  875. void loadArray(T &data)
  876. {
  877. ui32 size = ARRAY_COUNT(data);
  878. for(ui32 i = 0; i < size; i++)
  879. *this >> data[i];
  880. }
  881. template <typename T>
  882. void loadPointer(T &data)
  883. {
  884. ui8 hlp;
  885. *this >> hlp;
  886. if(!hlp)
  887. {
  888. data = nullptr;
  889. return;
  890. }
  891. if(smartVectorMembersSerialization)
  892. {
  893. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
  894. typedef typename VectorisedTypeFor<TObjectType>::type VType; //eg: CGHeroInstance -> CGobjectInstance
  895. typedef typename VectorizedIDType<TObjectType>::type IDType;
  896. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  897. {
  898. IDType id;
  899. *this >> id;
  900. if(id != IDType(-1))
  901. {
  902. data = static_cast<T>(getVectorItemFromId<VType, IDType>(*info, id));
  903. return;
  904. }
  905. }
  906. }
  907. if(sendStackInstanceByIds)
  908. {
  909. bool gotLoaded = LoadIfStackInstance<Serializer,T>::invoke(*This(), data);
  910. if(gotLoaded)
  911. return;
  912. }
  913. ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id)
  914. if(smartPointerSerialization)
  915. {
  916. *this >> pid; //get the id
  917. std::map<ui32, void*>::iterator i = loadedPointers.find(pid); //lookup
  918. if(i != loadedPointers.end())
  919. {
  920. //we already got this pointer
  921. data = static_cast<T>(i->second);
  922. return;
  923. }
  924. }
  925. //get type id
  926. ui16 tid;
  927. *this >> tid;
  928. This()->loadPointerHlp(tid, data, pid);
  929. }
  930. //that part of ptr deserialization was extracted to allow customization of its behavior in derived classes
  931. template <typename T>
  932. void loadPointerHlp( ui16 tid, T & data, ui32 pid )
  933. {
  934. if(!tid)
  935. {
  936. typedef typename boost::remove_pointer<T>::type npT;
  937. typedef typename boost::remove_const<npT>::type ncpT;
  938. data = new ncpT;
  939. ptrAllocated(data, pid);
  940. *this >> *data;
  941. }
  942. else
  943. {
  944. loaders[tid]->loadPtr(*this,&data, pid);
  945. }
  946. }
  947. template <typename T>
  948. void ptrAllocated(const T *ptr, ui32 pid)
  949. {
  950. if(smartPointerSerialization && pid != 0xffffffff)
  951. loadedPointers[pid] = (void*)ptr; //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
  952. }
  953. #define READ_CHECK_U32(x) \
  954. ui32 length; \
  955. *this >> length; \
  956. if(length > 500000) \
  957. { \
  958. logGlobal->warnStream() << "Warning: very big length: " << length;\
  959. reportState(logGlobal); \
  960. };
  961. template <typename T>
  962. void loadSerializable(shared_ptr<T> &data)
  963. {
  964. T *internalPtr;
  965. *this >> internalPtr;
  966. if(internalPtr)
  967. {
  968. auto itr = loadedSharedPointers.find(internalPtr);
  969. if(itr != loadedSharedPointers.end())
  970. {
  971. // This pointers is already loaded. The "data" needs to be pointed to it,
  972. // so their shared state is actually shared.
  973. try
  974. {
  975. data = boost::any_cast<std::shared_ptr<T>>(itr->second);
  976. }
  977. catch(std::exception &e)
  978. {
  979. logGlobal->errorStream() << e.what();
  980. logGlobal->errorStream() << boost::format("Failed to cast stored shared ptr. Real type: %s. Needed type %s. FIXME FIXME FIXME")
  981. % itr->second.type().name() % typeid(std::shared_ptr<T>).name();
  982. //TODO scenario with inheritance -> we can have stored ptr to base and load ptr to derived (or vice versa)
  983. assert(0);
  984. }
  985. }
  986. else
  987. {
  988. data = std::shared_ptr<T>(internalPtr);
  989. loadedSharedPointers[internalPtr] = data;
  990. }
  991. }
  992. else
  993. data.reset();
  994. }
  995. template <typename T>
  996. void loadSerializable(unique_ptr<T> &data)
  997. {
  998. T *internalPtr;
  999. *this >> internalPtr;
  1000. data.reset(internalPtr);
  1001. }
  1002. template <typename T>
  1003. void loadSerializable(std::vector<T> &data)
  1004. {
  1005. READ_CHECK_U32(length);
  1006. data.resize(length);
  1007. for(ui32 i=0;i<length;i++)
  1008. *this >> data[i];
  1009. }
  1010. template <typename T, size_t N>
  1011. void loadSerializable(std::array<T, N> &data)
  1012. {
  1013. for(ui32 i = 0; i < N; i++)
  1014. *this >> data[i];
  1015. }
  1016. template <typename T>
  1017. void loadSerializable(std::set<T> &data)
  1018. {
  1019. READ_CHECK_U32(length);
  1020. data.clear();
  1021. T ins;
  1022. for(ui32 i=0;i<length;i++)
  1023. {
  1024. *this >> ins;
  1025. data.insert(ins);
  1026. }
  1027. }
  1028. template <typename T, typename U>
  1029. void loadSerializable(boost::unordered_set<T, U> &data)
  1030. {
  1031. READ_CHECK_U32(length);
  1032. data.clear();
  1033. T ins;
  1034. for(ui32 i=0;i<length;i++)
  1035. {
  1036. *this >> ins;
  1037. data.insert(ins);
  1038. }
  1039. }
  1040. template <typename T>
  1041. void loadSerializable(std::list<T> &data)
  1042. {
  1043. READ_CHECK_U32(length);
  1044. data.clear();
  1045. T ins;
  1046. for(ui32 i=0;i<length;i++)
  1047. {
  1048. *this >> ins;
  1049. data.push_back(ins);
  1050. }
  1051. }
  1052. template <typename T1, typename T2>
  1053. void loadSerializable(std::pair<T1,T2> &data)
  1054. {
  1055. *this >> data.first >> data.second;
  1056. }
  1057. template <typename T1, typename T2>
  1058. void loadSerializable(std::map<T1,T2> &data)
  1059. {
  1060. READ_CHECK_U32(length);
  1061. data.clear();
  1062. T1 t;
  1063. for(ui32 i=0;i<length;i++)
  1064. {
  1065. *this >> t;
  1066. *this >> data[t];
  1067. }
  1068. }
  1069. void loadSerializable(std::string &data)
  1070. {
  1071. READ_CHECK_U32(length);
  1072. data.resize(length);
  1073. this->This()->read((void*)data.c_str(),length);
  1074. }
  1075. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  1076. void loadSerializable(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  1077. {
  1078. si32 which;
  1079. *this >> which;
  1080. if(which == 0)
  1081. {
  1082. T0 obj;
  1083. *this >> obj;
  1084. data = obj;
  1085. }
  1086. else if(which == 1)
  1087. {
  1088. T1 obj;
  1089. *this >> obj;
  1090. data = obj;
  1091. }
  1092. else
  1093. assert(0);
  1094. //TODO write more if needed, general solution would be much longer
  1095. }
  1096. template <typename T>
  1097. void loadSerializable(boost::optional<T> & data)
  1098. {
  1099. ui8 present;
  1100. *this >> present;
  1101. if(present)
  1102. {
  1103. T t;
  1104. *this >> t;
  1105. data = t;
  1106. }
  1107. else
  1108. {
  1109. data = boost::optional<T>();
  1110. }
  1111. }
  1112. // void loadSerializable(CStackInstance *&s)
  1113. // {
  1114. // if(sendStackInstanceByIds)
  1115. // {
  1116. // CArmedInstance *armed;
  1117. // SlotID slot;
  1118. // *this >> armed >> slot;
  1119. // assert(armed->hasStackAtSlot(slot));
  1120. // s = armed->stacks[slot];
  1121. // }
  1122. // else
  1123. // loadSerializableBySerializeCall(s);
  1124. // }
  1125. template <typename E>
  1126. void loadEnum(E &data)
  1127. {
  1128. si32 read;
  1129. *this >> read;
  1130. data = static_cast<E>(read);
  1131. }
  1132. void loadBoolean(bool &data)
  1133. {
  1134. ui8 read;
  1135. *this >> read;
  1136. data = static_cast<bool>(read);
  1137. }
  1138. void loadBooleanVector(std::vector<bool> & data)
  1139. {
  1140. std::vector<ui8> convData;
  1141. loadSerializable(convData);
  1142. std::copy(convData.begin(), convData.end(), std::back_inserter(data));
  1143. }
  1144. };
  1145. class DLL_LINKAGE CSaveFile
  1146. : public COSer<CSaveFile>
  1147. {
  1148. void dummyMagicFunction()
  1149. {
  1150. *this << std::string("This function makes stuff working.");
  1151. }
  1152. public:
  1153. std::string fName;
  1154. unique_ptr<std::ofstream> sfile;
  1155. CSaveFile(const std::string &fname); //throws!
  1156. ~CSaveFile();
  1157. int write(const void * data, unsigned size);
  1158. void openNextFile(const std::string &fname); //throws!
  1159. void clear();
  1160. void reportState(CLogger * out);
  1161. void putMagicBytes(const std::string &text);
  1162. };
  1163. class DLL_LINKAGE CLoadFile
  1164. : public CISer<CLoadFile>
  1165. {
  1166. void dummyMagicFunction()
  1167. {
  1168. std::string dummy = "This function makes stuff working.";
  1169. *this >> dummy;
  1170. }
  1171. public:
  1172. std::string fName;
  1173. unique_ptr<std::ifstream> sfile;
  1174. CLoadFile(const std::string &fname, int minimalVersion = version); //throws!
  1175. ~CLoadFile();
  1176. int read(const void * data, unsigned size); //throws!
  1177. void openNextFile(const std::string &fname, int minimalVersion); //throws!
  1178. void clear();
  1179. void reportState(CLogger * out);
  1180. void checkMagicBytes(const std::string &text);
  1181. };
  1182. class DLL_LINKAGE CLoadIntegrityValidator : public CISer<CLoadIntegrityValidator>
  1183. {
  1184. public:
  1185. unique_ptr<CLoadFile> primaryFile, controlFile;
  1186. bool foundDesync;
  1187. CLoadIntegrityValidator(const std::string &primaryFileName, const std::string &controlFileName, int minimalVersion = version); //throws!
  1188. int read(const void * data, unsigned size); //throws!
  1189. void checkMagicBytes(const std::string &text);
  1190. unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
  1191. };
  1192. typedef boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > TSocket;
  1193. typedef boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > TAcceptor;
  1194. class DLL_LINKAGE CConnection
  1195. :public CISer<CConnection>, public COSer<CConnection>
  1196. {
  1197. //CGameState *gs;
  1198. CConnection(void);
  1199. void init();
  1200. void reportState(CLogger * out);
  1201. public:
  1202. boost::mutex *rmx, *wmx; // read/write mutexes
  1203. TSocket * socket;
  1204. bool logging;
  1205. bool connected;
  1206. bool myEndianess, contactEndianess; //true if little endian, if endianess is different we'll have to revert received multi-byte vars
  1207. boost::asio::io_service *io_service;
  1208. std::string name; //who uses this connection
  1209. int connectionID;
  1210. boost::thread *handler;
  1211. bool receivedStop, sendStop;
  1212. CConnection(std::string host, std::string port, std::string Name);
  1213. CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name);
  1214. CConnection(TSocket * Socket, std::string Name); //use immediately after accepting connection into socket
  1215. int write(const void * data, unsigned size);
  1216. int read(void * data, unsigned size);
  1217. void close();
  1218. bool isOpen() const;
  1219. template<class T>
  1220. CConnection &operator&(const T&);
  1221. virtual ~CConnection(void);
  1222. CPack *retreivePack(); //gets from server next pack (allocates it with new)
  1223. void sendPackToServer(const CPack &pack, PlayerColor player, ui32 requestID);
  1224. void disableStackSendingByID();
  1225. void enableStackSendingByID();
  1226. void disableSmartPointerSerialization();
  1227. void enableSmartPointerSerializatoin();
  1228. void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache
  1229. void enterPregameConnectionMode();
  1230. };
  1231. DLL_LINKAGE std::ostream &operator<<(std::ostream &str, const CConnection &cpc);
  1232. template<typename T>
  1233. class CApplier
  1234. {
  1235. public:
  1236. std::map<ui16,T*> apps;
  1237. ~CApplier()
  1238. {
  1239. typename std::map<ui16, T*>::iterator iter;
  1240. for(iter = apps.begin(); iter != apps.end(); iter++)
  1241. delete iter->second;
  1242. }
  1243. template<typename U> void registerType(const U * t=nullptr)
  1244. {
  1245. ui16 ID = typeList.registerType(t);
  1246. apps[ID] = T::getApplier(t);
  1247. }
  1248. };