Do not use dynamic casts when using ObjectState

pull/2723/head
Andrei Kortunov 5 years ago
parent 1fadf259a9
commit dea2018d9f

@ -317,7 +317,6 @@ namespace MWClass
{
if (!state.mHasCustomState)
return;
const ESM::ContainerState& state2 = dynamic_cast<const ESM::ContainerState&> (state);
if (!ptr.getRefData().getCustomData())
{
@ -326,21 +325,21 @@ namespace MWClass
ptr.getRefData().setCustomData (data.release());
}
dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
readState (state2.mInventory);
ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData();
const ESM::ContainerState& containerState = state.asContainerState();
customData.mContainerStore.readState (containerState.mInventory);
}
void Container::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const
{
ESM::ContainerState& state2 = dynamic_cast<ESM::ContainerState&> (state);
if (!ptr.getRefData().getCustomData())
{
state.mHasCustomState = false;
return;
}
dynamic_cast<const ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
writeState (state2.mInventory);
const ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData();
ESM::ContainerState& containerState = state.asContainerState();
customData.mContainerStore.writeState (containerState.mInventory);
}
}

@ -776,8 +776,6 @@ namespace MWClass
if (!state.mHasCustomState)
return;
const ESM::CreatureState& state2 = dynamic_cast<const ESM::CreatureState&> (state);
if (state.mVersion > 0)
{
if (!ptr.getRefData().getCustomData())
@ -797,16 +795,14 @@ namespace MWClass
ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless.
CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData();
customData.mContainerStore->readState (state2.mInventory);
customData.mCreatureStats.readState (state2.mCreatureStats);
const ESM::CreatureState& creatureState = state.asCreatureState();
customData.mContainerStore->readState (creatureState.mInventory);
customData.mCreatureStats.readState (creatureState.mCreatureStats);
}
void Creature::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state)
const
{
ESM::CreatureState& state2 = dynamic_cast<ESM::CreatureState&> (state);
if (!ptr.getRefData().getCustomData())
{
state.mHasCustomState = false;
@ -814,9 +810,9 @@ namespace MWClass
}
const CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData();
customData.mContainerStore->writeState (state2.mInventory);
customData.mCreatureStats.writeState (state2.mCreatureStats);
ESM::CreatureState& creatureState = state.asCreatureState();
customData.mContainerStore->writeState (creatureState.mInventory);
customData.mCreatureStats.writeState (creatureState.mCreatureStats);
}
int Creature::getBaseGold(const MWWorld::ConstPtr& ptr) const

@ -151,19 +151,16 @@ namespace MWClass
if (!state.mHasCustomState)
return;
const ESM::CreatureLevListState& state2 = dynamic_cast<const ESM::CreatureLevListState&> (state);
ensureCustomData(ptr);
CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
customData.mSpawnActorId = state2.mSpawnActorId;
customData.mSpawn = state2.mSpawn;
const ESM::CreatureLevListState& levListState = state.asCreatureLevListState();
customData.mSpawnActorId = levListState.mSpawnActorId;
customData.mSpawn = levListState.mSpawn;
}
void CreatureLevList::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state)
const
{
ESM::CreatureLevListState& state2 = dynamic_cast<ESM::CreatureLevListState&> (state);
if (!ptr.getRefData().getCustomData())
{
state.mHasCustomState = false;
@ -171,7 +168,8 @@ namespace MWClass
}
const CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData();
state2.mSpawnActorId = customData.mSpawnActorId;
state2.mSpawn = customData.mSpawn;
ESM::CreatureLevListState& levListState = state.asCreatureLevListState();
levListState.mSpawnActorId = customData.mSpawnActorId;
levListState.mSpawn = customData.mSpawn;
}
}

@ -370,11 +370,11 @@ namespace MWClass
{
if (!state.mHasCustomState)
return;
ensureCustomData(ptr);
DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
const ESM::DoorState& state2 = dynamic_cast<const ESM::DoorState&>(state);
customData.mDoorState = static_cast<MWWorld::DoorState>(state2.mDoorState);
const ESM::DoorState& doorState = state.asDoorState();
customData.mDoorState = MWWorld::DoorState(doorState.mDoorState);
}
void Door::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const
@ -384,10 +384,10 @@ namespace MWClass
state.mHasCustomState = false;
return;
}
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
ESM::DoorState& state2 = dynamic_cast<ESM::DoorState&>(state);
state2.mDoorState = static_cast<int>(customData.mDoorState);
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
ESM::DoorState& doorState = state.asDoorState();
doorState.mDoorState = int(customData.mDoorState);
}
}

@ -1299,8 +1299,6 @@ namespace MWClass
if (!state.mHasCustomState)
return;
const ESM::NpcState& state2 = dynamic_cast<const ESM::NpcState&> (state);
if (state.mVersion > 0)
{
if (!ptr.getRefData().getCustomData())
@ -1314,17 +1312,15 @@ namespace MWClass
ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless.
NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData();
customData.mInventoryStore.readState (state2.mInventory);
customData.mNpcStats.readState (state2.mNpcStats);
static_cast<MWMechanics::CreatureStats&> (customData.mNpcStats).readState (state2.mCreatureStats);
const ESM::NpcState& npcState = state.asNpcState();
customData.mInventoryStore.readState (npcState.mInventory);
customData.mNpcStats.readState (npcState.mNpcStats);
customData.mNpcStats.readState (npcState.mCreatureStats);
}
void Npc::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state)
const
{
ESM::NpcState& state2 = dynamic_cast<ESM::NpcState&> (state);
if (!ptr.getRefData().getCustomData())
{
state.mHasCustomState = false;
@ -1332,10 +1328,10 @@ namespace MWClass
}
const NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData();
customData.mInventoryStore.writeState (state2.mInventory);
customData.mNpcStats.writeState (state2.mNpcStats);
static_cast<const MWMechanics::CreatureStats&> (customData.mNpcStats).writeState (state2.mCreatureStats);
ESM::NpcState& npcState = state.asNpcState();
customData.mInventoryStore.writeState (npcState.mInventory);
customData.mNpcStats.writeState (npcState.mNpcStats);
customData.mNpcStats.writeState (npcState.mCreatureStats);
}
int Npc::getBaseGold(const MWWorld::ConstPtr& ptr) const

@ -455,6 +455,11 @@ void MWMechanics::NpcStats::setTimeToStartDrowning(float time)
mTimeToStartDrowning=time;
}
void MWMechanics::NpcStats::writeState (ESM::CreatureStats& state) const
{
CreatureStats::writeState(state);
}
void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const
{
for (std::map<std::string, int>::const_iterator iter (mFactionRank.begin());
@ -494,6 +499,10 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const
state.mTimeToStartDrowning = mTimeToStartDrowning;
}
void MWMechanics::NpcStats::readState (const ESM::CreatureStats& state)
{
CreatureStats::readState(state);
}
void MWMechanics::NpcStats::readState (const ESM::NpcStats& state)
{

@ -127,8 +127,10 @@ namespace MWMechanics
/// @param time value from [0,20]
void setTimeToStartDrowning(float time);
void writeState (ESM::CreatureStats& state) const;
void writeState (ESM::NpcStats& state) const;
void readState (const ESM::CreatureStats& state);
void readState (const ESM::NpcStats& state);
};
}

@ -14,6 +14,15 @@ namespace ESM
virtual void load (ESMReader &esm);
virtual void save (ESMWriter &esm, bool inInventory = false) const;
virtual ContainerState& asContainerState()
{
return *this;
}
virtual const ContainerState& asContainerState() const
{
return *this;
}
};
}

@ -14,6 +14,15 @@ namespace ESM
virtual void load (ESMReader &esm);
virtual void save (ESMWriter &esm, bool inInventory = false) const;
virtual CreatureLevListState& asCreatureLevListState()
{
return *this;
}
virtual const CreatureLevListState& asCreatureLevListState() const
{
return *this;
}
};
}

@ -19,6 +19,15 @@ namespace ESM
virtual void load (ESMReader &esm);
virtual void save (ESMWriter &esm, bool inInventory = false) const;
virtual CreatureState& asCreatureState()
{
return *this;
}
virtual const CreatureState& asCreatureState() const
{
return *this;
}
};
}

@ -13,6 +13,15 @@ namespace ESM
virtual void load (ESMReader &esm);
virtual void save (ESMWriter &esm, bool inInventory = false) const;
virtual DoorState& asDoorState()
{
return *this;
}
virtual const DoorState& asDoorState() const
{
return *this;
}
};
}

@ -21,6 +21,15 @@ namespace ESM
virtual void load (ESMReader &esm);
virtual void save (ESMWriter &esm, bool inInventory = false) const;
virtual NpcState& asNpcState()
{
return *this;
}
virtual const NpcState& asNpcState() const
{
return *this;
}
};
}

@ -1,5 +1,9 @@
#include "objectstate.hpp"
#include <stdexcept>
#include <sstream>
#include <typeinfo>
#include "esmreader.hpp"
#include "esmwriter.hpp"
@ -84,4 +88,74 @@ void ESM::ObjectState::blank()
mHasCustomState = true;
}
const ESM::NpcState& ESM::ObjectState::asNpcState() const
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to NpcState";
throw std::logic_error(error.str());
}
ESM::NpcState& ESM::ObjectState::asNpcState()
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to NpcState";
throw std::logic_error(error.str());
}
const ESM::CreatureState& ESM::ObjectState::asCreatureState() const
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to CreatureState";
throw std::logic_error(error.str());
}
ESM::CreatureState& ESM::ObjectState::asCreatureState()
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to CreatureState";
throw std::logic_error(error.str());
}
const ESM::ContainerState& ESM::ObjectState::asContainerState() const
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to ContainerState";
throw std::logic_error(error.str());
}
ESM::ContainerState& ESM::ObjectState::asContainerState()
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to ContainerState";
throw std::logic_error(error.str());
}
const ESM::DoorState& ESM::ObjectState::asDoorState() const
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to DoorState";
throw std::logic_error(error.str());
}
ESM::DoorState& ESM::ObjectState::asDoorState()
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to DoorState";
throw std::logic_error(error.str());
}
const ESM::CreatureLevListState& ESM::ObjectState::asCreatureLevListState() const
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to CreatureLevListState";
throw std::logic_error(error.str());
}
ESM::CreatureLevListState& ESM::ObjectState::asCreatureLevListState()
{
std::stringstream error;
error << "bad cast " << typeid(this).name() << " to CreatureLevListState";
throw std::logic_error(error.str());
}
ESM::ObjectState::~ObjectState() {}

@ -12,6 +12,11 @@ namespace ESM
{
class ESMReader;
class ESMWriter;
struct ContainerState;
struct CreatureLevListState;
struct CreatureState;
struct DoorState;
struct NpcState;
// format 0, saved games only
@ -48,6 +53,21 @@ namespace ESM
void blank();
virtual ~ObjectState();
virtual const NpcState& asNpcState() const;
virtual NpcState& asNpcState();
virtual const CreatureState& asCreatureState() const;
virtual CreatureState& asCreatureState();
virtual const ContainerState& asContainerState() const;
virtual ContainerState& asContainerState();
virtual const DoorState& asDoorState() const;
virtual DoorState& asDoorState();
virtual const CreatureLevListState& asCreatureLevListState() const;
virtual CreatureLevListState& asCreatureLevListState();
};
}

Loading…
Cancel
Save