1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-07 00:58:39 +02:00

Merge pull request #126 from vmarkovtsev/issue/2306

Fix typeid ordering bug on MacOSX
This commit is contained in:
Alexander Shishkin
2015-10-25 15:47:11 +03:00
2 changed files with 74 additions and 71 deletions

View File

@ -68,7 +68,7 @@ void CConnection::init()
} }
CConnection::CConnection(std::string host, std::string port, std::string Name) 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; int i;
boost::system::error_code error = asio::error::host_not_found; boost::system::error_code error = asio::error::host_not_found;
@ -119,7 +119,7 @@ connerror1:
else else
logNetwork->errorStream() << "No error info. "; logNetwork->errorStream() << "No error info. ";
delete io_service; delete io_service;
//delete socket; //delete socket;
throw std::runtime_error("Can't establish connection :("); throw std::runtime_error("Can't establish connection :(");
} }
CConnection::CConnection(TSocket * Socket, std::string Name ) 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); socket = new tcp::socket(*io_service);
acceptor->accept(*socket,error); acceptor->accept(*socket,error);
if (error) if (error)
{ {
logNetwork->errorStream() << "Error on accepting: " << error; logNetwork->errorStream() << "Error on accepting: " << error;
delete socket; delete socket;
throw std::runtime_error("Can't establish connection :("); throw std::runtime_error("Can't establish connection :(");
} }
init(); init();
} }
@ -238,12 +238,12 @@ void CConnection::sendPackToServer(const CPack &pack, PlayerColor player, ui32 r
void CConnection::disableStackSendingByID() void CConnection::disableStackSendingByID()
{ {
CSerializer::sendStackInstanceByIds = false; CSerializer::sendStackInstanceByIds = false;
} }
void CConnection::enableStackSendingByID() void CConnection::enableStackSendingByID()
{ {
CSerializer::sendStackInstanceByIds = true; CSerializer::sendStackInstanceByIds = true;
} }
void CConnection::disableSmartPointerSerialization() void CConnection::disableSmartPointerSerialization()
@ -283,7 +283,7 @@ void CConnection::enableSmartVectorMemberSerializatoin()
CSerializer::smartVectorMembersSerialization = true; CSerializer::smartVectorMembersSerialization = true;
} }
CSaveFile::CSaveFile( const std::string &fname ): serializer(this) CSaveFile::CSaveFile( const std::string &fname ): serializer(this)
{ {
registerTypes(serializer); registerTypes(serializer);
openNextFile(fname); openNextFile(fname);
@ -377,7 +377,7 @@ void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalV
if(std::memcmp(buffer,"VCMI",4)) if(std::memcmp(buffer,"VCMI",4))
THROW_FORMAT("Error: not a VCMI file(%s)!", fName); THROW_FORMAT("Error: not a VCMI file(%s)!", fName);
serializer >> serializer.fileVersion; serializer >> serializer.fileVersion;
if(serializer.fileVersion < minimalVersion) if(serializer.fileVersion < minimalVersion)
THROW_FORMAT("Error: too old file format (%s)!", fName); THROW_FORMAT("Error: too old file format (%s)!", fName);
@ -435,7 +435,7 @@ CTypeList::CTypeList()
} }
CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type ) CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type )
{ {
if(auto typeDescr = getTypeDescriptor(type, false)) if(auto typeDescr = getTypeDescriptor(type, false))
return typeDescr; //type found, return ptr to structure return typeDescr; //type found, return ptr to structure
@ -448,14 +448,14 @@ CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type )
return newType; return newType;
} }
ui16 CTypeList::getTypeID(const std::type_info * type) const ui16 CTypeList::getTypeID( const std::type_info *type, bool throws ) const
{ {
TSharedLock lock(mx); auto descriptor = getTypeDescriptor(type, throws);
auto i = typeInfos.find(type); if (descriptor == nullptr)
if(i != typeInfos.end()) {
return i->second->typeID;
else
return 0; return 0;
}
return descriptor->typeID;
} }
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const
@ -483,7 +483,7 @@ std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, Ty
} }
} }
} }
std::vector<TypeInfoPtr> ret; std::vector<TypeInfoPtr> ret;
if(!previous.count(from)) if(!previous.count(from))
@ -525,7 +525,7 @@ CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type,
{ {
auto i = typeInfos.find(type); auto i = typeInfos.find(type);
if(i != typeInfos.end()) if(i != typeInfos.end())
return i->second; //type found, return ptr to structure return i->second; //type found, return ptr to structure
if(!throws) if(!throws)
return nullptr; return nullptr;
@ -552,19 +552,19 @@ CSerializer::CSerializer()
void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib) void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
{ {
registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects, registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects,
[](const CGObjectInstance &obj){ return obj.id; }); [](const CGObjectInstance &obj){ return obj.id; });
registerVectoredType<CHero, HeroTypeID>(&lib->heroh->heroes, registerVectoredType<CHero, HeroTypeID>(&lib->heroh->heroes,
[](const CHero &h){ return h.ID; }); [](const CHero &h){ return h.ID; });
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes, registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes,
[](const CGHeroInstance &h){ return h.type->ID; }); [](const CGHeroInstance &h){ return h.type->ID; });
registerVectoredType<CCreature, CreatureID>(&lib->creh->creatures, registerVectoredType<CCreature, CreatureID>(&lib->creh->creatures,
[](const CCreature &cre){ return cre.idNumber; }); [](const CCreature &cre){ return cre.idNumber; });
registerVectoredType<CArtifact, ArtifactID>(&lib->arth->artifacts, registerVectoredType<CArtifact, ArtifactID>(&lib->arth->artifacts,
[](const CArtifact &art){ return art.id; }); [](const CArtifact &art){ return art.id; });
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->map->artInstances, registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->map->artInstances,
[](const CArtifactInstance &artInst){ return artInst.id; }); [](const CArtifactInstance &artInst){ return artInst.id; });
registerVectoredType<CQuest, si32>(&gs->map->quests, registerVectoredType<CQuest, si32>(&gs->map->quests,
[](const CQuest &q){ return q.qid; }); [](const CQuest &q){ return q.qid; });
smartVectorMembersSerialization = true; smartVectorMembersSerialization = true;
@ -645,4 +645,3 @@ CMemorySerializer::CMemorySerializer(): iser(this), oser(this)
registerTypes(iser); registerTypes(iser);
registerTypes(oser); registerTypes(oser);
} }

View File

@ -81,10 +81,14 @@ enum SerializationLvl
struct TypeComparer struct TypeComparer
{ {
bool operator()(const std::type_info *a, const std::type_info *b) const bool operator()(const std::type_info *a, const std::type_info *b) const
{ {
return a->before(*b); #ifndef __APPLE__
} return a->before(*b);
#else
return std::string(a->name()) < std::string(b->name());
#endif
}
}; };
struct IPointerCaster struct IPointerCaster
@ -160,7 +164,7 @@ private:
/// Throws if there is no link registered. /// Throws if there is no link registered.
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to) const; std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to) const;
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to) const; std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to) const;
template<boost::any(IPointerCaster::*CastingFunction)(const boost::any &) const> template<boost::any(IPointerCaster::*CastingFunction)(const boost::any &) const>
boost::any castHelper(boost::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg) const 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<const PointerCaster<Derived, Base>>(); casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
} }
ui16 getTypeID(const std::type_info *type) const; ui16 getTypeID(const std::type_info *type, bool throws = false) const;
template <typename T> template <typename T>
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<typename TInput> template<typename TInput>
@ -435,13 +439,13 @@ public:
virtual int write(const void * data, unsigned size) = 0; virtual int write(const void * data, unsigned size) = 0;
}; };
class DLL_LINKAGE CSaverBase class DLL_LINKAGE CSaverBase
{ {
protected: protected:
IBinaryWriter * writer; IBinaryWriter * writer;
public: public:
CSaverBase(IBinaryWriter * w): writer(w){}; CSaverBase(IBinaryWriter * w): writer(w){};
inline int write(const void * data, unsigned size) inline int write(const void * data, unsigned size)
{ {
return writer->write(data, size); return writer->write(data, size);
@ -577,15 +581,15 @@ struct LoadIfStackInstance<Ser, CStackInstance *>
class DLL_LINKAGE COSer : public CSaverBase class DLL_LINKAGE COSer : public CSaverBase
{ {
public: public:
struct SaveBoolean struct SaveBoolean
{ {
static void invoke(COSer &s, const bool &data) static void invoke(COSer &s, const bool &data)
{ {
s.saveBoolean(data); s.saveBoolean(data);
} }
}; };
struct SaveBooleanVector struct SaveBooleanVector
{ {
static void invoke(COSer &s, const std::vector<bool> &data) static void invoke(COSer &s, const std::vector<bool> &data)
@ -620,7 +624,7 @@ public:
s.saveEnum(data); s.saveEnum(data);
} }
}; };
template<typename T> template<typename T>
struct SavePointer struct SavePointer
{ {
@ -629,7 +633,7 @@ public:
s.savePointer(data); s.savePointer(data);
} }
}; };
template<typename T> template<typename T>
struct SaveArray struct SaveArray
{ {
@ -646,9 +650,9 @@ public:
{ {
throw std::runtime_error("Wrong save serialization call!"); throw std::runtime_error("Wrong save serialization call!");
} }
}; };
template <typename T> template <typename T>
class CPointerSaver : public CBasicPointerSaver class CPointerSaver : public CBasicPointerSaver
{ {
public: public:
@ -660,8 +664,8 @@ public:
//T is most derived known type, it's time to call actual serialize //T is most derived known type, it's time to call actual serialize
const_cast<T&>(*ptr).serialize(s,version); const_cast<T&>(*ptr).serialize(s,version);
} }
}; };
bool saving; bool saving;
std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type> std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type>
@ -955,13 +959,13 @@ public:
virtual int read(void * data, unsigned size) = 0; virtual int read(void * data, unsigned size) = 0;
}; };
class DLL_LINKAGE CLoaderBase class DLL_LINKAGE CLoaderBase
{ {
protected: protected:
IBinaryReader * reader; IBinaryReader * reader;
public: public:
CLoaderBase(IBinaryReader * r): reader(r){}; CLoaderBase(IBinaryReader * r): reader(r){};
inline int read(void * data, unsigned size) inline int read(void * data, unsigned size)
{ {
return reader->read(data, size); return reader->read(data, size);
@ -1006,15 +1010,15 @@ public:
s.loadBoolean(data); s.loadBoolean(data);
} }
}; };
struct LoadBooleanVector struct LoadBooleanVector
{ {
static void invoke(CISer &s, std::vector<bool> &data) static void invoke(CISer &s, std::vector<bool> &data)
{ {
s.loadBooleanVector(data); s.loadBooleanVector(data);
} }
}; };
template<typename T> template<typename T>
struct LoadEnum struct LoadEnum
{ {
@ -1031,7 +1035,7 @@ public:
{ {
s.loadPrimitive(data); s.loadPrimitive(data);
} }
}; };
template<typename T> template<typename T>
struct LoadPointer struct LoadPointer
@ -1040,8 +1044,8 @@ public:
{ {
s.loadPointer(data); s.loadPointer(data);
} }
}; };
template<typename T> template<typename T>
struct LoadArray struct LoadArray
{ {
@ -1067,8 +1071,8 @@ public:
{ {
throw std::runtime_error("Wrong load serialization call!"); throw std::runtime_error("Wrong load serialization call!");
} }
}; };
template <typename T> class CPointerLoader : public CBasicPointerLoader template <typename T> class CPointerLoader : public CBasicPointerLoader
{ {
public: public:
@ -1085,8 +1089,8 @@ public:
ptr->serialize(s,version); ptr->serialize(s,version);
return &typeid(T); return &typeid(T);
} }
}; };
bool saving; bool saving;
std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type> std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
si32 fileVersion; si32 fileVersion;
@ -1530,9 +1534,9 @@ class DLL_LINKAGE CSaveFile
:public IBinaryWriter :public IBinaryWriter
{ {
public: public:
COSer serializer; COSer serializer;
std::string fName; std::string fName;
unique_ptr<std::ofstream> sfile; unique_ptr<std::ofstream> sfile;
@ -1545,13 +1549,13 @@ public:
void reportState(CLogger * out) override; void reportState(CLogger * out) override;
void putMagicBytes(const std::string &text); void putMagicBytes(const std::string &text);
template<class T> template<class T>
CSaveFile & operator<<(const T &t) CSaveFile & operator<<(const T &t)
{ {
serializer << t; serializer << t;
return * this; return * this;
} }
}; };
class DLL_LINKAGE CLoadFile class DLL_LINKAGE CLoadFile
@ -1559,7 +1563,7 @@ class DLL_LINKAGE CLoadFile
{ {
public: public:
CISer serializer; CISer serializer;
std::string fName; std::string fName;
unique_ptr<boost::filesystem::ifstream> sfile; unique_ptr<boost::filesystem::ifstream> sfile;
@ -1572,20 +1576,20 @@ public:
void reportState(CLogger * out) override; void reportState(CLogger * out) override;
void checkMagicBytes(const std::string & text); void checkMagicBytes(const std::string & text);
template<class T> template<class T>
CLoadFile & operator>>(T &t) CLoadFile & operator>>(T &t)
{ {
serializer >> t; serializer >> t;
return * this; return * this;
} }
}; };
class DLL_LINKAGE CLoadIntegrityValidator class DLL_LINKAGE CLoadIntegrityValidator
: public IBinaryReader : public IBinaryReader
{ {
public: public:
CISer serializer; CISer serializer;
unique_ptr<CLoadFile> primaryFile, controlFile; unique_ptr<CLoadFile> primaryFile, controlFile;
bool foundDesync; bool foundDesync;
@ -1611,7 +1615,7 @@ class DLL_LINKAGE CConnection
public: public:
CISer iser; CISer iser;
COSer oser; COSer oser;
boost::mutex *rmx, *wmx; // read/write mutexes boost::mutex *rmx, *wmx; // read/write mutexes
TSocket * socket; TSocket * socket;
bool logging; bool logging;
@ -1649,14 +1653,14 @@ public:
void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache void prepareForSendingHeroes(); //disables sending vectorised, enables smart pointer serialization, clears saved/loaded ptr cache
void enterPregameConnectionMode(); void enterPregameConnectionMode();
template<class T> template<class T>
CConnection & operator>>(T &t) CConnection & operator>>(T &t)
{ {
iser >> t; iser >> t;
return * this; return * this;
} }
template<class T> template<class T>
CConnection & operator<<(const T &t) CConnection & operator<<(const T &t)
{ {
@ -1678,7 +1682,7 @@ class DLL_LINKAGE CMemorySerializer
public: public:
CISer iser; CISer iser;
COSer oser; COSer oser;
int read(void * data, unsigned size) override; //throws! int read(void * data, unsigned size) override; //throws!
int write(const void * data, unsigned size) override; int write(const void * data, unsigned size) override;