mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-31 22:05:10 +02:00
Improved serializer. See: http://forum.vcmi.eu/viewtopic.php?p=11562#11562
Save format changed, removed compatibility workarounds.
This commit is contained in:
parent
a3cad2883f
commit
1e555a8ee3
@ -209,6 +209,16 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> class CApplyOnPG<CPack> : public CBaseForPGApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void applyOnPG(CSelectionScreen *selScr, void *pack) const
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Cannot apply on PG plain CPack!";
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static CApplier<CBaseForPGApply> *applier = nullptr;
|
static CApplier<CBaseForPGApply> *applier = nullptr;
|
||||||
|
|
||||||
static CPicture* createPicture(const JsonNode& config)
|
static CPicture* createPicture(const JsonNode& config)
|
||||||
|
@ -79,6 +79,22 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> class CApplyOnCL<CPack> : public CBaseForCLApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void applyOnClAfter(CClient *cl, void *pack) const
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Cannot apply on CL plain CPack!";
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
void applyOnClBefore(CClient *cl, void *pack) const
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Cannot apply on CL plain CPack!";
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static CApplier<CBaseForCLApply> *applier = nullptr;
|
static CApplier<CBaseForCLApply> *applier = nullptr;
|
||||||
|
|
||||||
void CClient::init()
|
void CClient::init()
|
||||||
|
@ -75,61 +75,61 @@ public:
|
|||||||
|
|
||||||
static CApplier<CBaseForGSApply> *applierGs = nullptr;
|
static CApplier<CBaseForGSApply> *applierGs = nullptr;
|
||||||
|
|
||||||
class IObjectCaller
|
// class IObjectCaller
|
||||||
{
|
// {
|
||||||
public:
|
// public:
|
||||||
virtual ~IObjectCaller(){};
|
// virtual ~IObjectCaller(){};
|
||||||
virtual void preInit()=0;
|
// virtual void preInit()=0;
|
||||||
virtual void postInit()=0;
|
// virtual void postInit()=0;
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
|
// template <typename T>
|
||||||
|
// class CObjectCaller : public IObjectCaller
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// void preInit()
|
||||||
|
// {
|
||||||
|
// //T::preInit();
|
||||||
|
// }
|
||||||
|
// void postInit()
|
||||||
|
// {
|
||||||
|
// //T::postInit();
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
template <typename T>
|
// class CObjectCallersHandler
|
||||||
class CObjectCaller : public IObjectCaller
|
// {
|
||||||
{
|
// public:
|
||||||
public:
|
// std::vector<IObjectCaller*> apps;
|
||||||
void preInit()
|
//
|
||||||
{
|
// template<typename T> void registerType(const T * t=nullptr)
|
||||||
//T::preInit();
|
// {
|
||||||
}
|
// apps.push_back(new CObjectCaller<T>);
|
||||||
void postInit()
|
// }
|
||||||
{
|
//
|
||||||
//T::postInit();
|
// CObjectCallersHandler()
|
||||||
}
|
// {
|
||||||
};
|
// registerTypes1(*this);
|
||||||
|
// }
|
||||||
class CObjectCallersHandler
|
//
|
||||||
{
|
// ~CObjectCallersHandler()
|
||||||
public:
|
// {
|
||||||
std::vector<IObjectCaller*> apps;
|
// for (auto & elem : apps)
|
||||||
|
// delete elem;
|
||||||
template<typename T> void registerType(const T * t=nullptr)
|
// }
|
||||||
{
|
//
|
||||||
apps.push_back(new CObjectCaller<T>);
|
// void preInit()
|
||||||
}
|
// {
|
||||||
|
// // for (size_t i = 0; i < apps.size(); i++)
|
||||||
CObjectCallersHandler()
|
// // apps[i]->preInit();
|
||||||
{
|
// }
|
||||||
registerTypes1(*this);
|
//
|
||||||
}
|
// void postInit()
|
||||||
|
// {
|
||||||
~CObjectCallersHandler()
|
// //for (size_t i = 0; i < apps.size(); i++)
|
||||||
{
|
// //apps[i]->postInit();
|
||||||
for (auto & elem : apps)
|
// }
|
||||||
delete elem;
|
// } *objCaller = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
void preInit()
|
|
||||||
{
|
|
||||||
// for (size_t i = 0; i < apps.size(); i++)
|
|
||||||
// apps[i]->preInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void postInit()
|
|
||||||
{
|
|
||||||
//for (size_t i = 0; i < apps.size(); i++)
|
|
||||||
//apps[i]->postInit();
|
|
||||||
}
|
|
||||||
} *objCaller = nullptr;
|
|
||||||
|
|
||||||
void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst) const
|
void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst) const
|
||||||
{
|
{
|
||||||
@ -730,7 +730,7 @@ CGameState::CGameState()
|
|||||||
mx = new boost::shared_mutex();
|
mx = new boost::shared_mutex();
|
||||||
applierGs = new CApplier<CBaseForGSApply>;
|
applierGs = new CApplier<CBaseForGSApply>;
|
||||||
registerTypes2(*applierGs);
|
registerTypes2(*applierGs);
|
||||||
objCaller = new CObjectCallersHandler;
|
//objCaller = new CObjectCallersHandler;
|
||||||
globalEffects.setDescription("Global effects");
|
globalEffects.setDescription("Global effects");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,7 +742,7 @@ CGameState::~CGameState()
|
|||||||
//delete scenarioOps; //TODO: fix for loading ind delete
|
//delete scenarioOps; //TODO: fix for loading ind delete
|
||||||
//delete initialOpts;
|
//delete initialOpts;
|
||||||
delete applierGs;
|
delete applierGs;
|
||||||
delete objCaller;
|
//delete objCaller;
|
||||||
|
|
||||||
for(auto ptr : hpool.heroesPool) // clean hero pool
|
for(auto ptr : hpool.heroesPool) // clean hero pool
|
||||||
ptr.second.dellNull();
|
ptr.second.dellNull();
|
||||||
@ -1838,7 +1838,7 @@ void CGameState::initTowns()
|
|||||||
void CGameState::initMapObjects()
|
void CGameState::initMapObjects()
|
||||||
{
|
{
|
||||||
logGlobal->debugStream() << "\tObject initialization";
|
logGlobal->debugStream() << "\tObject initialization";
|
||||||
objCaller->preInit();
|
// objCaller->preInit();
|
||||||
for(CGObjectInstance *obj : map->objects)
|
for(CGObjectInstance *obj : map->objects)
|
||||||
{
|
{
|
||||||
if(obj)
|
if(obj)
|
||||||
|
@ -45,13 +45,7 @@ class CIdentifierStorage
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
if(version >= 744)
|
h & id & scope;
|
||||||
h & id & scope;
|
|
||||||
else if(h.saving)
|
|
||||||
{
|
|
||||||
logGlobal->warnStream() << "Save compatibility, making object data with id -1 (can this happen?)";
|
|
||||||
id = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,8 +81,7 @@ public:
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
if(version >= 744)
|
h & registeredObjects;
|
||||||
h & registeredObjects;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -266,10 +259,6 @@ public:
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & allMods & activeMods & settings & modules;
|
h & allMods & activeMods & settings & modules & identifiers;
|
||||||
if(version >= 744)
|
|
||||||
h & identifiers;
|
|
||||||
else
|
|
||||||
logGlobal->warnStream() << "Savegame compatibility mode, omitting identifiers in modhandler. Related bugs will persist.";
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -128,6 +128,11 @@ public:
|
|||||||
|
|
||||||
static void preInit(); //called before objs receive their initObj
|
static void preInit(); //called before objs receive their initObj
|
||||||
static void postInit();//called after objs receive their initObj
|
static void postInit();//called after objs receive their initObj
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "IObjectInterface serialized, unexpected, should not happen!";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE IBoatGenerator
|
class DLL_LINKAGE IBoatGenerator
|
||||||
@ -136,6 +141,8 @@ public:
|
|||||||
const CGObjectInstance *o;
|
const CGObjectInstance *o;
|
||||||
|
|
||||||
IBoatGenerator(const CGObjectInstance *O);
|
IBoatGenerator(const CGObjectInstance *O);
|
||||||
|
virtual ~IBoatGenerator() {}
|
||||||
|
|
||||||
virtual int getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
|
virtual int getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
|
||||||
virtual void getOutOffsets(std::vector<int3> &offsets) const =0; //offsets to obj pos when we boat can be placed
|
virtual void getOutOffsets(std::vector<int3> &offsets) const =0; //offsets to obj pos when we boat can be placed
|
||||||
int3 bestLocation() const; //returns location when the boat should be placed
|
int3 bestLocation() const; //returns location when the boat should be placed
|
||||||
@ -143,16 +150,28 @@ public:
|
|||||||
enum EGeneratorState {GOOD, BOAT_ALREADY_BUILT, TILE_BLOCKED, NO_WATER};
|
enum EGeneratorState {GOOD, BOAT_ALREADY_BUILT, TILE_BLOCKED, NO_WATER};
|
||||||
EGeneratorState shipyardStatus() const; //0 - can buid, 1 - there is already a boat at dest tile, 2 - dest tile is blocked, 3 - no water
|
EGeneratorState shipyardStatus() const; //0 - can buid, 1 - there is already a boat at dest tile, 2 - dest tile is blocked, 3 - no water
|
||||||
void getProblemText(MetaString &out, const CGHeroInstance *visitor = nullptr) const;
|
void getProblemText(MetaString &out, const CGHeroInstance *visitor = nullptr) const;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & o;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE IShipyard : public IBoatGenerator
|
class DLL_LINKAGE IShipyard : public IBoatGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IShipyard(const CGObjectInstance *O);
|
IShipyard(const CGObjectInstance *O);
|
||||||
|
virtual ~IShipyard() {}
|
||||||
|
|
||||||
virtual void getBoatCost(std::vector<si32> &cost) const;
|
virtual void getBoatCost(std::vector<si32> &cost) const;
|
||||||
|
|
||||||
static const IShipyard *castFrom(const CGObjectInstance *obj);
|
static const IShipyard *castFrom(const CGObjectInstance *obj);
|
||||||
static IShipyard *castFrom(CGObjectInstance *obj);
|
static IShipyard *castFrom(CGObjectInstance *obj);
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & static_cast<IBoatGenerator&>(*this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE IMarket
|
class DLL_LINKAGE IMarket
|
||||||
@ -161,6 +180,8 @@ public:
|
|||||||
const CGObjectInstance *o;
|
const CGObjectInstance *o;
|
||||||
|
|
||||||
IMarket(const CGObjectInstance *O);
|
IMarket(const CGObjectInstance *O);
|
||||||
|
virtual ~IMarket() {}
|
||||||
|
|
||||||
virtual int getMarketEfficiency() const =0;
|
virtual int getMarketEfficiency() const =0;
|
||||||
virtual bool allowsTrade(EMarketMode::EMarketMode mode) const;
|
virtual bool allowsTrade(EMarketMode::EMarketMode mode) const;
|
||||||
virtual int availableUnits(EMarketMode::EMarketMode mode, int marketItemSerial) const; //-1 if unlimited
|
virtual int availableUnits(EMarketMode::EMarketMode mode, int marketItemSerial) const; //-1 if unlimited
|
||||||
@ -170,6 +191,11 @@ public:
|
|||||||
std::vector<EMarketMode::EMarketMode> availableModes() const;
|
std::vector<EMarketMode::EMarketMode> availableModes() const;
|
||||||
|
|
||||||
static const IMarket *castFrom(const CGObjectInstance *obj, bool verbose = true);
|
static const IMarket *castFrom(const CGObjectInstance *obj, bool verbose = true);
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & o;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CGObjectInstance : public IObjectInterface
|
class DLL_LINKAGE CGObjectInstance : public IObjectInterface
|
||||||
@ -653,6 +679,8 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & static_cast<CGDwelling&>(*this);
|
h & static_cast<CGDwelling&>(*this);
|
||||||
|
h & static_cast<IShipyard&>(*this);
|
||||||
|
h & static_cast<IMarket&>(*this);
|
||||||
h & name & builded & destroyed & identifier;
|
h & name & builded & destroyed & identifier;
|
||||||
h & garrisonHero & visitingHero;
|
h & garrisonHero & visitingHero;
|
||||||
h & alignment & forbiddenBuildings & builtBuildings & bonusValue
|
h & alignment & forbiddenBuildings & builtBuildings & bonusValue
|
||||||
@ -1333,6 +1361,12 @@ public:
|
|||||||
void getOutOffsets(std::vector<int3> &offsets) const; //offsets to obj pos when we boat can be placed
|
void getOutOffsets(std::vector<int3> &offsets) const; //offsets to obj pos when we boat can be placed
|
||||||
CGShipyard();
|
CGShipyard();
|
||||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & static_cast<CGObjectInstance&>(*this);
|
||||||
|
h & static_cast<IShipyard&>(*this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CGMagi : public CGObjectInstance
|
class DLL_LINKAGE CGMagi : public CGObjectInstance
|
||||||
@ -1417,6 +1451,7 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & static_cast<CGObjectInstance&>(*this);
|
h & static_cast<CGObjectInstance&>(*this);
|
||||||
|
h & static_cast<IMarket&>(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -440,27 +440,104 @@ CTypeList::CTypeList()
|
|||||||
registerTypes(*this);
|
registerTypes(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui16 CTypeList::registerType( const std::type_info *type )
|
CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type )
|
||||||
{
|
{
|
||||||
TTypeMap::const_iterator i = types.find(type);
|
if(auto typeDescr = getTypeDescriptor(type, false))
|
||||||
if(i != types.end())
|
return typeDescr; //type found, return ptr to structure
|
||||||
return i->second; //type found, return ID
|
|
||||||
|
|
||||||
//type not found - add it to the list and return given ID
|
//type not found - add it to the list and return given ID
|
||||||
ui16 id = types.size() + 1;
|
auto newType = make_shared<TypeDescriptor>();
|
||||||
types.insert(std::make_pair(type,id));
|
newType->typeID = typeInfos.size() + 1;
|
||||||
return id;
|
newType->name = type->name();
|
||||||
|
typeInfos[type] = newType;
|
||||||
|
|
||||||
|
return newType;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui16 CTypeList::getTypeID( const std::type_info *type )
|
ui16 CTypeList::getTypeID( const std::type_info *type )
|
||||||
{
|
{
|
||||||
TTypeMap::const_iterator i = types.find(type);
|
auto i = typeInfos.find(type);
|
||||||
if(i != types.end())
|
if(i != typeInfos.end())
|
||||||
return i->second;
|
return i->second->typeID;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to)
|
||||||
|
{
|
||||||
|
if(from == to)
|
||||||
|
return std::vector<CTypeList::TypeInfoPtr>();
|
||||||
|
|
||||||
|
// Perform a simple BFS in the class hierarchy.
|
||||||
|
|
||||||
|
auto BFS = [&](bool upcast)
|
||||||
|
{
|
||||||
|
std::map<TypeInfoPtr, TypeInfoPtr> previous;
|
||||||
|
std::queue<TypeInfoPtr> q;
|
||||||
|
q.push(to);
|
||||||
|
while(q.size())
|
||||||
|
{
|
||||||
|
auto typeNode = q.front();
|
||||||
|
q.pop();
|
||||||
|
for(auto &nodeBase : upcast ? typeNode->parents : typeNode->children)
|
||||||
|
{
|
||||||
|
if(!previous.count(nodeBase))
|
||||||
|
{
|
||||||
|
previous[nodeBase] = typeNode;
|
||||||
|
q.push(nodeBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TypeInfoPtr> ret;
|
||||||
|
|
||||||
|
if(!previous.count(from))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret.push_back(from);
|
||||||
|
TypeInfoPtr ptr = from;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ptr = previous.at(ptr);
|
||||||
|
ret.push_back(ptr);
|
||||||
|
} while(ptr != to);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try looking both up and down.
|
||||||
|
auto ret = BFS(true);
|
||||||
|
if(ret.empty())
|
||||||
|
ret = BFS(false);
|
||||||
|
|
||||||
|
if(ret.empty())
|
||||||
|
THROW_FORMAT("Cannot find relation between types %s and %s. Were they (and all classes between them) properly registered?", from->name % to->name);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to)
|
||||||
|
{
|
||||||
|
//This additional if is needed because getTypeDescriptor might fail if type is not registered
|
||||||
|
// (and if casting is not needed, then registereing should no be required)
|
||||||
|
if(*from == *to)
|
||||||
|
return std::vector<CTypeList::TypeInfoPtr>();
|
||||||
|
|
||||||
|
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
|
||||||
|
}
|
||||||
|
|
||||||
|
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws)
|
||||||
|
{
|
||||||
|
auto i = typeInfos.find(type);
|
||||||
|
if(i != typeInfos.end())
|
||||||
|
return i->second; //type found, return ptr to structure
|
||||||
|
|
||||||
|
if(!throws)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
THROW_FORMAT("Cannot find type descriptor for type %s. Was it registered?", type->name());
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream &str, const CConnection &cpc)
|
std::ostream & operator<<(std::ostream &str, const CConnection &cpc)
|
||||||
{
|
{
|
||||||
return str << "Connection with " << cpc.name << " (ID: " << cpc.connectionID << /*", " << (cpc.host ? "host" : "guest") <<*/ ")";
|
return str << "Connection with " << cpc.name << " (ID: " << cpc.connectionID << /*", " << (cpc.host ? "host" : "guest") <<*/ ")";
|
||||||
@ -536,6 +613,7 @@ int CLoadIntegrityValidator::read( void * data, unsigned size )
|
|||||||
unique_ptr<CLoadFile> CLoadIntegrityValidator::decay()
|
unique_ptr<CLoadFile> CLoadIntegrityValidator::decay()
|
||||||
{
|
{
|
||||||
primaryFile->loadedPointers = this->loadedPointers;
|
primaryFile->loadedPointers = this->loadedPointers;
|
||||||
|
primaryFile->loadedPointersTypes = this->loadedPointersTypes;
|
||||||
return std::move(primaryFile);
|
return std::move(primaryFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
293
lib/Connection.h
293
lib/Connection.h
@ -28,8 +28,8 @@
|
|||||||
#include "mapping/CCampaignHandler.h" //for CCampaignState
|
#include "mapping/CCampaignHandler.h" //for CCampaignState
|
||||||
#include "rmg/CMapGenerator.h" // for CMapGenOptions
|
#include "rmg/CMapGenerator.h" // for CMapGenOptions
|
||||||
|
|
||||||
const ui32 version = 744;
|
const ui32 version = 745;
|
||||||
const ui32 minSupportedVersion = 743;
|
const ui32 minSupportedVersion = version;
|
||||||
|
|
||||||
class CConnection;
|
class CConnection;
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
@ -86,23 +86,174 @@ struct TypeComparer
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IPointerCaster
|
||||||
|
{
|
||||||
|
virtual boost::any castRawPtr(const boost::any &ptr) const = 0; // takes From*, performs dynamic cast, returns To*
|
||||||
|
virtual boost::any castSharedPtr(const boost::any &ptr) const = 0; // takes std::shared_ptr<From>, performs dynamic cast, returns std::shared_ptr<To>
|
||||||
|
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.
|
||||||
|
//virtual boost::any castUniquePtr(const boost::any &ptr) const = 0; // takes std::unique_ptr<From>, performs dynamic cast, returns std::unique_ptr<To>
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct PointerCaster : IPointerCaster
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
From * from = (From*)boost::any_cast<void*>(ptr);
|
||||||
|
To * ret = dynamic_cast<To*>(from);
|
||||||
|
return (void*)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function performing casts between smart pointers using dynamic_pointer_cast
|
||||||
|
template<typename SmartPt>
|
||||||
|
boost::any castSmartPtr(const boost::any &ptr) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto from = boost::any_cast<SmartPt>(ptr);
|
||||||
|
auto ret = std::dynamic_pointer_cast<To>(from);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
THROW_FORMAT("Failed cast %s -> %s. Given argument was %s. Error message: %s", typeid(From).name() % typeid(To).name() % ptr.type().name() % e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual boost::any castSharedPtr(const boost::any &ptr) const override
|
||||||
|
{
|
||||||
|
return castSmartPtr<std::shared_ptr<From>>(ptr);
|
||||||
|
}
|
||||||
|
virtual boost::any castWeakPtr(const boost::any &ptr) const override
|
||||||
|
{
|
||||||
|
auto from = boost::any_cast<std::weak_ptr<From>>(ptr);
|
||||||
|
return castSmartPtr<std::shared_ptr<From>>(from.lock());
|
||||||
|
}
|
||||||
|
// virtual boost::any castUniquePtr(const boost::any &ptr) const override
|
||||||
|
// {
|
||||||
|
// return castSmartPtr<std::unique_ptr<From>>(ptr);
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CTypeList
|
class DLL_LINKAGE CTypeList
|
||||||
{
|
{
|
||||||
typedef std::multimap<const std::type_info *,ui16,TypeComparer> TTypeMap;
|
|
||||||
TTypeMap types;
|
|
||||||
public:
|
public:
|
||||||
CTypeList();
|
struct TypeDescriptor;
|
||||||
ui16 registerType(const std::type_info *type);
|
typedef std::shared_ptr<TypeDescriptor> TypeInfoPtr;
|
||||||
template <typename T> ui16 registerType(const T * t = nullptr)
|
struct TypeDescriptor
|
||||||
{
|
{
|
||||||
return registerType(getTypeInfo(t));
|
ui16 typeID;
|
||||||
|
const char *name;
|
||||||
|
std::vector<TypeInfoPtr> children, parents;
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
|
||||||
|
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)
|
||||||
|
|
||||||
|
CTypeList(CTypeList &)
|
||||||
|
{
|
||||||
|
// This type is non-copyable.
|
||||||
|
// Unfortunately on Windows it is required for DLL_EXPORT-ed type to provide copy c-tor, so we can't =delete it.
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
CTypeList &operator=(CTypeList &)
|
||||||
|
{
|
||||||
|
// As above.
|
||||||
|
assert(0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
|
||||||
|
CTypeList();
|
||||||
|
|
||||||
|
TypeInfoPtr registerType(const std::type_info *type);
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Base, typename Derived>
|
||||||
|
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||||
|
{
|
||||||
|
static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
|
||||||
|
static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
|
||||||
|
static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two diffrenet types.");
|
||||||
|
auto bt = getTypeInfo(b), dt = getTypeInfo(d); //obtain std::type_info
|
||||||
|
auto bti = registerType(bt), dti = registerType(dt); //obtain our TypeDescriptor
|
||||||
|
|
||||||
|
// register the relation between classes
|
||||||
|
bti->children.push_back(dti);
|
||||||
|
dti->parents.push_back(bti);
|
||||||
|
casters[std::make_pair(bti, dti)] = make_unique<const PointerCaster<Base, Derived>>();
|
||||||
|
casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui16 getTypeID(const std::type_info *type);
|
ui16 getTypeID(const std::type_info *type);
|
||||||
template <typename T> ui16 getTypeID(const T * t = nullptr)
|
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true); //if not throws, failure returns nullptr
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ui16 getTypeID(const T * t = nullptr)
|
||||||
{
|
{
|
||||||
return getTypeID(getTypeInfo(t));
|
return getTypeID(getTypeInfo(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
|
||||||
|
// Throws if there is no link registered.
|
||||||
|
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to);
|
||||||
|
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
auto typesSequence = castSequence(fromArg, toArg);
|
||||||
|
|
||||||
|
boost::any ptr = inputPtr;
|
||||||
|
for(int i = 0; i < (int)typesSequence.size() - 1; i++)
|
||||||
|
{
|
||||||
|
auto &from = typesSequence[i];
|
||||||
|
auto &to = typesSequence[i + 1];
|
||||||
|
auto castingPair = std::make_pair(from, to);
|
||||||
|
if(!casters.count(castingPair))
|
||||||
|
THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
|
||||||
|
|
||||||
|
auto &caster = casters.at(castingPair);
|
||||||
|
ptr = (*caster.*CastingFunction)(ptr); //Why does unique_ptr does not have operator->* ..?
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TInput>
|
||||||
|
void *castToMostDerived(const TInput *inputPtr)
|
||||||
|
{
|
||||||
|
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||||
|
auto derivedType = getTypeInfo(inputPtr);
|
||||||
|
|
||||||
|
if(baseType == *derivedType)
|
||||||
|
return (void*)inputPtr;
|
||||||
|
|
||||||
|
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>((void*)inputPtr, &baseType, derivedType));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TInput>
|
||||||
|
boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr)
|
||||||
|
{
|
||||||
|
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||||
|
auto derivedType = getTypeInfo(inputPtr.get());
|
||||||
|
|
||||||
|
if(baseType == *derivedType)
|
||||||
|
return inputPtr;
|
||||||
|
|
||||||
|
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to)
|
||||||
|
{
|
||||||
|
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
|
||||||
|
}
|
||||||
|
boost::any castShared(boost::any inputPtr, const std::type_info *from, const std::type_info *to)
|
||||||
|
{
|
||||||
|
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr)
|
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr)
|
||||||
@ -583,10 +734,19 @@ public:
|
|||||||
delete iter->second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void registerType(const T * t=nullptr)
|
template<typename T>
|
||||||
|
void addSaver(const T * t = nullptr)
|
||||||
{
|
{
|
||||||
ui16 ID = typeList.registerType(t);
|
auto ID = typeList.getTypeID(t);
|
||||||
savers[ID] = new CPointerSaver<COSer<Serializer>,T>;
|
if(!savers.count(ID))
|
||||||
|
savers[ID] = new CPointerSaver<COSer<Serializer>, T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename Derived> void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||||
|
{
|
||||||
|
typeList.registerType(b, d);
|
||||||
|
addSaver(b);
|
||||||
|
addSaver(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
Serializer * This()
|
Serializer * This()
|
||||||
@ -650,7 +810,10 @@ public:
|
|||||||
|
|
||||||
if(smartPointerSerialization)
|
if(smartPointerSerialization)
|
||||||
{
|
{
|
||||||
std::map<const void*,ui32>::iterator i = savedPointers.find(data);
|
// We might have an object that has multiple inheritance and store it via the non-first base pointer.
|
||||||
|
// Therefore, all pointers need to be normalized to the actual object address.
|
||||||
|
auto actualPointer = typeList.castToMostDerived(data);
|
||||||
|
std::map<const void*,ui32>::iterator i = savedPointers.find(actualPointer);
|
||||||
if(i != savedPointers.end())
|
if(i != savedPointers.end())
|
||||||
{
|
{
|
||||||
//this pointer has been already serialized - write only it's id
|
//this pointer has been already serialized - write only it's id
|
||||||
@ -660,7 +823,7 @@ public:
|
|||||||
|
|
||||||
//give id to this pointer
|
//give id to this pointer
|
||||||
ui32 pid = (ui32)savedPointers.size();
|
ui32 pid = (ui32)savedPointers.size();
|
||||||
savedPointers[data] = pid;
|
savedPointers[actualPointer] = pid;
|
||||||
*this << pid;
|
*this << pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,7 +841,7 @@ public:
|
|||||||
if(!tid)
|
if(!tid)
|
||||||
*this << *data; //if type is unregistered simply write all data in a standard way
|
*this << *data; //if type is unregistered simply write all data in a standard way
|
||||||
else
|
else
|
||||||
savers[tid]->savePtr(*this,data); //call serializer specific for our real type
|
savers[tid]->savePtr(*this, typeList.castToMostDerived(data)); //call serializer specific for our real type
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -855,24 +1018,44 @@ class DLL_LINKAGE CLoaderBase : public virtual CSerializer
|
|||||||
class CBasicPointerLoader
|
class CBasicPointerLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
|
virtual const type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
|
||||||
virtual ~CBasicPointerLoader(){}
|
virtual ~CBasicPointerLoader(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct ClassObjectCreator
|
||||||
|
{
|
||||||
|
static T *invoke()
|
||||||
|
{
|
||||||
|
static_assert(!typename std::is_abstract<T>::value, "Cannot call new upon abstract classes!");
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ClassObjectCreator<T, typename std::enable_if<std::is_abstract<T>::value>::type>
|
||||||
|
{
|
||||||
|
static T *invoke()
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Something went really wrong during deserialization. Attempted creating an object of an abstract class " + std::string(typeid(T).name()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
|
template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void loadPtr(CLoaderBase &ar, void *data, ui32 pid) const //data is pointer to the ACTUAL POINTER
|
const type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const //data is pointer to the ACTUAL POINTER
|
||||||
{
|
{
|
||||||
Serializer &s = static_cast<Serializer&>(ar);
|
Serializer &s = static_cast<Serializer&>(ar);
|
||||||
T *&ptr = *static_cast<T**>(data);
|
T *&ptr = *static_cast<T**>(data);
|
||||||
|
|
||||||
//create new object under pointer
|
//create new object under pointer
|
||||||
typedef typename boost::remove_pointer<T>::type npT;
|
typedef typename boost::remove_pointer<T>::type npT;
|
||||||
ptr = new npT;
|
ptr = ClassObjectCreator<npT>::invoke(); //does new npT or throws for abstract classes
|
||||||
s.ptrAllocated(ptr, pid);
|
s.ptrAllocated(ptr, pid);
|
||||||
//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
|
||||||
ptr->serialize(s,version);
|
ptr->serialize(s,version);
|
||||||
|
return &typeid(T);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -882,10 +1065,11 @@ template <typename Serializer> class DLL_LINKAGE CISer : public CLoaderBase
|
|||||||
public:
|
public:
|
||||||
bool saving;
|
bool saving;
|
||||||
std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
|
std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
|
||||||
ui32 fileVersion;
|
si32 fileVersion;
|
||||||
bool reverseEndianess; //if source has different endianess than us, we reverse bytes
|
bool reverseEndianess; //if source has different endianess than us, we reverse bytes
|
||||||
|
|
||||||
std::map<ui32, void*> loadedPointers;
|
std::map<ui32, void*> loadedPointers;
|
||||||
|
std::map<ui32, const std::type_info*> loadedPointersTypes;
|
||||||
std::map<const void*, boost::any> loadedSharedPointers;
|
std::map<const void*, boost::any> loadedSharedPointers;
|
||||||
|
|
||||||
bool smartPointerSerialization;
|
bool smartPointerSerialization;
|
||||||
@ -906,10 +1090,19 @@ public:
|
|||||||
delete iter->second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void registerType(const T * t=nullptr)
|
template<typename T>
|
||||||
|
void addLoader(const T * t = nullptr)
|
||||||
{
|
{
|
||||||
ui16 ID = typeList.registerType(t);
|
auto ID = typeList.getTypeID(t);
|
||||||
loaders[ID] = new CPointerLoader<CISer<Serializer>,T>;
|
if(!loaders.count(ID))
|
||||||
|
loaders[ID] = new CPointerLoader<CISer<Serializer>, T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename Derived> void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||||
|
{
|
||||||
|
typeList.registerType(b, d);
|
||||||
|
addLoader(b);
|
||||||
|
addLoader(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
Serializer * This()
|
Serializer * This()
|
||||||
@ -1049,8 +1242,10 @@ public:
|
|||||||
|
|
||||||
if(i != loadedPointers.end())
|
if(i != loadedPointers.end())
|
||||||
{
|
{
|
||||||
//we already got this pointer
|
// We already got this pointer
|
||||||
data = static_cast<T>(i->second);
|
// Cast it in case we are loading it to a non-first base pointer
|
||||||
|
assert(loadedPointersTypes.count(pid));
|
||||||
|
data = reinterpret_cast<T>(typeList.castRaw(i->second, loadedPointersTypes.at(pid), &typeid(typename boost::remove_const<typename boost::remove_pointer<T>::type>::type)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1069,13 +1264,14 @@ public:
|
|||||||
{
|
{
|
||||||
typedef typename boost::remove_pointer<T>::type npT;
|
typedef typename boost::remove_pointer<T>::type npT;
|
||||||
typedef typename boost::remove_const<npT>::type ncpT;
|
typedef typename boost::remove_const<npT>::type ncpT;
|
||||||
data = new ncpT;
|
data = ClassObjectCreator<ncpT>::invoke();
|
||||||
ptrAllocated(data, pid);
|
ptrAllocated(data, pid);
|
||||||
*this >> *data;
|
*this >> *data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loaders[tid]->loadPtr(*this,&data, pid);
|
auto typeInfo = loaders[tid]->loadPtr(*this,&data, pid);
|
||||||
|
data = reinterpret_cast<T>(typeList.castRaw((void*)data, typeInfo, &typeid(typename boost::remove_const<typename boost::remove_pointer<T>::type>::type)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1083,7 +1279,10 @@ public:
|
|||||||
void ptrAllocated(const T *ptr, ui32 pid)
|
void ptrAllocated(const T *ptr, ui32 pid)
|
||||||
{
|
{
|
||||||
if(smartPointerSerialization && pid != 0xffffffff)
|
if(smartPointerSerialization && pid != 0xffffffff)
|
||||||
|
{
|
||||||
|
loadedPointersTypes[pid] = &typeid(T);
|
||||||
loadedPointers[pid] = (void*)ptr; //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
|
loadedPointers[pid] = (void*)ptr; //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define READ_CHECK_U32(x) \
|
#define READ_CHECK_U32(x) \
|
||||||
@ -1099,19 +1298,34 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void loadSerializable(shared_ptr<T> &data)
|
void loadSerializable(shared_ptr<T> &data)
|
||||||
{
|
{
|
||||||
T *internalPtr;
|
typedef typename boost::remove_const<T>::type NonConstT;
|
||||||
|
NonConstT *internalPtr;
|
||||||
*this >> internalPtr;
|
*this >> internalPtr;
|
||||||
|
|
||||||
|
void *internalPtrDerived = typeList.castToMostDerived(internalPtr);
|
||||||
|
|
||||||
if(internalPtr)
|
if(internalPtr)
|
||||||
{
|
{
|
||||||
auto itr = loadedSharedPointers.find(internalPtr);
|
auto itr = loadedSharedPointers.find(internalPtrDerived);
|
||||||
if(itr != loadedSharedPointers.end())
|
if(itr != loadedSharedPointers.end())
|
||||||
{
|
{
|
||||||
// This pointers is already loaded. The "data" needs to be pointed to it,
|
// This pointers is already loaded. The "data" needs to be pointed to it,
|
||||||
// so their shared state is actually shared.
|
// so their shared state is actually shared.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
data = boost::any_cast<std::shared_ptr<T>>(itr->second);
|
auto actualType = typeList.getTypeInfo(internalPtr);
|
||||||
|
auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
|
||||||
|
if(*actualType == *typeWeNeedToReturn)
|
||||||
|
{
|
||||||
|
// No casting needed, just unpack already stored shared_ptr and return it
|
||||||
|
data = boost::any_cast<std::shared_ptr<T>>(itr->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We need to perform series of casts
|
||||||
|
auto ret = typeList.castShared(itr->second, actualType, typeWeNeedToReturn);
|
||||||
|
data = boost::any_cast<std::shared_ptr<T>>(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
@ -1124,8 +1338,9 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data = std::shared_ptr<T>(internalPtr);
|
auto hlp = std::shared_ptr<NonConstT>(internalPtr);
|
||||||
loadedSharedPointers[internalPtr] = data;
|
data = hlp; //possibly adds const
|
||||||
|
loadedSharedPointers[internalPtrDerived] = typeList.castSharedToMostDerived(hlp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1435,10 +1650,20 @@ public:
|
|||||||
for(iter = apps.begin(); iter != apps.end(); iter++)
|
for(iter = apps.begin(); iter != apps.end(); iter++)
|
||||||
delete iter->second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
template<typename U> void registerType(const U * t=nullptr)
|
|
||||||
|
template<typename RegisteredType>
|
||||||
|
void addApplier(ui16 ID)
|
||||||
{
|
{
|
||||||
ui16 ID = typeList.registerType(t);
|
if(!apps.count(ID))
|
||||||
apps[ID] = T::getApplier(t);
|
apps[ID] = T::getApplier<RegisteredType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Base, typename Derived>
|
||||||
|
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||||
|
{
|
||||||
|
typeList.registerType(b, d);
|
||||||
|
addApplier<Base>(typeList.getTypeID(b));
|
||||||
|
addApplier<Derived>(typeList.getTypeID(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -47,9 +47,9 @@ struct CPackForClient : public CPack
|
|||||||
|
|
||||||
CGameState* GS(CClient *cl);
|
CGameState* GS(CClient *cl);
|
||||||
void applyFirstCl(CClient *cl)//called before applying to gs
|
void applyFirstCl(CClient *cl)//called before applying to gs
|
||||||
{};
|
{}
|
||||||
void applyCl(CClient *cl)//called after applying to gs
|
void applyCl(CClient *cl)//called after applying to gs
|
||||||
{};
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CPackForServer : public CPack
|
struct CPackForServer : public CPack
|
||||||
@ -64,7 +64,11 @@ struct CPackForServer : public CPack
|
|||||||
type = 2;
|
type = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool applyGh(CGameHandler *gh);//called after applying to gs
|
bool applyGh(CGameHandler *gh) //called after applying to gs
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Should not happen... applying plain CPackForServer";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,237 +23,268 @@
|
|||||||
template<typename Serializer>
|
template<typename Serializer>
|
||||||
void registerTypes1(Serializer &s)
|
void registerTypes1(Serializer &s)
|
||||||
{
|
{
|
||||||
//map objects
|
//////////////////////////////////////////////////////////////////////////
|
||||||
s.template registerType<CGHeroPlaceholder>();
|
// Adventure map objects (and related)
|
||||||
s.template registerType<CGHeroInstance>();
|
//////////////////////////////////////////////////////////////////////////
|
||||||
s.template registerType<CGTownInstance>();
|
s.template registerType<IObjectInterface, CGObjectInstance>();
|
||||||
s.template registerType<CTownBonus>();
|
|
||||||
s.template registerType<CGPandoraBox>();
|
// Non-armed objects
|
||||||
s.template registerType<CGEvent>();
|
s.template registerType<CGObjectInstance, CGTeleport>();
|
||||||
s.template registerType<CGDwelling>();
|
s.template registerType<CGObjectInstance, CGPickable>();
|
||||||
s.template registerType<CGVisitableOPH>();
|
s.template registerType<CGObjectInstance, CGSignBottle>();
|
||||||
s.template registerType<CGVisitableOPW>();
|
s.template registerType<CGObjectInstance, CGScholar>();
|
||||||
s.template registerType<CGTeleport>();
|
s.template registerType<CGObjectInstance, CGBonusingObject>();
|
||||||
s.template registerType<CGPickable>();
|
s.template registerType<CGObjectInstance, CGMagicWell>();
|
||||||
s.template registerType<CGCreature>();
|
s.template registerType<CGObjectInstance, CGObservatory>();
|
||||||
s.template registerType<CGSignBottle>();
|
s.template registerType<CGObjectInstance, CGKeys>();
|
||||||
s.template registerType<CQuest>();
|
s.template registerType<CGKeys, CGKeymasterTent>();
|
||||||
s.template registerType<IQuestObject>();
|
s.template registerType<CGKeys, CGBorderGuard>(); s.template registerType<IQuestObject, CGBorderGuard>();
|
||||||
s.template registerType<CGSeerHut>();
|
s.template registerType<CGBorderGuard, CGBorderGate>();
|
||||||
s.template registerType<CGQuestGuard>();
|
s.template registerType<CGObjectInstance, CGBoat>();
|
||||||
s.template registerType<CGWitchHut>();
|
s.template registerType<CGObjectInstance, CGMagi>();
|
||||||
s.template registerType<CGScholar>();
|
s.template registerType<CGObjectInstance, CGSirens>();
|
||||||
s.template registerType<CGGarrison>();
|
s.template registerType<CGObjectInstance, CGShipyard>(); s.template registerType<IShipyard, CGShipyard>();
|
||||||
s.template registerType<CGArtifact>();
|
s.template registerType<CGObjectInstance, CGDenOfthieves>();
|
||||||
s.template registerType<CGResource>();
|
s.template registerType<CGObjectInstance, CGLighthouse>();
|
||||||
s.template registerType<CGMine>();
|
s.template registerType<CGObjectInstance, CGMarket>(); s.template registerType<IMarket, CGMarket>();
|
||||||
s.template registerType<CGShrine>();
|
s.template registerType<CGMarket, CGBlackMarket>();
|
||||||
s.template registerType<CGBonusingObject>();
|
s.template registerType<CGMarket, CGUniversity>();
|
||||||
s.template registerType<CGMagicSpring>();
|
s.template registerType<CGObjectInstance, CGHeroPlaceholder>();
|
||||||
s.template registerType<CGMagicWell>();
|
|
||||||
s.template registerType<CGObservatory>();
|
s.template registerType<CGObjectInstance, CArmedInstance>(); s.template registerType<CBonusSystemNode, CArmedInstance>(); s.template registerType<CCreatureSet, CArmedInstance>();
|
||||||
s.template registerType<CGKeys>();
|
|
||||||
s.template registerType<CGKeymasterTent>();
|
// Armed objects
|
||||||
s.template registerType<CGBorderGuard>();
|
s.template registerType<CArmedInstance, CGHeroInstance>(); s.template registerType<IBoatGenerator, CGHeroInstance>(); s.template registerType<CArtifactSet, CGHeroInstance>();
|
||||||
s.template registerType<CGBorderGate>();
|
s.template registerType<CArmedInstance, CGDwelling>();
|
||||||
s.template registerType<CGBoat>();
|
s.template registerType<CGDwelling, CGTownInstance>(); s.template registerType<IShipyard, CGTownInstance>(); s.template registerType<IMarket, CGTownInstance>();
|
||||||
s.template registerType<CGMagi>();
|
s.template registerType<CArmedInstance, CGPandoraBox>();
|
||||||
s.template registerType<CGSirens>();
|
s.template registerType<CGPandoraBox, CGEvent>();
|
||||||
s.template registerType<CGOnceVisitable>();
|
s.template registerType<CArmedInstance, CGCreature>();
|
||||||
s.template registerType<CBank>();
|
s.template registerType<CArmedInstance, CGGarrison>();
|
||||||
s.template registerType<CGPyramid>();
|
s.template registerType<CArmedInstance, CGArtifact>();
|
||||||
s.template registerType<CGShipyard>();
|
s.template registerType<CArmedInstance, CGResource>();
|
||||||
s.template registerType<CCartographer>();
|
s.template registerType<CArmedInstance, CGMine>();
|
||||||
s.template registerType<CGObjectInstance>();
|
s.template registerType<CArmedInstance, CBank>();
|
||||||
s.template registerType<COPWBonus>();
|
s.template registerType<CBank, CGPyramid>();
|
||||||
s.template registerType<CGDenOfthieves>();
|
s.template registerType<CArmedInstance, CGSeerHut>(); s.template registerType<IQuestObject, CGSeerHut>();
|
||||||
s.template registerType<CGObelisk>();
|
s.template registerType<CGSeerHut, CGQuestGuard>();
|
||||||
s.template registerType<CGLighthouse>();
|
|
||||||
s.template registerType<CGMarket>();
|
|
||||||
s.template registerType<CGBlackMarket>();
|
//Other object-related
|
||||||
s.template registerType<CGUniversity>();
|
s.template registerType<IObjectInterface, CGTownBuilding>();
|
||||||
|
s.template registerType<CGTownBuilding, CTownBonus>();
|
||||||
|
s.template registerType<CGTownBuilding, COPWBonus>();
|
||||||
|
|
||||||
|
|
||||||
|
s.template registerType<CGObjectInstance, CGVisitableOPH>();
|
||||||
|
|
||||||
|
s.template registerType<CGObjectInstance, CGVisitableOPW>();
|
||||||
|
s.template registerType<CGVisitableOPW, CGMagicSpring>();
|
||||||
|
|
||||||
|
s.template registerType<CGObjectInstance, CPlayersVisited>();
|
||||||
|
s.template registerType<CPlayersVisited, CGWitchHut>();
|
||||||
|
s.template registerType<CPlayersVisited, CGShrine>();
|
||||||
|
s.template registerType<CPlayersVisited, CGOnceVisitable>();
|
||||||
|
s.template registerType<CPlayersVisited, CCartographer>();
|
||||||
|
s.template registerType<CPlayersVisited, CGObelisk>();
|
||||||
|
|
||||||
|
//s.template registerType<CQuest>();
|
||||||
|
//s.template registerType<IQuestObject>();
|
||||||
|
|
||||||
//end of objects
|
//end of objects
|
||||||
s.template registerType<IPropagator>();
|
|
||||||
s.template registerType<CPropagatorNodeType>();
|
|
||||||
|
|
||||||
s.template registerType<ILimiter>();
|
//////////////////////////////////////////////////////////////////////////
|
||||||
s.template registerType<LimiterList>();
|
// Bonus system
|
||||||
s.template registerType<CCreatureTypeLimiter>();
|
//////////////////////////////////////////////////////////////////////////
|
||||||
s.template registerType<HasAnotherBonusLimiter>();
|
//s.template registerType<IPropagator>();
|
||||||
s.template registerType<CreatureNativeTerrainLimiter>();
|
s.template registerType<IPropagator, CPropagatorNodeType>();
|
||||||
s.template registerType<CreatureFactionLimiter>();
|
|
||||||
s.template registerType<CreatureAlignmentLimiter>();
|
|
||||||
s.template registerType<RankRangeLimiter>();
|
|
||||||
s.template registerType<StackOwnerLimiter>();
|
|
||||||
|
|
||||||
s.template registerType<CModInfo>();
|
// Limiters
|
||||||
|
//s.template registerType<ILimiter>();
|
||||||
|
s.template registerType<ILimiter, LimiterList>();
|
||||||
|
s.template registerType<ILimiter, CCreatureTypeLimiter>();
|
||||||
|
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
|
||||||
|
s.template registerType<ILimiter, CreatureNativeTerrainLimiter>();
|
||||||
|
s.template registerType<ILimiter, CreatureFactionLimiter>();
|
||||||
|
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
|
||||||
|
s.template registerType<ILimiter, RankRangeLimiter>();
|
||||||
|
s.template registerType<ILimiter, StackOwnerLimiter>();
|
||||||
|
|
||||||
|
// s.template registerType<CBonusSystemNode>();
|
||||||
|
s.template registerType<CBonusSystemNode, CArtifact>();
|
||||||
|
s.template registerType<CArtifact, CGrowingArtifact>();
|
||||||
|
s.template registerType<CBonusSystemNode, CCreature>();
|
||||||
|
s.template registerType<CBonusSystemNode, CStackInstance>();
|
||||||
|
s.template registerType<CStackInstance, CCommanderInstance>();
|
||||||
|
s.template registerType<CBonusSystemNode, PlayerState>();
|
||||||
|
s.template registerType<CBonusSystemNode, TeamState>();
|
||||||
|
//s.template registerType<CGameState>(); //TODO
|
||||||
|
s.template registerType<CBonusSystemNode, CGHeroInstance::HeroSpecial>();
|
||||||
|
//s.template registerType<CArmedInstance>();
|
||||||
|
s.template registerType<CBonusSystemNode, CStack>();
|
||||||
|
s.template registerType<CBonusSystemNode, BattleInfo>();
|
||||||
|
//s.template registerType<QuestInfo>();
|
||||||
|
s.template registerType<CBonusSystemNode, CArtifactInstance>();
|
||||||
|
s.template registerType<CArtifactInstance, CCombinedArtifactInstance>();
|
||||||
|
|
||||||
s.template registerType<CBonusSystemNode>();
|
//s.template registerType<CObstacleInstance>();
|
||||||
s.template registerType<CArtifact>();
|
s.template registerType<CObstacleInstance, MoatObstacle>();
|
||||||
s.template registerType<CGrowingArtifact>();
|
s.template registerType<CObstacleInstance, SpellCreatedObstacle>();
|
||||||
s.template registerType<CCreature>();
|
|
||||||
s.template registerType<CStackInstance>();
|
|
||||||
s.template registerType<CCommanderInstance>();
|
|
||||||
s.template registerType<PlayerState>();
|
|
||||||
s.template registerType<TeamState>();
|
|
||||||
s.template registerType<CGameState>();
|
|
||||||
s.template registerType<CGHeroInstance::HeroSpecial>();
|
|
||||||
s.template registerType<CArmedInstance>();
|
|
||||||
s.template registerType<CStack>();
|
|
||||||
s.template registerType<BattleInfo>();
|
|
||||||
s.template registerType<QuestInfo>();
|
|
||||||
s.template registerType<CArtifactInstance>();
|
|
||||||
s.template registerType<CCombinedArtifactInstance>();
|
|
||||||
|
|
||||||
s.template registerType<CObstacleInstance>();
|
|
||||||
s.template registerType<MoatObstacle>();
|
|
||||||
s.template registerType<SpellCreatedObstacle>();
|
|
||||||
|
|
||||||
//s.template registerType<CCreatureArtifactInstance>();
|
|
||||||
//s.template registerType<ArtSlotInfo>();
|
|
||||||
//s.template registerType<ArtifactLocation>();
|
|
||||||
//s.template registerType<StackLocation>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Serializer>
|
template<typename Serializer>
|
||||||
void registerTypes2(Serializer &s)
|
void registerTypes2(Serializer &s)
|
||||||
{
|
{
|
||||||
s.template registerType<PackageApplied>();
|
s.template registerType<CPack, CPackForClient>();
|
||||||
s.template registerType<SystemMessage>();
|
|
||||||
s.template registerType<PlayerBlocked>();
|
|
||||||
s.template registerType<YourTurn>();
|
|
||||||
s.template registerType<SetResource>();
|
|
||||||
s.template registerType<SetResources>();
|
|
||||||
s.template registerType<SetPrimSkill>();
|
|
||||||
s.template registerType<SetSecSkill>();
|
|
||||||
s.template registerType<HeroVisitCastle>();
|
|
||||||
s.template registerType<ChangeSpells>();
|
|
||||||
s.template registerType<SetMana>();
|
|
||||||
s.template registerType<SetMovePoints>();
|
|
||||||
s.template registerType<FoWChange>();
|
|
||||||
s.template registerType<SetAvailableHeroes>();
|
|
||||||
s.template registerType<GiveBonus>();
|
|
||||||
s.template registerType<ChangeObjPos>();
|
|
||||||
s.template registerType<PlayerEndsGame>();
|
|
||||||
s.template registerType<RemoveBonus>();
|
|
||||||
s.template registerType<UpdateCampaignState>();
|
|
||||||
s.template registerType<PrepareForAdvancingCampaign>();
|
|
||||||
s.template registerType<UpdateArtHandlerLists>();
|
|
||||||
s.template registerType<UpdateMapEvents>();
|
|
||||||
s.template registerType<UpdateCastleEvents>();
|
|
||||||
s.template registerType<RemoveObject>();
|
|
||||||
s.template registerType<TryMoveHero>();
|
|
||||||
//s.template registerType<SetGarrisons>();
|
|
||||||
s.template registerType<NewStructures>();
|
|
||||||
s.template registerType<RazeStructures>();
|
|
||||||
s.template registerType<SetAvailableCreatures>();
|
|
||||||
s.template registerType<SetHeroesInTown>();
|
|
||||||
//s.template registerType<SetHeroArtifacts>();
|
|
||||||
s.template registerType<HeroRecruited>();
|
|
||||||
s.template registerType<GiveHero>();
|
|
||||||
s.template registerType<NewTurn>();
|
|
||||||
s.template registerType<InfoWindow>();
|
|
||||||
s.template registerType<SetObjectProperty>();
|
|
||||||
s.template registerType<SetHoverName>();
|
|
||||||
s.template registerType<HeroLevelUp>();
|
|
||||||
s.template registerType<CommanderLevelUp>();
|
|
||||||
s.template registerType<SetCommanderProperty>();
|
|
||||||
s.template registerType<BlockingDialog>();
|
|
||||||
s.template registerType<GarrisonDialog>();
|
|
||||||
s.template registerType<ExchangeDialog>();
|
|
||||||
s.template registerType<BattleStart>();
|
|
||||||
s.template registerType<BattleNextRound>();
|
|
||||||
s.template registerType<BattleSetActiveStack>();
|
|
||||||
s.template registerType<BattleResult>();
|
|
||||||
s.template registerType<BattleStackMoved>();
|
|
||||||
s.template registerType<BattleStackAttacked>();
|
|
||||||
s.template registerType<BattleAttack>();
|
|
||||||
s.template registerType<StartAction>();
|
|
||||||
s.template registerType<EndAction>();
|
|
||||||
s.template registerType<BattleSpellCast>();
|
|
||||||
s.template registerType<SetStackEffect>();
|
|
||||||
s.template registerType<BattleTriggerEffect>();
|
|
||||||
s.template registerType<BattleObstaclePlaced>();
|
|
||||||
s.template registerType<BattleSetStackProperty>();
|
|
||||||
s.template registerType<StacksInjured>();
|
|
||||||
s.template registerType<BattleResultsApplied>();
|
|
||||||
s.template registerType<StacksHealedOrResurrected>();
|
|
||||||
s.template registerType<ObstaclesRemoved>();
|
|
||||||
s.template registerType<CatapultAttack>();
|
|
||||||
s.template registerType<BattleStacksRemoved>();
|
|
||||||
s.template registerType<BattleStackAdded>();
|
|
||||||
s.template registerType<ShowInInfobox>();
|
|
||||||
s.template registerType<AdvmapSpellCast>();
|
|
||||||
s.template registerType<OpenWindow>();
|
|
||||||
s.template registerType<NewObject>();
|
|
||||||
s.template registerType<NewArtifact>();
|
|
||||||
s.template registerType<AddQuest>();
|
|
||||||
s.template registerType<ChangeStackCount>();
|
|
||||||
s.template registerType<SetStackType>();
|
|
||||||
s.template registerType<EraseStack>();
|
|
||||||
s.template registerType<SwapStacks>();
|
|
||||||
s.template registerType<InsertNewStack>();
|
|
||||||
s.template registerType<RebalanceStacks>();
|
|
||||||
s.template registerType<SetAvailableArtifacts>();
|
|
||||||
s.template registerType<PutArtifact>();
|
|
||||||
s.template registerType<EraseArtifact>();
|
|
||||||
s.template registerType<MoveArtifact>();
|
|
||||||
s.template registerType<AssembledArtifact>();
|
|
||||||
s.template registerType<DisassembledArtifact>();
|
|
||||||
s.template registerType<HeroVisit>();
|
|
||||||
|
|
||||||
s.template registerType<SaveGame>();
|
s.template registerType<CPackForClient, PackageApplied>();
|
||||||
s.template registerType<SetSelection>();
|
s.template registerType<CPackForClient, SystemMessage>();
|
||||||
s.template registerType<PlayerMessage>();
|
s.template registerType<CPackForClient, PlayerBlocked>();
|
||||||
s.template registerType<CenterView>();
|
s.template registerType<CPackForClient, YourTurn>();
|
||||||
|
s.template registerType<CPackForClient, SetResource>();
|
||||||
|
s.template registerType<CPackForClient, SetResources>();
|
||||||
|
s.template registerType<CPackForClient, SetPrimSkill>();
|
||||||
|
s.template registerType<CPackForClient, SetSecSkill>();
|
||||||
|
s.template registerType<CPackForClient, HeroVisitCastle>();
|
||||||
|
s.template registerType<CPackForClient, ChangeSpells>();
|
||||||
|
s.template registerType<CPackForClient, SetMana>();
|
||||||
|
s.template registerType<CPackForClient, SetMovePoints>();
|
||||||
|
s.template registerType<CPackForClient, FoWChange>();
|
||||||
|
s.template registerType<CPackForClient, SetAvailableHeroes>();
|
||||||
|
s.template registerType<CPackForClient, GiveBonus>();
|
||||||
|
s.template registerType<CPackForClient, ChangeObjPos>();
|
||||||
|
s.template registerType<CPackForClient, PlayerEndsGame>();
|
||||||
|
s.template registerType<CPackForClient, RemoveBonus>();
|
||||||
|
s.template registerType<CPackForClient, UpdateCampaignState>();
|
||||||
|
s.template registerType<CPackForClient, PrepareForAdvancingCampaign>();
|
||||||
|
s.template registerType<CPackForClient, UpdateArtHandlerLists>();
|
||||||
|
s.template registerType<CPackForClient, UpdateMapEvents>();
|
||||||
|
s.template registerType<CPackForClient, UpdateCastleEvents>();
|
||||||
|
s.template registerType<CPackForClient, RemoveObject>();
|
||||||
|
s.template registerType<CPackForClient, TryMoveHero>();
|
||||||
|
//s.template registerType<CPackForClient, SetGarrisons>();
|
||||||
|
s.template registerType<CPackForClient, NewStructures>();
|
||||||
|
s.template registerType<CPackForClient, RazeStructures>();
|
||||||
|
s.template registerType<CPackForClient, SetAvailableCreatures>();
|
||||||
|
s.template registerType<CPackForClient, SetHeroesInTown>();
|
||||||
|
//s.template registerType<CPackForClient, SetHeroArtifacts>();
|
||||||
|
s.template registerType<CPackForClient, HeroRecruited>();
|
||||||
|
s.template registerType<CPackForClient, GiveHero>();
|
||||||
|
s.template registerType<CPackForClient, NewTurn>();
|
||||||
|
s.template registerType<CPackForClient, InfoWindow>();
|
||||||
|
s.template registerType<CPackForClient, SetObjectProperty>();
|
||||||
|
s.template registerType<CPackForClient, SetHoverName>();
|
||||||
|
s.template registerType<CPackForClient, BattleStart>();
|
||||||
|
s.template registerType<CPackForClient, BattleNextRound>();
|
||||||
|
s.template registerType<CPackForClient, BattleSetActiveStack>();
|
||||||
|
s.template registerType<CPackForClient, BattleResult>();
|
||||||
|
s.template registerType<CPackForClient, BattleStackMoved>();
|
||||||
|
s.template registerType<CPackForClient, BattleStackAttacked>();
|
||||||
|
s.template registerType<CPackForClient, BattleAttack>();
|
||||||
|
s.template registerType<CPackForClient, StartAction>();
|
||||||
|
s.template registerType<CPackForClient, EndAction>();
|
||||||
|
s.template registerType<CPackForClient, BattleSpellCast>();
|
||||||
|
s.template registerType<CPackForClient, SetStackEffect>();
|
||||||
|
s.template registerType<CPackForClient, BattleTriggerEffect>();
|
||||||
|
s.template registerType<CPackForClient, BattleObstaclePlaced>();
|
||||||
|
s.template registerType<CPackForClient, BattleSetStackProperty>();
|
||||||
|
s.template registerType<CPackForClient, StacksInjured>();
|
||||||
|
s.template registerType<CPackForClient, BattleResultsApplied>();
|
||||||
|
s.template registerType<CPackForClient, StacksHealedOrResurrected>();
|
||||||
|
s.template registerType<CPackForClient, ObstaclesRemoved>();
|
||||||
|
s.template registerType<CPackForClient, CatapultAttack>();
|
||||||
|
s.template registerType<CPackForClient, BattleStacksRemoved>();
|
||||||
|
s.template registerType<CPackForClient, BattleStackAdded>();
|
||||||
|
s.template registerType<CPackForClient, ShowInInfobox>();
|
||||||
|
s.template registerType<CPackForClient, AdvmapSpellCast>();
|
||||||
|
s.template registerType<CPackForClient, OpenWindow>();
|
||||||
|
s.template registerType<CPackForClient, NewObject>();
|
||||||
|
s.template registerType<CPackForClient, NewArtifact>();
|
||||||
|
s.template registerType<CPackForClient, AddQuest>();
|
||||||
|
s.template registerType<CPackForClient, SetAvailableArtifacts>();
|
||||||
|
s.template registerType<CPackForClient, CenterView>();
|
||||||
|
s.template registerType<CPackForClient, HeroVisit>();
|
||||||
|
s.template registerType<CPackForClient, SetCommanderProperty>();
|
||||||
|
|
||||||
|
s.template registerType<CPackForClient, Query>();
|
||||||
|
s.template registerType<Query, HeroLevelUp>();
|
||||||
|
s.template registerType<Query, CommanderLevelUp>();
|
||||||
|
s.template registerType<Query, BlockingDialog>();
|
||||||
|
s.template registerType<Query, GarrisonDialog>();
|
||||||
|
s.template registerType<Query, ExchangeDialog>();
|
||||||
|
|
||||||
|
s.template registerType<CPackForClient, CGarrisonOperationPack>();
|
||||||
|
s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
|
||||||
|
s.template registerType<CGarrisonOperationPack, SetStackType>();
|
||||||
|
s.template registerType<CGarrisonOperationPack, EraseStack>();
|
||||||
|
s.template registerType<CGarrisonOperationPack, SwapStacks>();
|
||||||
|
s.template registerType<CGarrisonOperationPack, InsertNewStack>();
|
||||||
|
s.template registerType<CGarrisonOperationPack, RebalanceStacks>();
|
||||||
|
|
||||||
|
s.template registerType<CPackForClient, CArtifactOperationPack>();
|
||||||
|
s.template registerType<CArtifactOperationPack, PutArtifact>();
|
||||||
|
s.template registerType<CArtifactOperationPack, EraseArtifact>();
|
||||||
|
s.template registerType<CArtifactOperationPack, MoveArtifact>();
|
||||||
|
s.template registerType<CArtifactOperationPack, AssembledArtifact>();
|
||||||
|
s.template registerType<CArtifactOperationPack, DisassembledArtifact>();
|
||||||
|
|
||||||
|
s.template registerType<CPackForClient, SaveGame>();
|
||||||
|
s.template registerType<CPackForClient, SetSelection>();
|
||||||
|
s.template registerType<CPackForClient, PlayerMessage>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Serializer>
|
template<typename Serializer>
|
||||||
void registerTypes3(Serializer &s)
|
void registerTypes3(Serializer &s)
|
||||||
{
|
{
|
||||||
s.template registerType<CloseServer>();
|
s.template registerType<CPack, CPackForServer>();
|
||||||
s.template registerType<EndTurn>();
|
s.template registerType<CPackForServer, CloseServer>();
|
||||||
s.template registerType<DismissHero>();
|
s.template registerType<CPackForServer, EndTurn>();
|
||||||
s.template registerType<MoveHero>();
|
s.template registerType<CPackForServer, DismissHero>();
|
||||||
s.template registerType<ArrangeStacks>();
|
s.template registerType<CPackForServer, MoveHero>();
|
||||||
s.template registerType<DisbandCreature>();
|
s.template registerType<CPackForServer, ArrangeStacks>();
|
||||||
s.template registerType<BuildStructure>();
|
s.template registerType<CPackForServer, DisbandCreature>();
|
||||||
s.template registerType<RecruitCreatures>();
|
s.template registerType<CPackForServer, BuildStructure>();
|
||||||
s.template registerType<UpgradeCreature>();
|
s.template registerType<CPackForServer, RecruitCreatures>();
|
||||||
s.template registerType<GarrisonHeroSwap>();
|
s.template registerType<CPackForServer, UpgradeCreature>();
|
||||||
s.template registerType<ExchangeArtifacts>();
|
s.template registerType<CPackForServer, GarrisonHeroSwap>();
|
||||||
s.template registerType<AssembleArtifacts>();
|
s.template registerType<CPackForServer, ExchangeArtifacts>();
|
||||||
s.template registerType<BuyArtifact>();
|
s.template registerType<CPackForServer, AssembleArtifacts>();
|
||||||
s.template registerType<TradeOnMarketplace>();
|
s.template registerType<CPackForServer, BuyArtifact>();
|
||||||
s.template registerType<SetFormation>();
|
s.template registerType<CPackForServer, TradeOnMarketplace>();
|
||||||
s.template registerType<HireHero>();
|
s.template registerType<CPackForServer, SetFormation>();
|
||||||
s.template registerType<BuildBoat>();
|
s.template registerType<CPackForServer, HireHero>();
|
||||||
s.template registerType<QueryReply>();
|
s.template registerType<CPackForServer, BuildBoat>();
|
||||||
s.template registerType<MakeAction>();
|
s.template registerType<CPackForServer, QueryReply>();
|
||||||
s.template registerType<MakeCustomAction>();
|
s.template registerType<CPackForServer, MakeAction>();
|
||||||
s.template registerType<DigWithHero>();
|
s.template registerType<CPackForServer, MakeCustomAction>();
|
||||||
s.template registerType<CastAdvSpell>();
|
s.template registerType<CPackForServer, DigWithHero>();
|
||||||
s.template registerType<CastleTeleportHero>();
|
s.template registerType<CPackForServer, CastAdvSpell>();
|
||||||
|
s.template registerType<CPackForServer, CastleTeleportHero>();
|
||||||
|
s.template registerType<CPackForServer, CommitPackage>();
|
||||||
|
|
||||||
s.template registerType<SaveGame>();
|
s.template registerType<CPackForServer, SaveGame>();
|
||||||
s.template registerType<CommitPackage>();
|
s.template registerType<CPackForServer, SetSelection>();
|
||||||
s.template registerType<SetSelection>();
|
s.template registerType<CPackForServer, PlayerMessage>();
|
||||||
s.template registerType<PlayerMessage>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Serializer>
|
template<typename Serializer>
|
||||||
void registerTypes4(Serializer &s)
|
void registerTypes4(Serializer &s)
|
||||||
{
|
{
|
||||||
s.template registerType<ChatMessage>();
|
s.template registerType<CPack, CPackForSelectionScreen>();
|
||||||
s.template registerType<QuitMenuWithoutStarting>();
|
s.template registerType<CPackForSelectionScreen, CPregamePackToPropagate>();
|
||||||
s.template registerType<PlayerJoined>();
|
s.template registerType<CPackForSelectionScreen, CPregamePackToHost>();
|
||||||
s.template registerType<SelectMap>();
|
|
||||||
s.template registerType<UpdateStartOptions>();
|
s.template registerType<CPregamePackToPropagate, ChatMessage>();
|
||||||
s.template registerType<PregameGuiAction>();
|
s.template registerType<CPregamePackToPropagate, QuitMenuWithoutStarting>();
|
||||||
s.template registerType<RequestOptionsChange>();
|
s.template registerType<CPregamePackToPropagate, SelectMap>();
|
||||||
s.template registerType<PlayerLeft>();
|
s.template registerType<CPregamePackToPropagate, UpdateStartOptions>();
|
||||||
s.template registerType<PlayersNames>();
|
s.template registerType<CPregamePackToPropagate, PregameGuiAction>();
|
||||||
s.template registerType<StartWithCurrentSettings>();
|
s.template registerType<CPregamePackToPropagate, PlayerLeft>();
|
||||||
|
s.template registerType<CPregamePackToPropagate, PlayersNames>();
|
||||||
|
s.template registerType<CPregamePackToPropagate, StartWithCurrentSettings>();
|
||||||
|
|
||||||
|
s.template registerType<CPregamePackToHost, PlayerJoined>();
|
||||||
|
s.template registerType<CPregamePackToHost, RequestOptionsChange>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Serializer>
|
template<typename Serializer>
|
||||||
|
@ -88,6 +88,18 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class CApplyOnGH<CPack> : public CBaseForGHApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool applyOnGH(CGameHandler *gh, CConnection *c, void *pack, PlayerColor player) const
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Cannot apply on GH plain CPack!";
|
||||||
|
assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static CApplier<CBaseForGHApply> *applier = nullptr;
|
static CApplier<CBaseForGHApply> *applier = nullptr;
|
||||||
|
|
||||||
CMP_stack cmpst ;
|
CMP_stack cmpst ;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user