Connection.h 45 KB

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