mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge remote-tracking branch 'origin/issue/2306' into develop
This commit is contained in:
commit
a051a08a46
@ -2735,24 +2735,13 @@ void VCAI::finish()
|
||||
|
||||
void VCAI::requestActionASAP(std::function<void()> whatToDo)
|
||||
{
|
||||
boost::mutex mutex;
|
||||
mutex.lock();
|
||||
|
||||
boost::thread newThread([&mutex,this,whatToDo]()
|
||||
boost::thread newThread([this,whatToDo]()
|
||||
{
|
||||
setThreadName("VCAI::requestActionASAP::helper");
|
||||
setThreadName("VCAI::requestActionASAP::whatToDo");
|
||||
SET_GLOBAL_STATE(this);
|
||||
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
||||
// unlock mutex and allow parent function to exit
|
||||
mutex.unlock();
|
||||
whatToDo();
|
||||
});
|
||||
|
||||
// wait for mutex to unlock and for thread to initialize properly
|
||||
mutex.lock();
|
||||
|
||||
// unlock mutex - boost dislikes destruction of locked mutexes
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void VCAI::lostHero(HeroPtr h)
|
||||
|
@ -247,21 +247,14 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
void CClient::loadGame(const std::string & fname, const bool server, const std::vector<int>& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port)
|
||||
{
|
||||
PlayerColor player(player_); //intentional shadowing
|
||||
logNetwork->infoStream() << "Loading procedure started!";
|
||||
|
||||
std::string realPort;
|
||||
if(settings["testing"]["enabled"].Bool())
|
||||
realPort = settings["testing"]["port"].String();
|
||||
else if(port.size())
|
||||
realPort = port;
|
||||
else
|
||||
realPort = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
||||
logNetwork->infoStream() <<"Loading procedure started!";
|
||||
|
||||
CServerHandler sh;
|
||||
if(server)
|
||||
sh.startServer();
|
||||
else
|
||||
serv = sh.justConnectToServer(ipaddr, realPort);
|
||||
serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port);
|
||||
|
||||
CStopWatch tmh;
|
||||
unique_ptr<CLoadFile> loader;
|
||||
@ -974,9 +967,6 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
|
||||
{
|
||||
serverThread = nullptr;
|
||||
shared = nullptr;
|
||||
if(settings["testing"]["enabled"].Bool())
|
||||
port = settings["testing"]["port"].String();
|
||||
else
|
||||
port = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
||||
verbose = true;
|
||||
|
||||
|
@ -1538,7 +1538,10 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
||||
}
|
||||
else if(const CGHeroInstance * h = curHero())
|
||||
{
|
||||
const CGPathNode * pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPos);
|
||||
int3 mapPosCopy = mapPos;
|
||||
const CGPathNode * pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPosCopy);
|
||||
assert(pnode);
|
||||
|
||||
int turns = pnode->turns;
|
||||
vstd::amin(turns, 3);
|
||||
switch(pnode->action)
|
||||
@ -1800,4 +1803,3 @@ void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
|
||||
|
||||
info.additionalIcons = &iconPositions;
|
||||
}
|
||||
|
||||
|
@ -450,18 +450,19 @@ CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type )
|
||||
return newType;
|
||||
}
|
||||
|
||||
ui16 CTypeList::getTypeID( const std::type_info *type )
|
||||
ui16 CTypeList::getTypeID( const std::type_info *type, bool throws ) const
|
||||
{
|
||||
auto descriptor = getTypeDescriptor(type, throws);
|
||||
if (descriptor == nullptr)
|
||||
{
|
||||
auto i = typeInfos.find(type);
|
||||
if(i != typeInfos.end())
|
||||
return i->second->typeID;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return descriptor->typeID;
|
||||
}
|
||||
|
||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to)
|
||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const
|
||||
{
|
||||
if(from == to)
|
||||
if(!strcmp(from->name, to->name))
|
||||
return std::vector<CTypeList::TypeInfoPtr>();
|
||||
|
||||
// Perform a simple BFS in the class hierarchy.
|
||||
@ -512,17 +513,17 @@ std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, Ty
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to)
|
||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to) const
|
||||
{
|
||||
//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)
|
||||
if(!strcmp(from->name(), to->name()))
|
||||
return std::vector<CTypeList::TypeInfoPtr>();
|
||||
|
||||
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
|
||||
}
|
||||
|
||||
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws)
|
||||
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws) const
|
||||
{
|
||||
auto i = typeInfos.find(type);
|
||||
if(i != typeInfos.end())
|
||||
@ -646,4 +647,3 @@ CMemorySerializer::CMemorySerializer(): iser(this), oser(this)
|
||||
registerTypes(iser);
|
||||
registerTypes(oser);
|
||||
}
|
||||
|
||||
|
126
lib/Connection.h
126
lib/Connection.h
@ -83,7 +83,11 @@ struct TypeComparer
|
||||
{
|
||||
bool operator()(const std::type_info *a, const std::type_info *b) const
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
return a->before(*b);
|
||||
#else
|
||||
return strcmp(a->name(), b->name()) < 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -102,6 +106,11 @@ struct PointerCaster : IPointerCaster
|
||||
{
|
||||
From * from = (From*)boost::any_cast<void*>(ptr);
|
||||
To * ret = dynamic_cast<To*>(from);
|
||||
if (ret == nullptr)
|
||||
{
|
||||
// Last resort when RTTI goes mad
|
||||
ret = static_cast<To*>(from);
|
||||
}
|
||||
return (void*)ret;
|
||||
}
|
||||
|
||||
@ -113,6 +122,11 @@ struct PointerCaster : IPointerCaster
|
||||
{
|
||||
auto from = boost::any_cast<SmartPt>(ptr);
|
||||
auto ret = std::dynamic_pointer_cast<To>(from);
|
||||
if (!ret)
|
||||
{
|
||||
// Last resort when RTTI goes mad
|
||||
ret = std::static_pointer_cast<To>(from);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
@ -136,7 +150,7 @@ struct PointerCaster : IPointerCaster
|
||||
// }
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CTypeList
|
||||
class DLL_LINKAGE CTypeList: public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
struct TypeDescriptor;
|
||||
@ -147,33 +161,53 @@ public:
|
||||
const char *name;
|
||||
std::vector<TypeInfoPtr> children, parents;
|
||||
};
|
||||
typedef boost::shared_mutex TMutex;
|
||||
typedef boost::unique_lock<TMutex> TUniqueLock;
|
||||
typedef boost::shared_lock<TMutex> TSharedLock;
|
||||
private:
|
||||
mutable TMutex mx;
|
||||
|
||||
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:
|
||||
/// 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) const;
|
||||
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to) const;
|
||||
|
||||
CTypeList();
|
||||
|
||||
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
|
||||
{
|
||||
TSharedLock lock(mx);
|
||||
auto typesSequence = castSequence(fromArg, toArg);
|
||||
|
||||
boost::any ptr = inputPtr;
|
||||
for(int i = 0; i < static_cast<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 not have operator->* ..?
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true) const; //if not throws, failure returns nullptr
|
||||
|
||||
TypeInfoPtr registerType(const std::type_info *type);
|
||||
|
||||
public:
|
||||
CTypeList();
|
||||
|
||||
template <typename Base, typename Derived>
|
||||
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||
{
|
||||
TUniqueLock lock(mx);
|
||||
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.");
|
||||
@ -187,77 +221,52 @@ public:
|
||||
casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
|
||||
}
|
||||
|
||||
ui16 getTypeID(const std::type_info *type);
|
||||
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true); //if not throws, failure returns nullptr
|
||||
ui16 getTypeID(const std::type_info *type, bool throws = false) const;
|
||||
|
||||
template <typename T>
|
||||
ui16 getTypeID(const T * t = nullptr)
|
||||
ui16 getTypeID(const T * t = nullptr, bool throws = false) const
|
||||
{
|
||||
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;
|
||||
return getTypeID(getTypeInfo(t), throws);
|
||||
}
|
||||
|
||||
template<typename TInput>
|
||||
void *castToMostDerived(const TInput *inputPtr)
|
||||
void * castToMostDerived(const TInput * inputPtr) const
|
||||
{
|
||||
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||
auto derivedType = getTypeInfo(inputPtr);
|
||||
|
||||
if(baseType == *derivedType)
|
||||
return (void*)inputPtr;
|
||||
if (!strcmp(baseType.name(), derivedType->name()))
|
||||
{
|
||||
return const_cast<void*>(reinterpret_cast<const void*>(inputPtr));
|
||||
}
|
||||
|
||||
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>((void*)inputPtr, &baseType, derivedType));
|
||||
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(
|
||||
const_cast<void*>(reinterpret_cast<const void*>(inputPtr)), &baseType,
|
||||
derivedType));
|
||||
}
|
||||
|
||||
template<typename TInput>
|
||||
boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr)
|
||||
boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr) const
|
||||
{
|
||||
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||
auto derivedType = getTypeInfo(inputPtr.get());
|
||||
|
||||
if(baseType == *derivedType)
|
||||
if (!strcmp(baseType.name(), derivedType->name()))
|
||||
return inputPtr;
|
||||
|
||||
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
|
||||
}
|
||||
|
||||
void* castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to)
|
||||
void * castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||
{
|
||||
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)
|
||||
boost::any castShared(boost::any inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||
{
|
||||
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) const
|
||||
{
|
||||
if(t)
|
||||
return &typeid(*t);
|
||||
@ -665,9 +674,8 @@ public:
|
||||
{
|
||||
COSer &s = static_cast<COSer&>(ar);
|
||||
const T *ptr = static_cast<const T*>(data);
|
||||
|
||||
//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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -331,9 +331,6 @@ struct SetAvailableHeroes : public CPackForClient //113
|
||||
for (int i = 0; i < GameConstants::AVAILABLE_HEROES_PER_PLAYER; i++)
|
||||
army[i].clear();
|
||||
}
|
||||
~SetAvailableHeroes()
|
||||
{
|
||||
}
|
||||
void applyCl(CClient *cl);
|
||||
DLL_LINKAGE void applyGs(CGameState *gs);
|
||||
|
||||
|
@ -917,7 +917,7 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
|
||||
c << &applied;
|
||||
};
|
||||
|
||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriate applier object
|
||||
if(isBlockedByQueries(pack, player))
|
||||
{
|
||||
sendPackageResponse(false);
|
||||
@ -5368,7 +5368,6 @@ void CGameHandler::runBattle()
|
||||
const CStack *next;
|
||||
while(!battleResult.get() && (next = curB.getNextStack()) && next->willMove())
|
||||
{
|
||||
|
||||
//check for bad morale => freeze
|
||||
int nextStackMorale = next->MoraleVal();
|
||||
if( nextStackMorale < 0 &&
|
||||
@ -5710,7 +5709,7 @@ bool CGameHandler::isValidObject(const CGObjectInstance *obj) const
|
||||
|
||||
bool CGameHandler::isBlockedByQueries(const CPack *pack, PlayerColor player)
|
||||
{
|
||||
if(dynamic_cast<const PlayerMessage*>(pack))
|
||||
if(!strcmp(typeid(*pack).name(), typeid(PlayerMessage).name()))
|
||||
return false;
|
||||
|
||||
auto query = queries.topQuery(player);
|
||||
@ -5849,7 +5848,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
||||
//catapult artifact remain even if "creature" killed in siege
|
||||
if(warMachine != ArtifactID::NONE && warMachine != ArtifactID::CATAPULT)
|
||||
{
|
||||
auto hero = dynamic_cast<const CGHeroInstance*> (army);
|
||||
auto hero = dynamic_ptr_cast<CGHeroInstance> (army);
|
||||
if (hero)
|
||||
removedWarMachines.push_back (ArtifactLocation(hero, hero->getArtPos(warMachine, true)));
|
||||
}
|
||||
@ -5955,4 +5954,3 @@ bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, ui8 te
|
||||
{
|
||||
return gh->moveHero(hid, dst, teleporting, false, asker);
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,8 @@ CBattleQuery::CBattleQuery()
|
||||
|
||||
bool CBattleQuery::blocksPack(const CPack *pack) const
|
||||
{
|
||||
return !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
|
||||
const char * name = typeid(*pack).name();
|
||||
return strcmp(name, typeid(MakeAction).name()) && strcmp(name, typeid(MakeCustomAction).name());
|
||||
}
|
||||
|
||||
void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||
@ -273,12 +274,12 @@ bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
||||
ourIds.insert(this->exchangingArmies[0]->id);
|
||||
ourIds.insert(this->exchangingArmies[1]->id);
|
||||
|
||||
|
||||
if (auto stacks = dynamic_cast<const ArrangeStacks*>(pack))
|
||||
if (auto stacks = dynamic_ptr_cast<ArrangeStacks>(pack))
|
||||
{
|
||||
return !vstd::contains(ourIds, stacks->id1) || !vstd::contains(ourIds, stacks->id2);
|
||||
}
|
||||
if (auto arts = dynamic_cast<const ExchangeArtifacts*>(pack))
|
||||
|
||||
if (auto arts = dynamic_ptr_cast<ExchangeArtifacts>(pack))
|
||||
{
|
||||
if(auto id1 = boost::apply_visitor(GetEngagedHeroIds(), arts->src.artHolder))
|
||||
if(!vstd::contains(ourIds, *id1))
|
||||
@ -289,17 +290,17 @@ bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (auto dismiss = dynamic_cast<const DisbandCreature*>(pack))
|
||||
if (auto dismiss = dynamic_ptr_cast<DisbandCreature>(pack))
|
||||
{
|
||||
return !vstd::contains(ourIds, dismiss->id);
|
||||
}
|
||||
|
||||
if (auto dismiss = dynamic_cast<const AssembleArtifacts*>(pack))
|
||||
if (auto dismiss = dynamic_ptr_cast<AssembleArtifacts>(pack))
|
||||
{
|
||||
return !vstd::contains(ourIds, dismiss->heroID);
|
||||
}
|
||||
|
||||
if(auto upgrade = dynamic_cast<const UpgradeCreature*>(pack))
|
||||
if(auto upgrade = dynamic_ptr_cast<UpgradeCreature>(pack))
|
||||
{
|
||||
return !vstd::contains(ourIds, upgrade->id);
|
||||
}
|
||||
@ -320,7 +321,7 @@ CBlockingDialogQuery::CBlockingDialogQuery(const BlockingDialog &bd)
|
||||
|
||||
void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
{
|
||||
auto obj = dynamic_cast<const CGTeleport *>(objectVisit.visitedObject);
|
||||
auto obj = dynamic_ptr_cast<const CGTeleport>(objectVisit.visitedObject);
|
||||
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
||||
}
|
||||
|
||||
@ -374,7 +375,7 @@ bool CDialogQuery::endsByPlayerAnswer() const
|
||||
bool CDialogQuery::blocksPack(const CPack *pack) const
|
||||
{
|
||||
//We accept only query replies from correct player
|
||||
if(auto reply = dynamic_cast<const QueryReply *>(pack))
|
||||
if(auto reply = dynamic_ptr_cast<QueryReply>(pack))
|
||||
{
|
||||
return !vstd::contains(players, reply->player);
|
||||
}
|
||||
|
@ -86,8 +86,8 @@ void CPregameServer::handleConnection(CConnection *cpc)
|
||||
logNetwork->infoStream() << "Got package to announce " << typeid(*cpfs).name() << " from " << *cpc;
|
||||
|
||||
boost::unique_lock<boost::recursive_mutex> queueLock(mx);
|
||||
bool quitting = dynamic_cast<QuitMenuWithoutStarting*>(cpfs),
|
||||
startingGame = dynamic_cast<StartWithCurrentSettings*>(cpfs);
|
||||
bool quitting = dynamic_ptr_cast<QuitMenuWithoutStarting>(cpfs),
|
||||
startingGame = dynamic_ptr_cast<StartWithCurrentSettings>(cpfs);
|
||||
if(quitting || startingGame) //host leaves main menu or wants to start game -> we end
|
||||
{
|
||||
cpc->receivedStop = true;
|
||||
@ -258,11 +258,11 @@ void CPregameServer::sendPack(CConnection * pc, const CPackForSelectionScreen &
|
||||
*pc << &pack;
|
||||
}
|
||||
|
||||
if(dynamic_cast<const QuitMenuWithoutStarting*>(&pack))
|
||||
if(dynamic_ptr_cast<QuitMenuWithoutStarting>(&pack))
|
||||
{
|
||||
pc->sendStop = true;
|
||||
}
|
||||
else if(dynamic_cast<const StartWithCurrentSettings*>(&pack))
|
||||
else if(dynamic_ptr_cast<StartWithCurrentSettings>(&pack))
|
||||
{
|
||||
pc->sendStop = true;
|
||||
}
|
||||
@ -270,25 +270,25 @@ void CPregameServer::sendPack(CConnection * pc, const CPackForSelectionScreen &
|
||||
|
||||
void CPregameServer::processPack(CPackForSelectionScreen * pack)
|
||||
{
|
||||
if(dynamic_cast<CPregamePackToHost*>(pack))
|
||||
if(dynamic_ptr_cast<CPregamePackToHost>(pack))
|
||||
{
|
||||
sendPack(host, *pack);
|
||||
}
|
||||
else if(SelectMap *sm = dynamic_cast<SelectMap*>(pack))
|
||||
else if(SelectMap *sm = dynamic_ptr_cast<SelectMap>(pack))
|
||||
{
|
||||
vstd::clear_pointer(curmap);
|
||||
curmap = sm->mapInfo;
|
||||
sm->free = false;
|
||||
announcePack(*pack);
|
||||
}
|
||||
else if(UpdateStartOptions *uso = dynamic_cast<UpdateStartOptions*>(pack))
|
||||
else if(UpdateStartOptions *uso = dynamic_ptr_cast<UpdateStartOptions>(pack))
|
||||
{
|
||||
vstd::clear_pointer(curStartInfo);
|
||||
curStartInfo = uso->options;
|
||||
uso->free = false;
|
||||
announcePack(*pack);
|
||||
}
|
||||
else if(dynamic_cast<const StartWithCurrentSettings*>(pack))
|
||||
else if(dynamic_ptr_cast<StartWithCurrentSettings>(pack))
|
||||
{
|
||||
state = ENDING_AND_STARTING_GAME;
|
||||
announcePack(*pack);
|
||||
|
@ -209,7 +209,7 @@ bool SetFormation::applyGh( CGameHandler *gh )
|
||||
bool HireHero::applyGh( CGameHandler *gh )
|
||||
{
|
||||
const CGObjectInstance *obj = gh->getObj(tid);
|
||||
const CGTownInstance *town = dynamic_cast<const CGTownInstance *>(obj);
|
||||
const CGTownInstance *town = dynamic_ptr_cast<CGTownInstance>(obj);
|
||||
if(town && PlayerRelations::ENEMIES == gh->getPlayerRelations(obj->tempOwner, gh->getPlayerAt(c)))
|
||||
COMPLAIN_AND_RETURN("Can't buy hero in enemy town!");
|
||||
|
||||
|
@ -8,3 +8,31 @@
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <boost/random/variate_generator.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
|
||||
template<class T, class F>
|
||||
inline const T * dynamic_ptr_cast(const F * ptr)
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
return dynamic_cast<const T*>(ptr);
|
||||
#else
|
||||
if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||
{
|
||||
return static_cast<const T*>(ptr);
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T, class F>
|
||||
inline T * dynamic_ptr_cast(F * ptr)
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
return dynamic_cast<T*>(ptr);
|
||||
#else
|
||||
if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
|
||||
{
|
||||
return static_cast<T*>(ptr);
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user