From 79fb5b0c7bcc7c3b847a65b62df36bd051c90d03 Mon Sep 17 00:00:00 2001 From: Vadim Markovtsev Date: Sun, 25 Oct 2015 13:04:21 +0300 Subject: [PATCH] Fix typeid ordering bug on MacOSX --- lib/Connection.cpp | 49 ++++++++++++----------- lib/Connection.h | 96 ++++++++++++++++++++++++---------------------- 2 files changed, 74 insertions(+), 71 deletions(-) diff --git a/lib/Connection.cpp b/lib/Connection.cpp index d88326017..0fce3d2c3 100644 --- a/lib/Connection.cpp +++ b/lib/Connection.cpp @@ -68,7 +68,7 @@ void CConnection::init() } CConnection::CConnection(std::string host, std::string port, std::string Name) -:iser(this), oser(this), io_service(new asio::io_service), name(Name) +:iser(this), oser(this), io_service(new asio::io_service), name(Name) { int i; boost::system::error_code error = asio::error::host_not_found; @@ -119,7 +119,7 @@ connerror1: else logNetwork->errorStream() << "No error info. "; delete io_service; - //delete socket; + //delete socket; throw std::runtime_error("Can't establish connection :("); } CConnection::CConnection(TSocket * Socket, std::string Name ) @@ -134,10 +134,10 @@ CConnection::CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_servi socket = new tcp::socket(*io_service); acceptor->accept(*socket,error); if (error) - { + { logNetwork->errorStream() << "Error on accepting: " << error; - delete socket; - throw std::runtime_error("Can't establish connection :("); + delete socket; + throw std::runtime_error("Can't establish connection :("); } init(); } @@ -238,12 +238,12 @@ void CConnection::sendPackToServer(const CPack &pack, PlayerColor player, ui32 r void CConnection::disableStackSendingByID() { - CSerializer::sendStackInstanceByIds = false; + CSerializer::sendStackInstanceByIds = false; } void CConnection::enableStackSendingByID() { - CSerializer::sendStackInstanceByIds = true; + CSerializer::sendStackInstanceByIds = true; } void CConnection::disableSmartPointerSerialization() @@ -283,7 +283,7 @@ void CConnection::enableSmartVectorMemberSerializatoin() CSerializer::smartVectorMembersSerialization = true; } -CSaveFile::CSaveFile( const std::string &fname ): serializer(this) +CSaveFile::CSaveFile( const std::string &fname ): serializer(this) { registerTypes(serializer); openNextFile(fname); @@ -377,7 +377,7 @@ void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalV if(std::memcmp(buffer,"VCMI",4)) THROW_FORMAT("Error: not a VCMI file(%s)!", fName); - serializer >> serializer.fileVersion; + serializer >> serializer.fileVersion; if(serializer.fileVersion < minimalVersion) THROW_FORMAT("Error: too old file format (%s)!", fName); @@ -435,7 +435,7 @@ CTypeList::CTypeList() } CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type ) -{ +{ if(auto typeDescr = getTypeDescriptor(type, false)) return typeDescr; //type found, return ptr to structure @@ -448,14 +448,14 @@ CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type ) return newType; } -ui16 CTypeList::getTypeID(const std::type_info * type) const -{ - TSharedLock lock(mx); - auto i = typeInfos.find(type); - if(i != typeInfos.end()) - return i->second->typeID; - else +ui16 CTypeList::getTypeID( const std::type_info *type, bool throws ) const +{ + auto descriptor = getTypeDescriptor(type, throws); + if (descriptor == nullptr) + { return 0; + } + return descriptor->typeID; } std::vector CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const @@ -483,7 +483,7 @@ std::vector CTypeList::castSequence(TypeInfoPtr from, Ty } } } - + std::vector ret; if(!previous.count(from)) @@ -525,7 +525,7 @@ CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, { auto i = typeInfos.find(type); if(i != typeInfos.end()) - return i->second; //type found, return ptr to structure + return i->second; //type found, return ptr to structure if(!throws) return nullptr; @@ -552,19 +552,19 @@ CSerializer::CSerializer() void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib) { - registerVectoredType(&gs->map->objects, + registerVectoredType(&gs->map->objects, [](const CGObjectInstance &obj){ return obj.id; }); - registerVectoredType(&lib->heroh->heroes, + registerVectoredType(&lib->heroh->heroes, [](const CHero &h){ return h.ID; }); registerVectoredType(&gs->map->allHeroes, [](const CGHeroInstance &h){ return h.type->ID; }); - registerVectoredType(&lib->creh->creatures, + registerVectoredType(&lib->creh->creatures, [](const CCreature &cre){ return cre.idNumber; }); registerVectoredType(&lib->arth->artifacts, [](const CArtifact &art){ return art.id; }); - registerVectoredType(&gs->map->artInstances, + registerVectoredType(&gs->map->artInstances, [](const CArtifactInstance &artInst){ return artInst.id; }); - registerVectoredType(&gs->map->quests, + registerVectoredType(&gs->map->quests, [](const CQuest &q){ return q.qid; }); smartVectorMembersSerialization = true; @@ -645,4 +645,3 @@ CMemorySerializer::CMemorySerializer(): iser(this), oser(this) registerTypes(iser); registerTypes(oser); } - diff --git a/lib/Connection.h b/lib/Connection.h index bf12e07f4..b27a77c50 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -81,10 +81,14 @@ enum SerializationLvl struct TypeComparer { - bool operator()(const std::type_info *a, const std::type_info *b) const - { - return a->before(*b); - } + bool operator()(const std::type_info *a, const std::type_info *b) const + { + #ifndef __APPLE__ + return a->before(*b); + #else + return std::string(a->name()) < std::string(b->name()); + #endif + } }; struct IPointerCaster @@ -160,7 +164,7 @@ private: /// Throws if there is no link registered. std::vector castSequence(TypeInfoPtr from, TypeInfoPtr to) const; std::vector castSequence(const std::type_info *from, const std::type_info *to) const; - + template boost::any castHelper(boost::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg) const @@ -207,12 +211,12 @@ public: casters[std::make_pair(dti, bti)] = make_unique>(); } - ui16 getTypeID(const std::type_info *type) const; + ui16 getTypeID(const std::type_info *type, bool throws = false) const; template - ui16 getTypeID(const T * t = nullptr) const + ui16 getTypeID(const T * t = nullptr, bool throws = false) const { - return getTypeID(getTypeInfo(t)); + return getTypeID(getTypeInfo(t), throws); } template @@ -435,13 +439,13 @@ public: virtual int write(const void * data, unsigned size) = 0; }; -class DLL_LINKAGE CSaverBase +class DLL_LINKAGE CSaverBase { protected: IBinaryWriter * writer; public: CSaverBase(IBinaryWriter * w): writer(w){}; - + inline int write(const void * data, unsigned size) { return writer->write(data, size); @@ -577,15 +581,15 @@ struct LoadIfStackInstance class DLL_LINKAGE COSer : public CSaverBase { public: - + struct SaveBoolean { static void invoke(COSer &s, const bool &data) { s.saveBoolean(data); } - }; - + }; + struct SaveBooleanVector { static void invoke(COSer &s, const std::vector &data) @@ -620,7 +624,7 @@ public: s.saveEnum(data); } }; - + template struct SavePointer { @@ -629,7 +633,7 @@ public: s.savePointer(data); } }; - + template struct SaveArray { @@ -646,9 +650,9 @@ public: { throw std::runtime_error("Wrong save serialization call!"); } - }; - - template + }; + + template class CPointerSaver : public CBasicPointerSaver { public: @@ -660,8 +664,8 @@ public: //T is most derived known type, it's time to call actual serialize const_cast(*ptr).serialize(s,version); } - }; - + }; + bool saving; std::map savers; // typeID => CPointerSaver @@ -955,13 +959,13 @@ public: virtual int read(void * data, unsigned size) = 0; }; -class DLL_LINKAGE CLoaderBase +class DLL_LINKAGE CLoaderBase { protected: IBinaryReader * reader; public: CLoaderBase(IBinaryReader * r): reader(r){}; - + inline int read(void * data, unsigned size) { return reader->read(data, size); @@ -1006,15 +1010,15 @@ public: s.loadBoolean(data); } }; - + struct LoadBooleanVector { static void invoke(CISer &s, std::vector &data) { s.loadBooleanVector(data); } - }; - + }; + template struct LoadEnum { @@ -1031,7 +1035,7 @@ public: { s.loadPrimitive(data); } - }; + }; template struct LoadPointer @@ -1040,8 +1044,8 @@ public: { s.loadPointer(data); } - }; - + }; + template struct LoadArray { @@ -1067,8 +1071,8 @@ public: { throw std::runtime_error("Wrong load serialization call!"); } - }; - + }; + template class CPointerLoader : public CBasicPointerLoader { public: @@ -1085,8 +1089,8 @@ public: ptr->serialize(s,version); return &typeid(T); } - }; - + }; + bool saving; std::map loaders; // typeID => CPointerSaver si32 fileVersion; @@ -1530,9 +1534,9 @@ class DLL_LINKAGE CSaveFile :public IBinaryWriter { public: - + COSer serializer; - + std::string fName; unique_ptr sfile; @@ -1545,13 +1549,13 @@ public: void reportState(CLogger * out) override; void putMagicBytes(const std::string &text); - + template CSaveFile & operator<<(const T &t) { serializer << t; return * this; - } + } }; class DLL_LINKAGE CLoadFile @@ -1559,7 +1563,7 @@ class DLL_LINKAGE CLoadFile { public: CISer serializer; - + std::string fName; unique_ptr sfile; @@ -1572,20 +1576,20 @@ public: void reportState(CLogger * out) override; void checkMagicBytes(const std::string & text); - + template CLoadFile & operator>>(T &t) { serializer >> t; return * this; - } + } }; -class DLL_LINKAGE CLoadIntegrityValidator +class DLL_LINKAGE CLoadIntegrityValidator : public IBinaryReader { public: - CISer serializer; + CISer serializer; unique_ptr primaryFile, controlFile; bool foundDesync; @@ -1611,7 +1615,7 @@ class DLL_LINKAGE CConnection public: CISer iser; COSer oser; - + boost::mutex *rmx, *wmx; // read/write mutexes TSocket * socket; bool logging; @@ -1649,14 +1653,14 @@ public: void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache void enterPregameConnectionMode(); - + template CConnection & operator>>(T &t) { iser >> t; return * this; - } - + } + template CConnection & operator<<(const T &t) { @@ -1678,7 +1682,7 @@ class DLL_LINKAGE CMemorySerializer public: CISer iser; COSer oser; - + int read(void * data, unsigned size) override; //throws! int write(const void * data, unsigned size) override;