Connection.h 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671
  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/mpl/eval_if.hpp>
  14. #include <boost/mpl/equal_to.hpp>
  15. #include <boost/mpl/int.hpp>
  16. #include <boost/mpl/identity.hpp>
  17. #include <boost/mpl/for_each.hpp>
  18. #include <boost/any.hpp>
  19. #include "ConstTransitivePtr.h"
  20. #include "CCreatureSet.h" //for CStackInstance
  21. #include "mapObjects/CGHeroInstance.h"
  22. #include "mapping/CCampaignHandler.h" //for CCampaignState
  23. #include "rmg/CMapGenerator.h" // for CMapGenOptions
  24. const ui32 version = 750;
  25. const ui32 minSupportedVersion = version;
  26. class CConnection;
  27. class CGObjectInstance;
  28. class CStackInstance;
  29. class CGameState;
  30. class CCreature;
  31. class LibClasses;
  32. class CHero;
  33. struct CPack;
  34. extern DLL_LINKAGE LibClasses * VLC;
  35. namespace mpl = boost::mpl;
  36. const std::string SAVEGAME_MAGIC = "VCMISVG";
  37. namespace boost
  38. {
  39. namespace asio
  40. {
  41. namespace ip
  42. {
  43. class tcp;
  44. }
  45. class io_service;
  46. template <typename Protocol> class stream_socket_service;
  47. template <typename Protocol,typename StreamSocketService>
  48. class basic_stream_socket;
  49. template <typename Protocol> class socket_acceptor_service;
  50. template <typename Protocol,typename SocketAcceptorService>
  51. class basic_socket_acceptor;
  52. }
  53. class mutex;
  54. }
  55. enum SerializationLvl
  56. {
  57. Wrong=0,
  58. Boolean,
  59. Primitive,
  60. Array,
  61. Pointer,
  62. Enum,
  63. Serializable,
  64. BooleanVector
  65. };
  66. struct TypeComparer
  67. {
  68. bool operator()(const std::type_info *a, const std::type_info *b) const
  69. {
  70. return a->before(*b);
  71. }
  72. };
  73. struct IPointerCaster
  74. {
  75. virtual boost::any castRawPtr(const boost::any &ptr) const = 0; // takes From*, performs dynamic cast, returns To*
  76. virtual boost::any castSharedPtr(const boost::any &ptr) const = 0; // takes std::shared_ptr<From>, performs dynamic cast, returns std::shared_ptr<To>
  77. virtual boost::any castWeakPtr(const boost::any &ptr) const = 0; // takes std::weak_ptr<From>, performs dynamic cast, returns std::weak_ptr<To>. The object under poitner must live.
  78. //virtual boost::any castUniquePtr(const boost::any &ptr) const = 0; // takes std::unique_ptr<From>, performs dynamic cast, returns std::unique_ptr<To>
  79. };
  80. template <typename From, typename To>
  81. struct PointerCaster : IPointerCaster
  82. {
  83. virtual boost::any castRawPtr(const boost::any &ptr) const override // takes void* pointing to From object, performs dynamic cast, returns void* pointing to To object
  84. {
  85. From * from = (From*)boost::any_cast<void*>(ptr);
  86. To * ret = dynamic_cast<To*>(from);
  87. return (void*)ret;
  88. }
  89. // Helper function performing casts between smart pointers using dynamic_pointer_cast
  90. template<typename SmartPt>
  91. boost::any castSmartPtr(const boost::any &ptr) const
  92. {
  93. try
  94. {
  95. auto from = boost::any_cast<SmartPt>(ptr);
  96. auto ret = std::dynamic_pointer_cast<To>(from);
  97. return ret;
  98. }
  99. catch(std::exception &e)
  100. {
  101. THROW_FORMAT("Failed cast %s -> %s. Given argument was %s. Error message: %s", typeid(From).name() % typeid(To).name() % ptr.type().name() % e.what());
  102. }
  103. }
  104. virtual boost::any castSharedPtr(const boost::any &ptr) const override
  105. {
  106. return castSmartPtr<std::shared_ptr<From>>(ptr);
  107. }
  108. virtual boost::any castWeakPtr(const boost::any &ptr) const override
  109. {
  110. auto from = boost::any_cast<std::weak_ptr<From>>(ptr);
  111. return castSmartPtr<std::shared_ptr<From>>(from.lock());
  112. }
  113. // virtual boost::any castUniquePtr(const boost::any &ptr) const override
  114. // {
  115. // return castSmartPtr<std::unique_ptr<From>>(ptr);
  116. // }
  117. };
  118. class DLL_LINKAGE CTypeList
  119. {
  120. public:
  121. struct TypeDescriptor;
  122. typedef std::shared_ptr<TypeDescriptor> TypeInfoPtr;
  123. struct TypeDescriptor
  124. {
  125. ui16 typeID;
  126. const char *name;
  127. std::vector<TypeInfoPtr> children, parents;
  128. };
  129. private:
  130. std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
  131. std::map<std::pair<TypeInfoPtr, TypeInfoPtr>, std::unique_ptr<const IPointerCaster>> casters; //for each pair <Base, Der> we provide a caster (each registered relations creates a single entry here)
  132. CTypeList(CTypeList &)
  133. {
  134. // This type is non-copyable.
  135. // Unfortunately on Windows it is required for DLL_EXPORT-ed type to provide copy c-tor, so we can't =delete it.
  136. assert(0);
  137. }
  138. CTypeList &operator=(CTypeList &)
  139. {
  140. // As above.
  141. assert(0);
  142. return *this;
  143. }
  144. public:
  145. CTypeList();
  146. TypeInfoPtr registerType(const std::type_info *type);
  147. template <typename Base, typename Derived>
  148. void registerType(const Base * b = nullptr, const Derived * d = nullptr)
  149. {
  150. static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
  151. static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
  152. static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two diffrenet types.");
  153. auto bt = getTypeInfo(b), dt = getTypeInfo(d); //obtain std::type_info
  154. auto bti = registerType(bt), dti = registerType(dt); //obtain our TypeDescriptor
  155. // register the relation between classes
  156. bti->children.push_back(dti);
  157. dti->parents.push_back(bti);
  158. casters[std::make_pair(bti, dti)] = make_unique<const PointerCaster<Base, Derived>>();
  159. casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
  160. }
  161. ui16 getTypeID(const std::type_info *type);
  162. TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true); //if not throws, failure returns nullptr
  163. template <typename T>
  164. ui16 getTypeID(const T * t = nullptr)
  165. {
  166. return getTypeID(getTypeInfo(t));
  167. }
  168. // Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
  169. // Throws if there is no link registered.
  170. std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to);
  171. std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to);
  172. template<boost::any(IPointerCaster::*CastingFunction)(const boost::any &) const>
  173. boost::any castHelper(boost::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg)
  174. {
  175. auto typesSequence = castSequence(fromArg, toArg);
  176. boost::any ptr = inputPtr;
  177. for(int i = 0; i < (int)typesSequence.size() - 1; i++)
  178. {
  179. auto &from = typesSequence[i];
  180. auto &to = typesSequence[i + 1];
  181. auto castingPair = std::make_pair(from, to);
  182. if(!casters.count(castingPair))
  183. THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
  184. auto &caster = casters.at(castingPair);
  185. ptr = (*caster.*CastingFunction)(ptr); //Why does unique_ptr does not have operator->* ..?
  186. }
  187. return ptr;
  188. }
  189. template<typename TInput>
  190. void *castToMostDerived(const TInput *inputPtr)
  191. {
  192. auto &baseType = typeid(typename std::remove_cv<TInput>::type);
  193. auto derivedType = getTypeInfo(inputPtr);
  194. if(baseType == *derivedType)
  195. return (void*)inputPtr;
  196. return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>((void*)inputPtr, &baseType, derivedType));
  197. }
  198. template<typename TInput>
  199. boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr)
  200. {
  201. auto &baseType = typeid(typename std::remove_cv<TInput>::type);
  202. auto derivedType = getTypeInfo(inputPtr.get());
  203. if(baseType == *derivedType)
  204. return inputPtr;
  205. return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
  206. }
  207. void* castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to)
  208. {
  209. return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
  210. }
  211. boost::any castShared(boost::any inputPtr, const std::type_info *from, const std::type_info *to)
  212. {
  213. return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
  214. }
  215. template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr)
  216. {
  217. if(t)
  218. return &typeid(*t);
  219. else
  220. return &typeid(T);
  221. }
  222. };
  223. extern DLL_LINKAGE CTypeList typeList;
  224. template<typename Ser>
  225. struct SaveBoolean
  226. {
  227. static void invoke(Ser &s, const bool &data)
  228. {
  229. s.saveBoolean(data);
  230. }
  231. };
  232. template<typename Ser>
  233. struct LoadBoolean
  234. {
  235. static void invoke(Ser &s, bool &data)
  236. {
  237. s.loadBoolean(data);
  238. }
  239. };
  240. template<typename Ser>
  241. struct SaveBooleanVector
  242. {
  243. static void invoke(Ser &s, const std::vector<bool> &data)
  244. {
  245. s.saveBooleanVector(data);
  246. }
  247. };
  248. template<typename Ser>
  249. struct LoadBooleanVector
  250. {
  251. static void invoke(Ser &s, std::vector<bool> &data)
  252. {
  253. s.loadBooleanVector(data);
  254. }
  255. };
  256. template<typename Ser,typename T>
  257. struct SavePrimitive
  258. {
  259. static void invoke(Ser &s, const T &data)
  260. {
  261. s.savePrimitive(data);
  262. }
  263. };
  264. template<typename Ser,typename T>
  265. struct SaveSerializable
  266. {
  267. static void invoke(Ser &s, const T &data)
  268. {
  269. s.saveSerializable(data);
  270. }
  271. };
  272. template<typename Ser,typename T>
  273. struct SaveEnum
  274. {
  275. static void invoke(Ser &s, const T &data)
  276. {
  277. s.saveEnum(data);
  278. }
  279. };
  280. template<typename Ser,typename T>
  281. struct LoadEnum
  282. {
  283. static void invoke(Ser &s, T &data)
  284. {
  285. s.loadEnum(data);
  286. }
  287. };
  288. template<typename Ser,typename T>
  289. struct LoadPrimitive
  290. {
  291. static void invoke(Ser &s, T &data)
  292. {
  293. s.loadPrimitive(data);
  294. }
  295. };
  296. template<typename Ser,typename T>
  297. struct SavePointer
  298. {
  299. static void invoke(Ser &s, const T &data)
  300. {
  301. s.savePointer(data);
  302. }
  303. };
  304. template<typename Ser,typename T>
  305. struct LoadPointer
  306. {
  307. static void invoke(Ser &s, T &data)
  308. {
  309. s.loadPointer(data);
  310. }
  311. };
  312. template<typename Ser,typename T>
  313. struct SaveArray
  314. {
  315. static void invoke(Ser &s, const T &data)
  316. {
  317. s.saveArray(data);
  318. }
  319. };
  320. template<typename Ser,typename T>
  321. struct LoadArray
  322. {
  323. static void invoke(Ser &s, T &data)
  324. {
  325. s.loadArray(data);
  326. }
  327. };
  328. template<typename Ser,typename T>
  329. struct LoadSerializable
  330. {
  331. static void invoke(Ser &s, T &data)
  332. {
  333. s.loadSerializable(data);
  334. }
  335. };
  336. template<typename Ser,typename T>
  337. struct SaveWrong
  338. {
  339. static void invoke(Ser &s, const T &data)
  340. {
  341. throw std::runtime_error("Wrong save serialization call!");
  342. }
  343. };
  344. template<typename Ser,typename T>
  345. struct LoadWrong
  346. {
  347. static void invoke(Ser &s, const T &data)
  348. {
  349. throw std::runtime_error("Wrong load serialization call!");
  350. }
  351. };
  352. template<typename Variant, typename Source>
  353. struct VariantLoaderHelper
  354. {
  355. Source & source;
  356. std::vector<std::function<Variant()>> funcs;
  357. VariantLoaderHelper(Source & source):
  358. source(source)
  359. {
  360. mpl::for_each<typename Variant::types>(std::ref(*this));
  361. }
  362. template<typename Type>
  363. void operator()(Type)
  364. {
  365. funcs.push_back([&]() -> Variant
  366. {
  367. Type obj;
  368. source >> obj;
  369. return Variant(obj);
  370. });
  371. }
  372. };
  373. template<typename T>
  374. struct SerializationLevel
  375. {
  376. typedef mpl::integral_c_tag tag;
  377. typedef
  378. typename mpl::eval_if<
  379. boost::is_same<T, bool>,
  380. mpl::int_<Boolean>,
  381. //else
  382. typename mpl::eval_if<
  383. boost::is_same<T, std::vector<bool> >,
  384. mpl::int_<BooleanVector>,
  385. //else
  386. typename mpl::eval_if<
  387. boost::is_fundamental<T>,
  388. mpl::int_<Primitive>,
  389. //else
  390. typename mpl::eval_if<
  391. boost::is_enum<T>,
  392. mpl::int_<Enum>,
  393. //else
  394. typename mpl::eval_if<
  395. boost::is_class<T>,
  396. mpl::int_<Serializable>,
  397. //else
  398. typename mpl::eval_if<
  399. boost::is_array<T>,
  400. mpl::int_<Array>,
  401. //else
  402. typename mpl::eval_if<
  403. boost::is_pointer<T>,
  404. mpl::int_<Pointer>,
  405. //else
  406. typename mpl::eval_if<
  407. boost::is_enum<T>,
  408. mpl::int_<Primitive>,
  409. //else
  410. mpl::int_<Wrong>
  411. >
  412. >
  413. >
  414. >
  415. >
  416. >
  417. >
  418. >::type type;
  419. static const int value = SerializationLevel::type::value;
  420. };
  421. template <typename ObjType, typename IdType>
  422. struct VectorisedObjectInfo
  423. {
  424. const std::vector<ConstTransitivePtr<ObjType> > *vector; //pointer to the appropriate vector
  425. std::function<IdType(const ObjType &)> idRetriever;
  426. //const IdType ObjType::*idPtr; //pointer to the field representing the position in the vector
  427. VectorisedObjectInfo(const std::vector< ConstTransitivePtr<ObjType> > *Vector, std::function<IdType(const ObjType &)> IdGetter)
  428. :vector(Vector), idRetriever(IdGetter)
  429. {
  430. }
  431. };
  432. template<typename T>
  433. si32 idToNumber(const T &t, typename boost::enable_if<boost::is_convertible<T,si32> >::type * dummy = 0)
  434. {
  435. return t;
  436. }
  437. template<typename T, typename NT>
  438. NT idToNumber(const BaseForID<T, NT> &t)
  439. {
  440. return t.getNum();
  441. }
  442. /// Class which is responsible for storing and loading data.
  443. class DLL_LINKAGE CSerializer
  444. {
  445. public:
  446. typedef std::map<const std::type_info *, boost::any, TypeComparer> TTypeVecMap;
  447. TTypeVecMap vectors; //entry must be a pointer to vector containing pointers to the objects of key type
  448. bool smartVectorMembersSerialization;
  449. bool sendStackInstanceByIds;
  450. CSerializer();
  451. ~CSerializer();
  452. virtual void reportState(CLogger * out){};
  453. template <typename T, typename U>
  454. void registerVectoredType(const std::vector<T*> *Vector, const std::function<U(const T&)> &idRetriever)
  455. {
  456. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, idRetriever);
  457. }
  458. template <typename T, typename U>
  459. void registerVectoredType(const std::vector<ConstTransitivePtr<T> > *Vector, const std::function<U(const T&)> &idRetriever)
  460. {
  461. vectors[&typeid(T)] = VectorisedObjectInfo<T, U>(Vector, idRetriever);
  462. }
  463. template <typename T, typename U>
  464. const VectorisedObjectInfo<T, U> *getVectorisedTypeInfo()
  465. {
  466. const std::type_info *myType = nullptr;
  467. //
  468. // 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..
  469. // myType = &typeid(CGObjectInstance);
  470. // else
  471. myType = &typeid(T);
  472. TTypeVecMap::iterator i = vectors.find(myType);
  473. if(i == vectors.end())
  474. return nullptr;
  475. else
  476. {
  477. assert(!i->second.empty());
  478. assert(i->second.type() == typeid(VectorisedObjectInfo<T, U>));
  479. VectorisedObjectInfo<T, U> *ret = &(boost::any_cast<VectorisedObjectInfo<T, U>&>(i->second));
  480. return ret;
  481. }
  482. }
  483. template <typename T, typename U>
  484. T* getVectorItemFromId(const VectorisedObjectInfo<T, U> &oInfo, U id) const
  485. {
  486. /* if(id < 0)
  487. return nullptr;*/
  488. si32 idAsNumber = idToNumber(id);
  489. assert(oInfo.vector);
  490. assert(static_cast<si32>(oInfo.vector->size()) > idAsNumber);
  491. return const_cast<T*>((*oInfo.vector)[idAsNumber].get());
  492. }
  493. template <typename T, typename U>
  494. U getIdFromVectorItem(const VectorisedObjectInfo<T, U> &oInfo, const T* obj) const
  495. {
  496. if(!obj)
  497. return U(-1);
  498. return oInfo.idRetriever(*obj);
  499. }
  500. void addStdVecItems(CGameState *gs, LibClasses *lib = VLC);
  501. };
  502. class DLL_LINKAGE CSaverBase : public virtual CSerializer
  503. {
  504. };
  505. class CBasicPointerSaver
  506. {
  507. public:
  508. virtual void savePtr(CSaverBase &ar, const void *data) const =0;
  509. virtual ~CBasicPointerSaver(){}
  510. };
  511. template <typename Serializer, typename T> class CPointerSaver : public CBasicPointerSaver
  512. {
  513. public:
  514. void savePtr(CSaverBase &ar, const void *data) const
  515. {
  516. Serializer &s = static_cast<Serializer&>(ar);
  517. const T *ptr = static_cast<const T*>(data);
  518. //T is most derived known type, it's time to call actual serialize
  519. const_cast<T&>(*ptr).serialize(s,version);
  520. }
  521. };
  522. template <typename T> //metafunction returning CGObjectInstance if T is its derivate or T elsewise
  523. struct VectorisedTypeFor
  524. {
  525. typedef typename
  526. //if
  527. mpl::eval_if<boost::is_same<CGHeroInstance,T>,
  528. mpl::identity<CGHeroInstance>,
  529. //else if
  530. mpl::eval_if<boost::is_base_of<CGObjectInstance,T>,
  531. mpl::identity<CGObjectInstance>,
  532. //else
  533. mpl::identity<T>
  534. > >::type type;
  535. };
  536. template <typename U>
  537. struct VectorizedIDType
  538. {
  539. typedef typename
  540. //if
  541. mpl::eval_if<boost::is_same<CArtifact,U>,
  542. mpl::identity<ArtifactID>,
  543. //else if
  544. mpl::eval_if<boost::is_same<CCreature,U>,
  545. mpl::identity<CreatureID>,
  546. //else if
  547. mpl::eval_if<boost::is_same<CHero,U>,
  548. mpl::identity<HeroTypeID>,
  549. //else if
  550. mpl::eval_if<boost::is_same<CArtifactInstance,U>,
  551. mpl::identity<ArtifactInstanceID>,
  552. //else if
  553. mpl::eval_if<boost::is_same<CGHeroInstance,U>,
  554. mpl::identity<HeroTypeID>,
  555. //else if
  556. mpl::eval_if<boost::is_base_of<CGObjectInstance,U>,
  557. mpl::identity<ObjectInstanceID>,
  558. //else
  559. mpl::identity<si32>
  560. > > > > > >::type type;
  561. };
  562. template <typename Handler>
  563. struct VariantVisitorSaver : boost::static_visitor<>
  564. {
  565. Handler &h;
  566. VariantVisitorSaver(Handler &H):h(H)
  567. {
  568. }
  569. template <typename T>
  570. void operator()(const T &t)
  571. {
  572. h << t;
  573. }
  574. };
  575. template<typename Ser,typename T>
  576. struct SaveIfStackInstance
  577. {
  578. static bool invoke(Ser &s, const T &data)
  579. {
  580. return false;
  581. }
  582. };
  583. template<typename Ser>
  584. struct SaveIfStackInstance<Ser, CStackInstance *>
  585. {
  586. static bool invoke(Ser &s, const CStackInstance* const &data)
  587. {
  588. assert(data->armyObj);
  589. SlotID slot;
  590. if(data->getNodeType() == CBonusSystemNode::COMMANDER)
  591. slot = SlotID::COMMANDER_SLOT_PLACEHOLDER;
  592. else
  593. slot = data->armyObj->findStack(data);
  594. assert(slot != SlotID());
  595. s << data->armyObj << slot;
  596. return true;
  597. }
  598. };
  599. template<typename Ser,typename T>
  600. struct LoadIfStackInstance
  601. {
  602. static bool invoke(Ser &s, T &data)
  603. {
  604. return false;
  605. }
  606. };
  607. template<typename Ser>
  608. struct LoadIfStackInstance<Ser, CStackInstance *>
  609. {
  610. static bool invoke(Ser &s, CStackInstance* &data)
  611. {
  612. CArmedInstance *armedObj;
  613. SlotID slot;
  614. s >> armedObj >> slot;
  615. if(slot != SlotID::COMMANDER_SLOT_PLACEHOLDER)
  616. {
  617. assert(armedObj->hasStackAtSlot(slot));
  618. data = armedObj->stacks[slot];
  619. }
  620. else
  621. {
  622. auto hero = dynamic_cast<CGHeroInstance *>(armedObj);
  623. assert(hero);
  624. assert(hero->commander);
  625. data = hero->commander;
  626. }
  627. return true;
  628. }
  629. };
  630. /// The class which manages saving objects.
  631. template <typename Serializer> class DLL_LINKAGE COSer : public CSaverBase
  632. {
  633. public:
  634. bool saving;
  635. std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type>
  636. std::map<const void*, ui32> savedPointers;
  637. bool smartPointerSerialization;
  638. COSer()
  639. {
  640. saving=true;
  641. smartPointerSerialization = true;
  642. }
  643. ~COSer()
  644. {
  645. std::map<ui16,CBasicPointerSaver*>::iterator iter;
  646. for(iter = savers.begin(); iter != savers.end(); iter++)
  647. delete iter->second;
  648. }
  649. template<typename T>
  650. void addSaver(const T * t = nullptr)
  651. {
  652. auto ID = typeList.getTypeID(t);
  653. if(!savers.count(ID))
  654. savers[ID] = new CPointerSaver<COSer<Serializer>, T>;
  655. }
  656. template<typename Base, typename Derived> void registerType(const Base * b = nullptr, const Derived * d = nullptr)
  657. {
  658. typeList.registerType(b, d);
  659. addSaver(b);
  660. addSaver(d);
  661. }
  662. Serializer * This()
  663. {
  664. return static_cast<Serializer*>(this);
  665. }
  666. template<class T>
  667. Serializer & operator<<(const T &t)
  668. {
  669. this->This()->save(t);
  670. return * this->This();
  671. }
  672. template<class T>
  673. COSer & operator&(const T & t)
  674. {
  675. return * this->This() << t;
  676. }
  677. int write(const void * data, unsigned size);
  678. template <typename T>
  679. void savePrimitive(const T &data)
  680. {
  681. this->This()->write(&data,sizeof(data));
  682. }
  683. template <typename T>
  684. void savePointer(const T &data)
  685. {
  686. //write if pointer is not nullptr
  687. ui8 hlp = (data!=nullptr);
  688. *this << hlp;
  689. //if pointer is nullptr then we don't need anything more...
  690. if(!hlp)
  691. return;
  692. if(smartVectorMembersSerialization)
  693. {
  694. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType;
  695. typedef typename VectorisedTypeFor<TObjectType>::type VType;
  696. typedef typename VectorizedIDType<TObjectType>::type IDType;
  697. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  698. {
  699. IDType id = getIdFromVectorItem<VType>(*info, data);
  700. *this << id;
  701. if(id != IDType(-1)) //vector id is enough
  702. return;
  703. }
  704. }
  705. if(sendStackInstanceByIds)
  706. {
  707. const bool gotSaved = SaveIfStackInstance<Serializer,T>::invoke(*This(), data);
  708. if(gotSaved)
  709. return;
  710. }
  711. if(smartPointerSerialization)
  712. {
  713. // We might have an object that has multiple inheritance and store it via the non-first base pointer.
  714. // Therefore, all pointers need to be normalized to the actual object address.
  715. auto actualPointer = typeList.castToMostDerived(data);
  716. std::map<const void*,ui32>::iterator i = savedPointers.find(actualPointer);
  717. if(i != savedPointers.end())
  718. {
  719. //this pointer has been already serialized - write only it's id
  720. *this << i->second;
  721. return;
  722. }
  723. //give id to this pointer
  724. ui32 pid = (ui32)savedPointers.size();
  725. savedPointers[actualPointer] = pid;
  726. *this << pid;
  727. }
  728. //write type identifier
  729. ui16 tid = typeList.getTypeID(data);
  730. *this << tid;
  731. This()->savePointerHlp(tid, data);
  732. }
  733. //that part of ptr serialization was extracted to allow customization of its behavior in derived classes
  734. template <typename T>
  735. void savePointerHlp(ui16 tid, const T &data)
  736. {
  737. if(!tid)
  738. *this << *data; //if type is unregistered simply write all data in a standard way
  739. else
  740. savers[tid]->savePtr(*this, typeList.castToMostDerived(data)); //call serializer specific for our real type
  741. }
  742. template <typename T>
  743. void saveArray(const T &data)
  744. {
  745. ui32 size = ARRAY_COUNT(data);
  746. for(ui32 i=0; i < size; i++)
  747. *this << data[i];
  748. }
  749. template <typename T>
  750. void save(const T &data)
  751. {
  752. typedef
  753. //if
  754. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  755. mpl::identity<SaveBoolean<Serializer> >,
  756. //else if
  757. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  758. mpl::identity<SaveBooleanVector<Serializer> >,
  759. //else if
  760. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  761. mpl::identity<SavePrimitive<Serializer,T> >,
  762. //else if
  763. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  764. mpl::identity<SaveEnum<Serializer,T> >,
  765. //else if
  766. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  767. mpl::identity<SavePointer<Serializer,T> >,
  768. //else if
  769. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  770. mpl::identity<SaveArray<Serializer,T> >,
  771. //else if
  772. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  773. mpl::identity<SaveSerializable<Serializer,T> >,
  774. //else
  775. mpl::identity<SaveWrong<Serializer,T> >
  776. >
  777. >
  778. >
  779. >
  780. >
  781. >
  782. >::type typex;
  783. typex::invoke(* this->This(), data);
  784. }
  785. template <typename T>
  786. void saveSerializable(const T &data)
  787. {
  788. const_cast<T&>(data).serialize(*this,version);
  789. }
  790. template <typename T>
  791. void saveSerializable(const shared_ptr<T> &data)
  792. {
  793. T *internalPtr = data.get();
  794. *this << internalPtr;
  795. }
  796. template <typename T>
  797. void saveSerializable(const unique_ptr<T> &data)
  798. {
  799. T *internalPtr = data.get();
  800. *this << internalPtr;
  801. }
  802. template <typename T>
  803. void saveSerializable(const std::vector<T> &data)
  804. {
  805. ui32 length = data.size();
  806. *this << length;
  807. for(ui32 i=0;i<length;i++)
  808. *this << data[i];
  809. }
  810. template <typename T, size_t N>
  811. void saveSerializable(const std::array<T, N> &data)
  812. {
  813. for(ui32 i=0; i < N; i++)
  814. *this << data[i];
  815. }
  816. template <typename T>
  817. void saveSerializable(const std::set<T> &data)
  818. {
  819. std::set<T> &d = const_cast<std::set<T> &>(data);
  820. ui32 length = d.size();
  821. *this << length;
  822. for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
  823. *this << *i;
  824. }
  825. template <typename T, typename U>
  826. void saveSerializable(const std::unordered_set<T, U> &data)
  827. {
  828. std::unordered_set<T, U> &d = const_cast<std::unordered_set<T, U> &>(data);
  829. ui32 length = d.size();
  830. *this << length;
  831. for(typename std::unordered_set<T, U>::iterator i=d.begin();i!=d.end();i++)
  832. *this << *i;
  833. }
  834. template <typename T>
  835. void saveSerializable(const std::list<T> &data)
  836. {
  837. std::list<T> &d = const_cast<std::list<T> &>(data);
  838. ui32 length = d.size();
  839. *this << length;
  840. for(typename std::list<T>::iterator i=d.begin();i!=d.end();i++)
  841. *this << *i;
  842. }
  843. void saveSerializable(const std::string &data)
  844. {
  845. *this << ui32(data.length());
  846. this->This()->write(data.c_str(),data.size());
  847. }
  848. template <typename T1, typename T2>
  849. void saveSerializable(const std::pair<T1,T2> &data)
  850. {
  851. *this << data.first << data.second;
  852. }
  853. template <typename T1, typename T2>
  854. void saveSerializable(const std::map<T1,T2> &data)
  855. {
  856. *this << ui32(data.size());
  857. for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
  858. *this << i->first << i->second;
  859. }
  860. template <typename T1, typename T2>
  861. void saveSerializable(const std::multimap<T1, T2> &data)
  862. {
  863. *this << ui32(data.size());
  864. for(typename std::map<T1, T2>::const_iterator i = data.begin(); i != data.end(); i++)
  865. *this << i->first << i->second;
  866. }
  867. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  868. void saveSerializable(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  869. {
  870. si32 which = data.which();
  871. *this << which;
  872. VariantVisitorSaver<Serializer> visitor(*this->This());
  873. boost::apply_visitor(visitor, data);
  874. }
  875. template <typename T>
  876. void saveSerializable(const boost::optional<T> &data)
  877. {
  878. if(data)
  879. {
  880. *this << (ui8)1;
  881. *this << *data;
  882. }
  883. else
  884. {
  885. *this << (ui8)0;
  886. }
  887. }
  888. template <typename E>
  889. void saveEnum(const E &data)
  890. {
  891. si32 writ = static_cast<si32>(data);
  892. *this << writ;
  893. }
  894. void saveBoolean(const bool & data)
  895. {
  896. ui8 writ = static_cast<ui8>(data);
  897. *this << writ;
  898. }
  899. void saveBooleanVector(const std::vector<bool> & data)
  900. {
  901. std::vector<ui8> convData;
  902. std::copy(data.begin(), data.end(), std::back_inserter(convData));
  903. saveSerializable(convData);
  904. }
  905. };
  906. class DLL_LINKAGE CLoaderBase : public virtual CSerializer
  907. {};
  908. class CBasicPointerLoader
  909. {
  910. public:
  911. virtual const std::type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
  912. virtual ~CBasicPointerLoader(){}
  913. };
  914. template <typename T, typename Enable = void>
  915. struct ClassObjectCreator
  916. {
  917. static T *invoke()
  918. {
  919. static_assert(!std::is_abstract<T>::value, "Cannot call new upon abstract classes!");
  920. return new T();
  921. }
  922. };
  923. template<typename T>
  924. struct ClassObjectCreator<T, typename std::enable_if<std::is_abstract<T>::value>::type>
  925. {
  926. static T *invoke()
  927. {
  928. throw std::runtime_error("Something went really wrong during deserialization. Attempted creating an object of an abstract class " + std::string(typeid(T).name()));
  929. }
  930. };
  931. template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
  932. {
  933. public:
  934. const std::type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const //data is pointer to the ACTUAL POINTER
  935. {
  936. Serializer &s = static_cast<Serializer&>(ar);
  937. T *&ptr = *static_cast<T**>(data);
  938. //create new object under pointer
  939. typedef typename boost::remove_pointer<T>::type npT;
  940. ptr = ClassObjectCreator<npT>::invoke(); //does new npT or throws for abstract classes
  941. s.ptrAllocated(ptr, pid);
  942. //T is most derived known type, it's time to call actual serialize
  943. ptr->serialize(s,version);
  944. return &typeid(T);
  945. }
  946. };
  947. /// The class which manages loading of objects.
  948. template <typename Serializer> class DLL_LINKAGE CISer : public CLoaderBase
  949. {
  950. public:
  951. bool saving;
  952. std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
  953. si32 fileVersion;
  954. bool reverseEndianess; //if source has different endianness than us, we reverse bytes
  955. std::map<ui32, void*> loadedPointers;
  956. std::map<ui32, const std::type_info*> loadedPointersTypes;
  957. std::map<const void*, boost::any> loadedSharedPointers;
  958. bool smartPointerSerialization;
  959. CISer()
  960. {
  961. saving = false;
  962. fileVersion = 0;
  963. smartPointerSerialization = true;
  964. reverseEndianess = false;
  965. }
  966. ~CISer()
  967. {
  968. std::map<ui16,CBasicPointerLoader*>::iterator iter;
  969. for(iter = loaders.begin(); iter != loaders.end(); iter++)
  970. delete iter->second;
  971. }
  972. template<typename T>
  973. void addLoader(const T * t = nullptr)
  974. {
  975. auto ID = typeList.getTypeID(t);
  976. if(!loaders.count(ID))
  977. loaders[ID] = new CPointerLoader<CISer<Serializer>, T>;
  978. }
  979. template<typename Base, typename Derived> void registerType(const Base * b = nullptr, const Derived * d = nullptr)
  980. {
  981. typeList.registerType(b, d);
  982. addLoader(b);
  983. addLoader(d);
  984. }
  985. Serializer * This()
  986. {
  987. return static_cast<Serializer*>(this);
  988. }
  989. template<class T>
  990. Serializer & operator>>(T &t)
  991. {
  992. this->This()->load(t);
  993. return * this->This();
  994. }
  995. template<class T>
  996. CISer & operator&(T & t)
  997. {
  998. return * this->This() >> t;
  999. }
  1000. int write(const void * data, unsigned size);
  1001. template <typename T>
  1002. void load(T &data)
  1003. {
  1004. typedef
  1005. //if
  1006. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Boolean> >,
  1007. mpl::identity<LoadBoolean<Serializer> >,
  1008. //else if
  1009. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<BooleanVector> >,
  1010. mpl::identity<LoadBooleanVector<Serializer> >,
  1011. //else if
  1012. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  1013. mpl::identity<LoadPrimitive<Serializer,T> >,
  1014. //else if
  1015. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Enum> >,
  1016. mpl::identity<LoadEnum<Serializer,T> >,
  1017. //else if
  1018. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  1019. mpl::identity<LoadPointer<Serializer,T> >,
  1020. //else if
  1021. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  1022. mpl::identity<LoadArray<Serializer,T> >,
  1023. //else if
  1024. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  1025. mpl::identity<LoadSerializable<Serializer,T> >,
  1026. //else
  1027. mpl::identity<LoadWrong<Serializer,T> >
  1028. >
  1029. >
  1030. >
  1031. >
  1032. >
  1033. >
  1034. >::type typex;
  1035. typex::invoke(* this->This(), data);
  1036. }
  1037. template <typename T>
  1038. void loadPrimitive(T &data)
  1039. {
  1040. if(0) //for testing #989
  1041. {
  1042. this->This()->read(&data,sizeof(data));
  1043. }
  1044. else
  1045. {
  1046. unsigned length = sizeof(data);
  1047. char* dataPtr = (char*)&data;
  1048. this->This()->read(dataPtr,length);
  1049. if(reverseEndianess)
  1050. std::reverse(dataPtr, dataPtr + length);
  1051. }
  1052. }
  1053. template <typename T>
  1054. void loadSerializableBySerializeCall(T &data)
  1055. {
  1056. ////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
  1057. typedef typename boost::remove_const<T>::type nonConstT;
  1058. nonConstT &hlp = const_cast<nonConstT&>(data);
  1059. hlp.serialize(*this,fileVersion);
  1060. //data.serialize(*this,myVersion);
  1061. }
  1062. template <typename T>
  1063. void loadSerializable(T &data)
  1064. {
  1065. loadSerializableBySerializeCall(data);
  1066. }
  1067. template <typename T>
  1068. void loadArray(T &data)
  1069. {
  1070. ui32 size = ARRAY_COUNT(data);
  1071. for(ui32 i = 0; i < size; i++)
  1072. *this >> data[i];
  1073. }
  1074. template <typename T>
  1075. void loadPointer(T &data)
  1076. {
  1077. ui8 hlp;
  1078. *this >> hlp;
  1079. if(!hlp)
  1080. {
  1081. data = nullptr;
  1082. return;
  1083. }
  1084. if(smartVectorMembersSerialization)
  1085. {
  1086. typedef typename boost::remove_const<typename boost::remove_pointer<T>::type>::type TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
  1087. typedef typename VectorisedTypeFor<TObjectType>::type VType; //eg: CGHeroInstance -> CGobjectInstance
  1088. typedef typename VectorizedIDType<TObjectType>::type IDType;
  1089. if(const auto *info = getVectorisedTypeInfo<VType, IDType>())
  1090. {
  1091. IDType id;
  1092. *this >> id;
  1093. if(id != IDType(-1))
  1094. {
  1095. data = static_cast<T>(getVectorItemFromId<VType, IDType>(*info, id));
  1096. return;
  1097. }
  1098. }
  1099. }
  1100. if(sendStackInstanceByIds)
  1101. {
  1102. bool gotLoaded = LoadIfStackInstance<Serializer,T>::invoke(*This(), data);
  1103. if(gotLoaded)
  1104. return;
  1105. }
  1106. ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id)
  1107. if(smartPointerSerialization)
  1108. {
  1109. *this >> pid; //get the id
  1110. std::map<ui32, void*>::iterator i = loadedPointers.find(pid); //lookup
  1111. if(i != loadedPointers.end())
  1112. {
  1113. // We already got this pointer
  1114. // Cast it in case we are loading it to a non-first base pointer
  1115. assert(loadedPointersTypes.count(pid));
  1116. data = reinterpret_cast<T>(typeList.castRaw(i->second, loadedPointersTypes.at(pid), &typeid(typename boost::remove_const<typename boost::remove_pointer<T>::type>::type)));
  1117. return;
  1118. }
  1119. }
  1120. //get type id
  1121. ui16 tid;
  1122. *this >> tid;
  1123. This()->loadPointerHlp(tid, data, pid);
  1124. }
  1125. //that part of ptr deserialization was extracted to allow customization of its behavior in derived classes
  1126. template <typename T>
  1127. void loadPointerHlp( ui16 tid, T & data, ui32 pid )
  1128. {
  1129. if(!tid)
  1130. {
  1131. typedef typename boost::remove_pointer<T>::type npT;
  1132. typedef typename boost::remove_const<npT>::type ncpT;
  1133. data = ClassObjectCreator<ncpT>::invoke();
  1134. ptrAllocated(data, pid);
  1135. *this >> *data;
  1136. }
  1137. else
  1138. {
  1139. auto typeInfo = loaders[tid]->loadPtr(*this,&data, pid);
  1140. data = reinterpret_cast<T>(typeList.castRaw((void*)data, typeInfo, &typeid(typename boost::remove_const<typename boost::remove_pointer<T>::type>::type)));
  1141. }
  1142. }
  1143. template <typename T>
  1144. void ptrAllocated(const T *ptr, ui32 pid)
  1145. {
  1146. if(smartPointerSerialization && pid != 0xffffffff)
  1147. {
  1148. loadedPointersTypes[pid] = &typeid(T);
  1149. loadedPointers[pid] = (void*)ptr; //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
  1150. }
  1151. }
  1152. #define READ_CHECK_U32(x) \
  1153. ui32 length; \
  1154. *this >> length; \
  1155. if(length > 500000) \
  1156. { \
  1157. logGlobal->warnStream() << "Warning: very big length: " << length;\
  1158. reportState(logGlobal); \
  1159. };
  1160. template <typename T>
  1161. void loadSerializable(shared_ptr<T> &data)
  1162. {
  1163. typedef typename boost::remove_const<T>::type NonConstT;
  1164. NonConstT *internalPtr;
  1165. *this >> internalPtr;
  1166. void *internalPtrDerived = typeList.castToMostDerived(internalPtr);
  1167. if(internalPtr)
  1168. {
  1169. auto itr = loadedSharedPointers.find(internalPtrDerived);
  1170. if(itr != loadedSharedPointers.end())
  1171. {
  1172. // This pointers is already loaded. The "data" needs to be pointed to it,
  1173. // so their shared state is actually shared.
  1174. try
  1175. {
  1176. auto actualType = typeList.getTypeInfo(internalPtr);
  1177. auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
  1178. if(*actualType == *typeWeNeedToReturn)
  1179. {
  1180. // No casting needed, just unpack already stored shared_ptr and return it
  1181. data = boost::any_cast<std::shared_ptr<T>>(itr->second);
  1182. }
  1183. else
  1184. {
  1185. // We need to perform series of casts
  1186. auto ret = typeList.castShared(itr->second, actualType, typeWeNeedToReturn);
  1187. data = boost::any_cast<std::shared_ptr<T>>(ret);
  1188. }
  1189. }
  1190. catch(std::exception &e)
  1191. {
  1192. logGlobal->errorStream() << e.what();
  1193. logGlobal->errorStream() << boost::format("Failed to cast stored shared ptr. Real type: %s. Needed type %s. FIXME FIXME FIXME")
  1194. % itr->second.type().name() % typeid(std::shared_ptr<T>).name();
  1195. //TODO scenario with inheritance -> we can have stored ptr to base and load ptr to derived (or vice versa)
  1196. assert(0);
  1197. }
  1198. }
  1199. else
  1200. {
  1201. auto hlp = std::shared_ptr<NonConstT>(internalPtr);
  1202. data = hlp; //possibly adds const
  1203. loadedSharedPointers[internalPtrDerived] = typeList.castSharedToMostDerived(hlp);
  1204. }
  1205. }
  1206. else
  1207. data.reset();
  1208. }
  1209. template <typename T>
  1210. void loadSerializable(unique_ptr<T> &data)
  1211. {
  1212. T *internalPtr;
  1213. *this >> internalPtr;
  1214. data.reset(internalPtr);
  1215. }
  1216. template <typename T>
  1217. void loadSerializable(std::vector<T> &data)
  1218. {
  1219. READ_CHECK_U32(length);
  1220. data.resize(length);
  1221. for(ui32 i=0;i<length;i++)
  1222. *this >> data[i];
  1223. }
  1224. template <typename T, size_t N>
  1225. void loadSerializable(std::array<T, N> &data)
  1226. {
  1227. for(ui32 i = 0; i < N; i++)
  1228. *this >> data[i];
  1229. }
  1230. template <typename T>
  1231. void loadSerializable(std::set<T> &data)
  1232. {
  1233. READ_CHECK_U32(length);
  1234. data.clear();
  1235. T ins;
  1236. for(ui32 i=0;i<length;i++)
  1237. {
  1238. *this >> ins;
  1239. data.insert(ins);
  1240. }
  1241. }
  1242. template <typename T, typename U>
  1243. void loadSerializable(std::unordered_set<T, U> &data)
  1244. {
  1245. READ_CHECK_U32(length);
  1246. data.clear();
  1247. T ins;
  1248. for(ui32 i=0;i<length;i++)
  1249. {
  1250. *this >> ins;
  1251. data.insert(ins);
  1252. }
  1253. }
  1254. template <typename T>
  1255. void loadSerializable(std::list<T> &data)
  1256. {
  1257. READ_CHECK_U32(length);
  1258. data.clear();
  1259. T ins;
  1260. for(ui32 i=0;i<length;i++)
  1261. {
  1262. *this >> ins;
  1263. data.push_back(ins);
  1264. }
  1265. }
  1266. template <typename T1, typename T2>
  1267. void loadSerializable(std::pair<T1,T2> &data)
  1268. {
  1269. *this >> data.first >> data.second;
  1270. }
  1271. template <typename T1, typename T2>
  1272. void loadSerializable(std::map<T1,T2> &data)
  1273. {
  1274. READ_CHECK_U32(length);
  1275. data.clear();
  1276. T1 t;
  1277. for(ui32 i=0;i<length;i++)
  1278. {
  1279. *this >> t;
  1280. *this >> data[t];
  1281. }
  1282. }
  1283. template <typename T1, typename T2>
  1284. void loadSerializable(std::multimap<T1, T2> &data)
  1285. {
  1286. READ_CHECK_U32(length);
  1287. data.clear();
  1288. T1 key;
  1289. T2 value;
  1290. for(ui32 i = 0; i < length; i++)
  1291. {
  1292. *this >> key >> value;
  1293. data.insert(std::pair<T1, T2>(std::move(key), std::move(value)));
  1294. }
  1295. }
  1296. void loadSerializable(std::string &data)
  1297. {
  1298. READ_CHECK_U32(length);
  1299. data.resize(length);
  1300. this->This()->read((void*)data.c_str(),length);
  1301. }
  1302. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  1303. void loadSerializable(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &data)
  1304. {
  1305. typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> TVariant;
  1306. VariantLoaderHelper<TVariant, CISer> loader(*this);
  1307. si32 which;
  1308. *this >> which;
  1309. assert(which < loader.funcs.size());
  1310. data = loader.funcs.at(which)();
  1311. }
  1312. template <typename T>
  1313. void loadSerializable(boost::optional<T> & data)
  1314. {
  1315. ui8 present;
  1316. *this >> present;
  1317. if(present)
  1318. {
  1319. T t;
  1320. *this >> t;
  1321. data = t;
  1322. }
  1323. else
  1324. {
  1325. data = boost::optional<T>();
  1326. }
  1327. }
  1328. // void loadSerializable(CStackInstance *&s)
  1329. // {
  1330. // if(sendStackInstanceByIds)
  1331. // {
  1332. // CArmedInstance *armed;
  1333. // SlotID slot;
  1334. // *this >> armed >> slot;
  1335. // assert(armed->hasStackAtSlot(slot));
  1336. // s = armed->stacks[slot];
  1337. // }
  1338. // else
  1339. // loadSerializableBySerializeCall(s);
  1340. // }
  1341. template <typename E>
  1342. void loadEnum(E &data)
  1343. {
  1344. si32 read;
  1345. *this >> read;
  1346. data = static_cast<E>(read);
  1347. }
  1348. void loadBoolean(bool &data)
  1349. {
  1350. ui8 read;
  1351. *this >> read;
  1352. data = static_cast<bool>(read);
  1353. }
  1354. void loadBooleanVector(std::vector<bool> & data)
  1355. {
  1356. std::vector<ui8> convData;
  1357. loadSerializable(convData);
  1358. convData.resize(data.size());
  1359. range::copy(convData, data.begin());
  1360. }
  1361. };
  1362. class DLL_LINKAGE CSaveFile
  1363. : public COSer<CSaveFile>
  1364. {
  1365. public:
  1366. std::string fName;
  1367. unique_ptr<std::ofstream> sfile;
  1368. CSaveFile(const std::string &fname); //throws!
  1369. ~CSaveFile();
  1370. int write(const void * data, unsigned size);
  1371. void openNextFile(const std::string &fname); //throws!
  1372. void clear();
  1373. void reportState(CLogger * out);
  1374. void putMagicBytes(const std::string &text);
  1375. };
  1376. class DLL_LINKAGE CLoadFile
  1377. : public CISer<CLoadFile>
  1378. {
  1379. public:
  1380. std::string fName;
  1381. unique_ptr<std::ifstream> sfile;
  1382. CLoadFile(const std::string &fname, int minimalVersion = version); //throws!
  1383. ~CLoadFile();
  1384. int read(void * data, unsigned size); //throws!
  1385. void openNextFile(const std::string &fname, int minimalVersion); //throws!
  1386. void clear();
  1387. void reportState(CLogger * out);
  1388. void checkMagicBytes(const std::string &text);
  1389. };
  1390. class DLL_LINKAGE CLoadIntegrityValidator : public CISer<CLoadIntegrityValidator>
  1391. {
  1392. public:
  1393. unique_ptr<CLoadFile> primaryFile, controlFile;
  1394. bool foundDesync;
  1395. CLoadIntegrityValidator(const std::string &primaryFileName, const std::string &controlFileName, int minimalVersion = version); //throws!
  1396. int read( void * data, unsigned size); //throws!
  1397. void checkMagicBytes(const std::string &text);
  1398. unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
  1399. };
  1400. typedef boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > TSocket;
  1401. typedef boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > TAcceptor;
  1402. class DLL_LINKAGE CConnection
  1403. : public CISer<CConnection>, public COSer<CConnection>
  1404. {
  1405. //CGameState *gs;
  1406. CConnection(void);
  1407. void init();
  1408. void reportState(CLogger * out);
  1409. public:
  1410. boost::mutex *rmx, *wmx; // read/write mutexes
  1411. TSocket * socket;
  1412. bool logging;
  1413. bool connected;
  1414. bool myEndianess, contactEndianess; //true if little endian, if endianness is different we'll have to revert received multi-byte vars
  1415. boost::asio::io_service *io_service;
  1416. std::string name; //who uses this connection
  1417. int connectionID;
  1418. boost::thread *handler;
  1419. bool receivedStop, sendStop;
  1420. CConnection(std::string host, std::string port, std::string Name);
  1421. CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name);
  1422. CConnection(TSocket * Socket, std::string Name); //use immediately after accepting connection into socket
  1423. int write(const void * data, unsigned size);
  1424. int read(void * data, unsigned size);
  1425. void close();
  1426. bool isOpen() const;
  1427. template<class T>
  1428. CConnection &operator&(const T&);
  1429. virtual ~CConnection(void);
  1430. CPack *retreivePack(); //gets from server next pack (allocates it with new)
  1431. void sendPackToServer(const CPack &pack, PlayerColor player, ui32 requestID);
  1432. void disableStackSendingByID();
  1433. void enableStackSendingByID();
  1434. void disableSmartPointerSerialization();
  1435. void enableSmartPointerSerializatoin();
  1436. void disableSmartVectorMemberSerialization();
  1437. void enableSmartVectorMemberSerializatoin();
  1438. void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache
  1439. void enterPregameConnectionMode();
  1440. };
  1441. DLL_LINKAGE std::ostream &operator<<(std::ostream &str, const CConnection &cpc);
  1442. // Serializer that stores objects in the dynamic buffer. Allows performing deep object copies.
  1443. class DLL_LINKAGE CMemorySerializer
  1444. : public CISer<CMemorySerializer>, public COSer<CMemorySerializer>
  1445. {
  1446. std::vector<ui8> buffer;
  1447. size_t readPos; //index of the next byte to be read
  1448. public:
  1449. int read(void * data, unsigned size); //throws!
  1450. int write(const void * data, unsigned size);
  1451. CMemorySerializer();
  1452. template <typename T>
  1453. static unique_ptr<T> deepCopy(const T &data)
  1454. {
  1455. CMemorySerializer mem;
  1456. mem << &data;
  1457. unique_ptr<T> ret;
  1458. mem >> ret;
  1459. return ret;
  1460. }
  1461. };
  1462. template<typename T>
  1463. class CApplier
  1464. {
  1465. public:
  1466. std::map<ui16,T*> apps;
  1467. ~CApplier()
  1468. {
  1469. typename std::map<ui16, T*>::iterator iter;
  1470. for(iter = apps.begin(); iter != apps.end(); iter++)
  1471. delete iter->second;
  1472. }
  1473. template<typename RegisteredType>
  1474. void addApplier(ui16 ID)
  1475. {
  1476. if(!apps.count(ID))
  1477. {
  1478. RegisteredType * rtype = nullptr;
  1479. apps[ID] = T::getApplier(rtype);
  1480. }
  1481. }
  1482. template<typename Base, typename Derived>
  1483. void registerType(const Base * b = nullptr, const Derived * d = nullptr)
  1484. {
  1485. typeList.registerType(b, d);
  1486. addApplier<Base>(typeList.getTypeID(b));
  1487. addApplier<Derived>(typeList.getTypeID(d));
  1488. }
  1489. };