Connection.h 45 KB

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