forked from mirror/openmw-tes3mp
Fast version of dynamic_cast for MWClass
This commit is contained in:
parent
db71634a2d
commit
cd4a1ffd16
7 changed files with 150 additions and 59 deletions
|
@ -27,23 +27,26 @@
|
|||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
namespace
|
||||
namespace MWClass
|
||||
{
|
||||
struct ContainerCustomData : public MWWorld::CustomData
|
||||
class ContainerCustomData : public MWWorld::CustomData
|
||||
{
|
||||
public:
|
||||
MWWorld::ContainerStore mContainerStore;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
|
||||
virtual ContainerCustomData& asContainerCustomData()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
MWWorld::CustomData *ContainerCustomData::clone() const
|
||||
{
|
||||
return new ContainerCustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
std::string Container::getId (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return ptr.get<ESM::Container>()->mBase->mId;
|
||||
|
@ -202,7 +205,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
return ptr.getRefData().getCustomData()->asContainerCustomData().mContainerStore;
|
||||
}
|
||||
|
||||
std::string Container::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -40,14 +40,29 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
struct CreatureCustomData : public MWWorld::CustomData
|
||||
bool isFlagBitSet(const MWWorld::Ptr &ptr, ESM::Creature::Flags bitMask)
|
||||
{
|
||||
return (ptr.get<ESM::Creature>()->mBase->mFlags & bitMask) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
||||
class CreatureCustomData : public MWWorld::CustomData
|
||||
{
|
||||
public:
|
||||
MWMechanics::CreatureStats mCreatureStats;
|
||||
MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures
|
||||
MWMechanics::Movement mMovement;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
|
||||
virtual CreatureCustomData& asCreatureCustomData()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
CreatureCustomData() : mContainerStore(0) {}
|
||||
virtual ~CreatureCustomData() { delete mContainerStore; }
|
||||
};
|
||||
|
@ -59,14 +74,6 @@ namespace
|
|||
return cloned;
|
||||
}
|
||||
|
||||
bool isFlagBitSet(const MWWorld::Ptr &ptr, ESM::Creature::Flags bitMask)
|
||||
{
|
||||
return (ptr.get<ESM::Creature>()->mBase->mFlags & bitMask) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
const Creature::GMST& Creature::getGmst()
|
||||
{
|
||||
static GMST gmst;
|
||||
|
@ -193,7 +200,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
||||
return ptr.getRefData().getCustomData()->asCreatureCustomData().mCreatureStats;
|
||||
}
|
||||
|
||||
|
||||
|
@ -421,7 +428,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return *dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
return *ptr.getRefData().getCustomData()->asCreatureCustomData().mContainerStore;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr &ptr) const
|
||||
|
@ -511,7 +518,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
return ptr.getRefData().getCustomData()->asCreatureCustomData().mMovement;
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
|
@ -711,7 +718,7 @@ namespace MWClass
|
|||
else
|
||||
ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless.
|
||||
|
||||
CreatureCustomData& customData = dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData();
|
||||
|
||||
customData.mContainerStore->readState (state2.mInventory);
|
||||
customData.mCreatureStats.readState (state2.mCreatureStats);
|
||||
|
@ -730,7 +737,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
CreatureCustomData& customData = dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData();
|
||||
|
||||
customData.mContainerStore->writeState (state2.mInventory);
|
||||
customData.mCreatureStats.writeState (state2.mCreatureStats);
|
||||
|
|
|
@ -7,25 +7,28 @@
|
|||
|
||||
#include "../mwworld/customdata.hpp"
|
||||
|
||||
namespace
|
||||
namespace MWClass
|
||||
{
|
||||
struct CreatureLevListCustomData : public MWWorld::CustomData
|
||||
class CreatureLevListCustomData : public MWWorld::CustomData
|
||||
{
|
||||
public:
|
||||
// actorId of the creature we spawned
|
||||
int mSpawnActorId;
|
||||
bool mSpawn; // Should a new creature be spawned?
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
|
||||
virtual CreatureLevListCustomData& asCreatureLevListCustomData()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CreatureLevListCustomData::clone() const
|
||||
{
|
||||
return new CreatureLevListCustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
std::string CreatureLevList::getId (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return ptr.get<ESM::CreatureLevList>()->mBase->mId;
|
||||
|
@ -40,7 +43,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData(ptr);
|
||||
|
||||
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
|
||||
customData.mSpawn = true;
|
||||
}
|
||||
|
||||
|
@ -55,7 +58,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData(ptr);
|
||||
|
||||
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
|
||||
if (!customData.mSpawn)
|
||||
return;
|
||||
|
||||
|
@ -104,7 +107,7 @@ namespace MWClass
|
|||
const ESM::CreatureLevListState& state2 = dynamic_cast<const ESM::CreatureLevListState&> (state);
|
||||
|
||||
ensureCustomData(ptr);
|
||||
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
|
||||
customData.mSpawnActorId = state2.mSpawnActorId;
|
||||
customData.mSpawn = state2.mSpawn;
|
||||
}
|
||||
|
@ -115,7 +118,7 @@ namespace MWClass
|
|||
ESM::CreatureLevListState& state2 = dynamic_cast<ESM::CreatureLevListState&> (state);
|
||||
|
||||
ensureCustomData(ptr);
|
||||
CreatureLevListCustomData& customData = dynamic_cast<CreatureLevListCustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
|
||||
state2.mSpawnActorId = customData.mSpawnActorId;
|
||||
state2.mSpawn = customData.mSpawn;
|
||||
}
|
||||
|
|
|
@ -28,23 +28,26 @@
|
|||
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
namespace
|
||||
namespace MWClass
|
||||
{
|
||||
struct DoorCustomData : public MWWorld::CustomData
|
||||
class DoorCustomData : public MWWorld::CustomData
|
||||
{
|
||||
public:
|
||||
int mDoorState; // 0 = nothing, 1 = opening, 2 = closing
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
|
||||
virtual DoorCustomData& asDoorCustomData()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
MWWorld::CustomData *DoorCustomData::clone() const
|
||||
{
|
||||
return new DoorCustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
std::string Door::getId (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return ptr.get<ESM::Door>()->mBase->mId;
|
||||
|
@ -65,7 +68,7 @@ namespace MWClass
|
|||
// Resume the door's opening/closing animation if it wasn't finished
|
||||
if (ptr.getRefData().getCustomData())
|
||||
{
|
||||
const DoorCustomData& customData = dynamic_cast<const DoorCustomData&>(*ptr.getRefData().getCustomData());
|
||||
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
||||
if (customData.mDoorState > 0)
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState);
|
||||
|
@ -324,7 +327,7 @@ namespace MWClass
|
|||
int Door::getDoorState (const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
ensureCustomData(ptr);
|
||||
const DoorCustomData& customData = dynamic_cast<const DoorCustomData&>(*ptr.getRefData().getCustomData());
|
||||
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
||||
return customData.mDoorState;
|
||||
}
|
||||
|
||||
|
@ -334,14 +337,14 @@ namespace MWClass
|
|||
throw std::runtime_error("load doors can't be moved");
|
||||
|
||||
ensureCustomData(ptr);
|
||||
DoorCustomData& customData = dynamic_cast<DoorCustomData&>(*ptr.getRefData().getCustomData());
|
||||
DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
||||
customData.mDoorState = state;
|
||||
}
|
||||
|
||||
void Door::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const
|
||||
{
|
||||
ensureCustomData(ptr);
|
||||
DoorCustomData& customData = dynamic_cast<DoorCustomData&>(*ptr.getRefData().getCustomData());
|
||||
DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
||||
|
||||
const ESM::DoorState& state2 = dynamic_cast<const ESM::DoorState&>(state);
|
||||
customData.mDoorState = state2.mDoorState;
|
||||
|
@ -350,7 +353,7 @@ namespace MWClass
|
|||
void Door::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) const
|
||||
{
|
||||
ensureCustomData(ptr);
|
||||
const DoorCustomData& customData = dynamic_cast<const DoorCustomData&>(*ptr.getRefData().getCustomData());
|
||||
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
||||
|
||||
ESM::DoorState& state2 = dynamic_cast<ESM::DoorState&>(state);
|
||||
state2.mDoorState = customData.mDoorState;
|
||||
|
|
|
@ -42,19 +42,6 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
struct NpcCustomData : public MWWorld::CustomData
|
||||
{
|
||||
MWMechanics::NpcStats mNpcStats;
|
||||
MWMechanics::Movement mMovement;
|
||||
MWWorld::InventoryStore mInventoryStore;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
|
||||
MWWorld::CustomData *NpcCustomData::clone() const
|
||||
{
|
||||
return new NpcCustomData (*this);
|
||||
}
|
||||
|
||||
int is_even(double d) {
|
||||
double int_part;
|
||||
|
@ -251,6 +238,27 @@ namespace
|
|||
|
||||
namespace MWClass
|
||||
{
|
||||
|
||||
class NpcCustomData : public MWWorld::CustomData
|
||||
{
|
||||
public:
|
||||
MWMechanics::NpcStats mNpcStats;
|
||||
MWMechanics::Movement mMovement;
|
||||
MWWorld::InventoryStore mInventoryStore;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
|
||||
virtual NpcCustomData& asNpcCustomData()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
MWWorld::CustomData *NpcCustomData::clone() const
|
||||
{
|
||||
return new NpcCustomData (*this);
|
||||
}
|
||||
|
||||
const Npc::GMST& Npc::getGmst()
|
||||
{
|
||||
static GMST gmst;
|
||||
|
@ -446,14 +454,14 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
return ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats;
|
||||
}
|
||||
|
||||
MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
return ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats;
|
||||
}
|
||||
|
||||
|
||||
|
@ -780,7 +788,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||
return ptr.getRefData().getCustomData()->asNpcCustomData().mInventoryStore;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore& Npc::getInventoryStore (const MWWorld::Ptr& ptr)
|
||||
|
@ -788,7 +796,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||
return ptr.getRefData().getCustomData()->asNpcCustomData().mInventoryStore;
|
||||
}
|
||||
|
||||
std::string Npc::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
@ -897,7 +905,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
return ptr.getRefData().getCustomData()->asNpcCustomData().mMovement;
|
||||
}
|
||||
|
||||
bool Npc::isEssential (const MWWorld::Ptr& ptr) const
|
||||
|
@ -1161,7 +1169,7 @@ namespace MWClass
|
|||
else
|
||||
ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless.
|
||||
|
||||
NpcCustomData& customData = dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData());
|
||||
NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData();
|
||||
|
||||
customData.mInventoryStore.readState (state2.mInventory);
|
||||
customData.mNpcStats.readState (state2.mNpcStats);
|
||||
|
@ -1181,7 +1189,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
NpcCustomData& customData = dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData());
|
||||
NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData();
|
||||
|
||||
customData.mInventoryStore.writeState (state2.mInventory);
|
||||
customData.mNpcStats.writeState (state2.mNpcStats);
|
||||
|
|
46
apps/openmw/mwworld/customdata.cpp
Normal file
46
apps/openmw/mwworld/customdata.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include "customdata.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
||||
MWClass::CreatureCustomData &CustomData::asCreatureCustomData()
|
||||
{
|
||||
std::stringstream error;
|
||||
error << "bad cast " << typeid(this).name() << " to CreatureCustomData";
|
||||
throw std::logic_error(error.str());
|
||||
}
|
||||
|
||||
MWClass::NpcCustomData &CustomData::asNpcCustomData()
|
||||
{
|
||||
std::stringstream error;
|
||||
error << "bad cast " << typeid(this).name() << " to NpcCustomData";
|
||||
throw std::logic_error(error.str());
|
||||
}
|
||||
|
||||
MWClass::ContainerCustomData &CustomData::asContainerCustomData()
|
||||
{
|
||||
std::stringstream error;
|
||||
error << "bad cast " << typeid(this).name() << " to ContainerCustomData";
|
||||
throw std::logic_error(error.str());
|
||||
}
|
||||
|
||||
MWClass::DoorCustomData &CustomData::asDoorCustomData()
|
||||
{
|
||||
std::stringstream error;
|
||||
error << "bad cast " << typeid(this).name() << " to DoorCustomData";
|
||||
throw std::logic_error(error.str());
|
||||
}
|
||||
|
||||
MWClass::CreatureLevListCustomData &CustomData::asCreatureLevListCustomData()
|
||||
{
|
||||
std::stringstream error;
|
||||
error << "bad cast " << typeid(this).name() << " to CreatureLevListCustomData";
|
||||
throw std::logic_error(error.str());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,6 +1,15 @@
|
|||
#ifndef GAME_MWWORLD_CUSTOMDATA_H
|
||||
#define GAME_MWWORLD_CUSTOMDATA_H
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
class CreatureCustomData;
|
||||
class NpcCustomData;
|
||||
class ContainerCustomData;
|
||||
class DoorCustomData;
|
||||
class CreatureLevListCustomData;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
/// \brief Base class for the MW-class-specific part of RefData
|
||||
|
@ -11,6 +20,18 @@ namespace MWWorld
|
|||
virtual ~CustomData() {}
|
||||
|
||||
virtual CustomData *clone() const = 0;
|
||||
|
||||
// Fast version of dynamic_cast<X&>. Needs to be overridden in the respective class.
|
||||
|
||||
virtual MWClass::CreatureCustomData& asCreatureCustomData();
|
||||
|
||||
virtual MWClass::NpcCustomData& asNpcCustomData();
|
||||
|
||||
virtual MWClass::ContainerCustomData& asContainerCustomData();
|
||||
|
||||
virtual MWClass::DoorCustomData& asDoorCustomData();
|
||||
|
||||
virtual MWClass::CreatureLevListCustomData& asCreatureLevListCustomData();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue