mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Fix dynamic_cast on MacOSX in CQuery.cpp
This commit is contained in:
parent
610318d5d3
commit
68cc860133
@ -65,14 +65,14 @@ class ServerSpellCastEnvironment: public SpellCastEnvironment
|
||||
public:
|
||||
ServerSpellCastEnvironment(CGameHandler * gh);
|
||||
~ServerSpellCastEnvironment(){};
|
||||
void sendAndApply(CPackForClient * info) const override;
|
||||
void sendAndApply(CPackForClient * info) const override;
|
||||
CRandomGenerator & getRandomGenerator() const override;
|
||||
void complain(const std::string & problem) const override;
|
||||
const CMap * getMap() const override;
|
||||
const CGameInfoCallback * getCb() const override;
|
||||
bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const override;
|
||||
bool moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, PlayerColor asker = PlayerColor::NEUTRAL) const override;
|
||||
private:
|
||||
mutable CGameHandler * gh;
|
||||
mutable CGameHandler * gh;
|
||||
};
|
||||
|
||||
CondSh<bool> battleMadeAction;
|
||||
@ -102,7 +102,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
template <>
|
||||
class CApplyOnGH<CPack> : public CBaseForGHApply
|
||||
{
|
||||
public:
|
||||
@ -799,15 +799,15 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
||||
|
||||
const Bonus * bonus = att->getBonusLocalFirst(Selector::type(Bonus::SPELL_LIKE_ATTACK));
|
||||
if (bonus && (bat.shot())) //TODO: make it work in melee?
|
||||
{
|
||||
{
|
||||
//this is need for displaying hit animation
|
||||
bat.flags |= BattleAttack::SPELL_LIKE;
|
||||
bat.spellID = SpellID(bonus->subtype);
|
||||
|
||||
|
||||
//TODO: should spell override creature`s projectile?
|
||||
|
||||
|
||||
std::set<const CStack*> attackedCreatures = SpellID(bonus->subtype).toSpell()->getAffectedStacks(gs->curB, ECastingMode::SPELL_LIKE_ATTACK, att->owner, bonus->val, targetHex, att);
|
||||
|
||||
|
||||
//TODO: get exact attacked hex for defender
|
||||
|
||||
for(const CStack * stack : attackedCreatures)
|
||||
@ -817,7 +817,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
||||
applyBattleEffects(bat, att, stack, distance, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//now add effect info for all attacked stacks
|
||||
for(BattleStackAttacked & bsa : bat.bsa)
|
||||
{
|
||||
@ -828,7 +828,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
||||
bsa.spellID = SpellID(bonus->subtype);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, const CStack *def, int distance, bool secondary) //helper function for prepareAttack
|
||||
@ -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);
|
||||
@ -1026,7 +1026,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
||||
int v = path.first.size()-1;
|
||||
|
||||
bool stackIsMoving = true;
|
||||
|
||||
|
||||
while(stackIsMoving)
|
||||
{
|
||||
if(v<tilesToMove)
|
||||
@ -1079,10 +1079,10 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
||||
if(obs->stopsMovement() || !curStack->alive())
|
||||
stackIsMoving = false;
|
||||
|
||||
obs.reset();
|
||||
obs.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
processObstacle(obstacle);
|
||||
if(curStack->alive())
|
||||
processObstacle(obstacle2);
|
||||
@ -1105,14 +1105,14 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
|
||||
if(curStack->alive() && curStack->doubleWide())
|
||||
{
|
||||
BattleHex otherHex = curStack->occupiedHex(curStack->position);
|
||||
|
||||
|
||||
if(otherHex.isValid())
|
||||
if(auto theLastObstacle = battleGetObstacleOnPos(otherHex, false))
|
||||
{
|
||||
//two hex creature hit obstacle by backside
|
||||
handleDamageFromObstacle(*theLastObstacle, curStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1125,7 +1125,7 @@ CGameHandler::CGameHandler(void)
|
||||
registerTypesServerPacks(*applier);
|
||||
visitObjectAfterVictory = false;
|
||||
queries.gh = this;
|
||||
|
||||
|
||||
spellEnv = new ServerSpellCastEnvironment(this);
|
||||
}
|
||||
|
||||
@ -3907,8 +3907,8 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
complain("That stack can't cast spells!");
|
||||
else
|
||||
{
|
||||
const CSpell * spell = SpellID(spellID).toSpell();
|
||||
BattleSpellCastParameters parameters(gs->curB, stack, spell);
|
||||
const CSpell * spell = SpellID(spellID).toSpell();
|
||||
BattleSpellCastParameters parameters(gs->curB, stack, spell);
|
||||
parameters.spellLvl = 0;
|
||||
if (spellcaster)
|
||||
vstd::amax(parameters.spellLvl, spellcaster->val);
|
||||
@ -3940,12 +3940,12 @@ void CGameHandler::playerMessage( PlayerColor player, const std::string &message
|
||||
{
|
||||
SetMana sm;
|
||||
GiveBonus giveBonus(GiveBonus::HERO);
|
||||
|
||||
|
||||
CGHeroInstance *h = gs->getHero(currObj);
|
||||
if(!h && complain("Cannot realize cheat, no hero selected!")) return;
|
||||
|
||||
sm.hid = h->id;
|
||||
|
||||
|
||||
giveBonus.id = h->id.getNum();
|
||||
|
||||
//give all spells with bonus (to allow banned spells)
|
||||
@ -4107,11 +4107,11 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
}
|
||||
|
||||
const CSpell * s = SpellID(ba.additionalInfo).toSpell();
|
||||
|
||||
|
||||
BattleSpellCastParameters parameters(gs->curB, h, s);
|
||||
parameters.aimToHex(ba.destinationTile);//todo: allow multiple destinations
|
||||
parameters.mode = ECastingMode::HERO_CASTING;
|
||||
parameters.selectedStack = gs->curB->battleGetStackByID(ba.selectedStack, false);
|
||||
parameters.selectedStack = gs->curB->battleGetStackByID(ba.selectedStack, false);
|
||||
|
||||
ESpellCastProblem::ESpellCastProblem escp = gs->curB->battleCanCastThisSpell(h, s, ECastingMode::HERO_CASTING);//todo: should we check aimed cast(battleCanCastThisSpellHere)?
|
||||
if(escp != ESpellCastProblem::OK)
|
||||
@ -4123,9 +4123,9 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
|
||||
StartAction start_action(ba);
|
||||
sendAndApply(&start_action); //start spell casting
|
||||
|
||||
|
||||
s->battleCast(spellEnv, parameters);
|
||||
|
||||
|
||||
sendAndApply(&end_action);
|
||||
if( !gs->curB->battleGetStackByID(gs->curB->activeStack, true))
|
||||
{
|
||||
@ -4255,8 +4255,8 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||
auto bonus = *RandomGeneratorUtil::nextItem(bl, gs->getRandomGenerator());
|
||||
auto spellID = SpellID(bonus->subtype);
|
||||
const CSpell * spell = SpellID(spellID).toSpell();
|
||||
bl.remove_if([&bonus](Bonus * b){return b==bonus;});
|
||||
|
||||
bl.remove_if([&bonus](Bonus * b){return b==bonus;});
|
||||
|
||||
if (gs->curB->battleCanCastThisSpell(st, spell, ECastingMode::ENCHANTER_CASTING) == ESpellCastProblem::OK)
|
||||
{
|
||||
BattleSpellCastParameters parameters(gs->curB, st, spell);
|
||||
@ -4265,8 +4265,8 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||
parameters.aimToHex(BattleHex::INVALID);
|
||||
parameters.mode = ECastingMode::ENCHANTER_CASTING;
|
||||
parameters.selectedStack = nullptr;
|
||||
|
||||
spell->battleCast(spellEnv, parameters);
|
||||
|
||||
spell->battleCast(spellEnv, parameters);
|
||||
|
||||
//todo: move to mechanics
|
||||
BattleSetStackProperty ssp;
|
||||
@ -4275,9 +4275,9 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||
ssp.val = bonus->additionalInfo; //increase cooldown counter
|
||||
ssp.stackID = st->ID;
|
||||
sendAndApply(&ssp);
|
||||
|
||||
|
||||
cast = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
bl = *(st->getBonuses(Selector::type(Bonus::ENCHANTED)));
|
||||
@ -4383,7 +4383,7 @@ void CGameHandler::handleTimeEvents()
|
||||
while(gs->map->events.size() && gs->map->events.front().firstOccurence+1 == gs->day)
|
||||
{
|
||||
CMapEvent ev = gs->map->events.front();
|
||||
|
||||
|
||||
for (int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++)
|
||||
{
|
||||
auto color = PlayerColor(player);
|
||||
@ -4973,7 +4973,7 @@ void CGameHandler::attackCasting(const BattleAttack & bat, Bonus::BonusType atta
|
||||
parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
|
||||
parameters.selectedStack = nullptr;
|
||||
|
||||
spell->battleCast(spellEnv, parameters);
|
||||
spell->battleCast(spellEnv, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4990,7 +4990,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
const CStack * attacker = gs->curB->battleGetStackByID(bat.stackAttacking);
|
||||
if (!attacker) //could be already dead
|
||||
return;
|
||||
|
||||
|
||||
auto cast = [=](SpellID spellID, int power)
|
||||
{
|
||||
const CSpell * spell = SpellID(spellID).toSpell();
|
||||
@ -4999,13 +4999,13 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
parameters.spellLvl = 0;
|
||||
parameters.effectLevel = 0;
|
||||
parameters.aimToStack(gs->curB->battleGetStackByID(bat.bsa.at(0).stackAttacked));
|
||||
parameters.effectPower = power;
|
||||
parameters.effectPower = power;
|
||||
parameters.mode = ECastingMode::AFTER_ATTACK_CASTING;
|
||||
parameters.selectedStack = nullptr;
|
||||
|
||||
spell->battleCast(this->spellEnv, parameters);
|
||||
};
|
||||
|
||||
spell->battleCast(this->spellEnv, parameters);
|
||||
};
|
||||
|
||||
attackCasting(bat, Bonus::SPELL_AFTER_ATTACK, attacker);
|
||||
|
||||
if(bat.bsa.at(0).newAmount <= 0)
|
||||
@ -5056,11 +5056,11 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
bool CGameHandler::castSpell(const CGHeroInstance *h, SpellID spellID, const int3 &pos)
|
||||
{
|
||||
const CSpell *s = spellID.toSpell();
|
||||
|
||||
|
||||
AdventureSpellCastParameters p;
|
||||
p.caster = h;
|
||||
p.pos = pos;
|
||||
|
||||
|
||||
return s->adventureCast(spellEnv, p);
|
||||
}
|
||||
|
||||
@ -5298,8 +5298,8 @@ void CGameHandler::runBattle()
|
||||
auto h = gs->curB->battleGetFightingHero(i);
|
||||
if(h && h->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
|
||||
{
|
||||
TBonusListPtr bl = h->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
|
||||
TBonusListPtr bl = h->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
|
||||
for (Bonus *b : *bl)
|
||||
{
|
||||
const CSpell * spell = SpellID(b->subtype).toSpell();
|
||||
@ -5308,7 +5308,7 @@ void CGameHandler::runBattle()
|
||||
parameters.effectLevel = 3;
|
||||
parameters.aimToHex(BattleHex::INVALID);
|
||||
parameters.mode = ECastingMode::PASSIVE_CASTING;
|
||||
parameters.selectedStack = nullptr;
|
||||
parameters.selectedStack = nullptr;
|
||||
parameters.enchantPower = b->val;
|
||||
spell->battleCast(spellEnv, parameters);
|
||||
}
|
||||
@ -5347,7 +5347,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 &&
|
||||
@ -5483,7 +5482,7 @@ void CGameHandler::runBattle()
|
||||
{
|
||||
logGlobal->traceStream() << "Activating " << next->nodeName();
|
||||
auto nextId = next->ID;
|
||||
BattleSetActiveStack sas;
|
||||
BattleSetActiveStack sas;
|
||||
sas.stack = nextId;
|
||||
sendAndApply(&sas);
|
||||
|
||||
@ -5900,7 +5899,7 @@ CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
|
||||
///ServerSpellCastEnvironment
|
||||
ServerSpellCastEnvironment::ServerSpellCastEnvironment(CGameHandler * gh): gh(gh)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ServerSpellCastEnvironment::sendAndApply(CPackForClient * info) const
|
||||
@ -5933,4 +5932,3 @@ bool ServerSpellCastEnvironment::moveHero(ObjectInstanceID hid, int3 dst, ui8 te
|
||||
{
|
||||
return gh->moveHero(hid, dst, teleporting, false, asker);
|
||||
}
|
||||
|
||||
|
@ -97,11 +97,11 @@ CObjectVisitQuery::CObjectVisitQuery(const CGObjectInstance *Obj, const CGHeroIn
|
||||
addPlayer(Hero->tempOwner);
|
||||
}
|
||||
|
||||
bool CObjectVisitQuery::blocksPack(const CPack *pack) const
|
||||
bool CObjectVisitQuery::blocksPack(const CPack *pack) const
|
||||
{
|
||||
//During the visit itself ALL actions are blocked.
|
||||
//(However, the visit may trigger a query above that'll pass some.)
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CObjectVisitQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||
@ -220,7 +220,7 @@ std::vector<shared_ptr<CQuery>> Queries::allQueries()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
void CBattleQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
{
|
||||
assert(result);
|
||||
objectVisit.visitedObject->battleFinished(objectVisit.visitingHero, *result);
|
||||
@ -242,9 +242,14 @@ CBattleQuery::CBattleQuery()
|
||||
|
||||
}
|
||||
|
||||
bool CBattleQuery::blocksPack(const CPack *pack) const
|
||||
bool CBattleQuery::blocksPack(const CPack *pack) const
|
||||
{
|
||||
return !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
|
||||
#ifndef __APPLE__
|
||||
bool dynamic_success = !dynamic_cast<const MakeAction*>(pack) && !dynamic_cast<const MakeCustomAction*>(pack);
|
||||
#else
|
||||
const char * name = typeid(*pack).name();
|
||||
return strcmp(name, typeid(MakeAction).name()) && strcmp(name, typeid(MakeCustomAction).name());
|
||||
#endif
|
||||
}
|
||||
|
||||
void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||
@ -252,7 +257,7 @@ void CBattleQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||
gh->battleAfterLevelUp(*result);
|
||||
}
|
||||
|
||||
void CGarrisonDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
void CGarrisonDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
{
|
||||
objectVisit.visitedObject->garrisonDialogClosed(objectVisit.visitingHero);
|
||||
}
|
||||
@ -266,18 +271,18 @@ CGarrisonDialogQuery::CGarrisonDialogQuery(const CArmedInstance *up, const CArme
|
||||
addPlayer(down->tempOwner);
|
||||
}
|
||||
|
||||
bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
||||
bool CGarrisonDialogQuery::blocksPack(const CPack *pack) const
|
||||
{
|
||||
std::set<ObjectInstanceID> ourIds;
|
||||
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))
|
||||
@ -288,24 +293,24 @@ 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);
|
||||
}
|
||||
return CDialogQuery::blocksPack(pack);
|
||||
}
|
||||
|
||||
void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
void CBlockingDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
{
|
||||
assert(answer);
|
||||
objectVisit.visitedObject->blockingDialogAnswered(objectVisit.visitingHero, *answer);
|
||||
@ -319,7 +324,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<CGTeleport>(objectVisit.visitedObject);
|
||||
obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
|
||||
}
|
||||
|
||||
@ -342,7 +347,7 @@ void CHeroLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
||||
gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
|
||||
}
|
||||
|
||||
void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
{
|
||||
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||
}
|
||||
@ -360,20 +365,20 @@ void CCommanderLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color
|
||||
gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
|
||||
}
|
||||
|
||||
void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||
{
|
||||
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||
}
|
||||
|
||||
bool CDialogQuery::endsByPlayerAnswer() const
|
||||
bool CDialogQuery::endsByPlayerAnswer() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDialogQuery::blocksPack(const CPack *pack) 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);
|
||||
}
|
||||
|
@ -8,3 +8,17 @@
|
||||
#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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user