Connection.h 43 KB

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