From 045bb7cbd7d206f9de9e4b624aa6dd6dc0d4d55a Mon Sep 17 00:00:00 2001 From: elsid <elsid.mail@gmail.com> Date: Sat, 3 Apr 2021 00:48:35 +0200 Subject: [PATCH 1/3] Store CustomData and ContainerStore as unique_ptr --- apps/openmw/mwclass/container.cpp | 8 +++--- apps/openmw/mwclass/container.hpp | 2 +- apps/openmw/mwclass/creature.cpp | 36 ++++++++++++++----------- apps/openmw/mwclass/creaturelevlist.cpp | 10 +++---- apps/openmw/mwclass/door.cpp | 9 +++---- apps/openmw/mwclass/npc.cpp | 11 ++++---- apps/openmw/mwworld/containerstore.hpp | 2 +- apps/openmw/mwworld/customdata.hpp | 4 ++- apps/openmw/mwworld/inventorystore.hpp | 2 +- apps/openmw/mwworld/refdata.cpp | 11 +++----- apps/openmw/mwworld/refdata.hpp | 5 ++-- 11 files changed, 52 insertions(+), 48 deletions(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 28305c394..2d7f30047 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -46,9 +46,9 @@ namespace MWClass mStore.readState(inventory); } - MWWorld::CustomData *ContainerCustomData::clone() const + std::unique_ptr<MWWorld::CustomData> ContainerCustomData::clone() const { - return new ContainerCustomData (*this); + return std::make_unique<ContainerCustomData>(*this); } ContainerCustomData& ContainerCustomData::asContainerCustomData() @@ -72,7 +72,7 @@ namespace MWClass MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>(); // store - ptr.getRefData().setCustomData (std::make_unique<ContainerCustomData>(*ref->mBase, ptr.getCell()).release()); + ptr.getRefData().setCustomData (std::make_unique<ContainerCustomData>(*ref->mBase, ptr.getCell())); MWBase::Environment::get().getWorld()->addContainerScripts(ptr, ptr.getCell()); } @@ -317,7 +317,7 @@ namespace MWClass return; const ESM::ContainerState& containerState = state.asContainerState(); - ptr.getRefData().setCustomData(std::make_unique<ContainerCustomData>(containerState.mInventory).release()); + ptr.getRefData().setCustomData(std::make_unique<ContainerCustomData>(containerState.mInventory)); } void Container::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 2dc0c06ca..fc3e046f1 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -20,7 +20,7 @@ namespace MWClass ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell); ContainerCustomData(const ESM::InventoryState& inventory); - MWWorld::CustomData *clone() const override; + std::unique_ptr<MWWorld::CustomData> clone() const override; ContainerCustomData& asContainerCustomData() override; const ContainerCustomData& asContainerCustomData() const override; diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 31341db73..2a55fb9fd 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -55,10 +55,14 @@ namespace MWClass { public: MWMechanics::CreatureStats mCreatureStats; - MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures + std::unique_ptr<MWWorld::ContainerStore> mContainerStore; // may be InventoryStore for some creatures MWMechanics::Movement mMovement; - MWWorld::CustomData *clone() const override; + CreatureCustomData() = default; + CreatureCustomData(const CreatureCustomData& other); + CreatureCustomData(CreatureCustomData&& other) noexcept = default; + + std::unique_ptr<MWWorld::CustomData> clone() const override; CreatureCustomData& asCreatureCustomData() override { @@ -68,16 +72,18 @@ namespace MWClass { return *this; } - - CreatureCustomData() : mContainerStore(nullptr) {} - virtual ~CreatureCustomData() { delete mContainerStore; } }; - MWWorld::CustomData *CreatureCustomData::clone() const + CreatureCustomData::CreatureCustomData(const CreatureCustomData& other) + : mCreatureStats(other.mCreatureStats), + mContainerStore(other.mContainerStore->clone()), + mMovement(other.mMovement) { - CreatureCustomData* cloned = new CreatureCustomData (*this); - cloned->mContainerStore = mContainerStore->clone(); - return cloned; + } + + std::unique_ptr<MWWorld::CustomData> CreatureCustomData::clone() const + { + return std::make_unique<CreatureCustomData>(*this); } const Creature::GMST& Creature::getGmst() @@ -148,16 +154,16 @@ namespace MWClass // inventory bool hasInventory = hasInventoryStore(ptr); if (hasInventory) - data->mContainerStore = new MWWorld::InventoryStore(); + data->mContainerStore = std::make_unique<MWWorld::InventoryStore>(); else - data->mContainerStore = new MWWorld::ContainerStore(); + data->mContainerStore = std::make_unique<MWWorld::ContainerStore>(); data->mCreatureStats.setGoldPool(ref->mBase->mData.mGold); data->mCreatureStats.setNeedRecalcDynamicStats(false); // store - ptr.getRefData().setCustomData(data.release()); + ptr.getRefData().setCustomData(std::move(data)); getContainerStore(ptr).fill(ref->mBase->mInventory, ptr.getCellRef().getRefId()); @@ -758,11 +764,11 @@ namespace MWClass std::unique_ptr<CreatureCustomData> data (new CreatureCustomData); if (hasInventoryStore(ptr)) - data->mContainerStore = new MWWorld::InventoryStore(); + data->mContainerStore = std::make_unique<MWWorld::InventoryStore>(); else - data->mContainerStore = new MWWorld::ContainerStore(); + data->mContainerStore = std::make_unique<MWWorld::ContainerStore>(); - ptr.getRefData().setCustomData (data.release()); + ptr.getRefData().setCustomData (std::move(data)); } } else diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index e3e52901e..3b401f1a3 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -17,7 +17,7 @@ namespace MWClass int mSpawnActorId; bool mSpawn; // Should a new creature be spawned? - MWWorld::CustomData *clone() const override; + std::unique_ptr<MWWorld::CustomData> clone() const override; CreatureLevListCustomData& asCreatureLevListCustomData() override { @@ -29,9 +29,9 @@ namespace MWClass } }; - MWWorld::CustomData *CreatureLevListCustomData::clone() const + std::unique_ptr<MWWorld::CustomData> CreatureLevListCustomData::clone() const { - return new CreatureLevListCustomData (*this); + return std::make_unique<CreatureLevListCustomData>(*this); } std::string CreatureLevList::getName (const MWWorld::ConstPtr& ptr) const @@ -138,11 +138,11 @@ namespace MWClass { if (!ptr.getRefData().getCustomData()) { - std::unique_ptr<CreatureLevListCustomData> data (new CreatureLevListCustomData); + std::unique_ptr<CreatureLevListCustomData> data = std::make_unique<CreatureLevListCustomData>(); data->mSpawnActorId = -1; data->mSpawn = true; - ptr.getRefData().setCustomData(data.release()); + ptr.getRefData().setCustomData(std::move(data)); } } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 25f7fc456..ae8085586 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -36,7 +36,7 @@ namespace MWClass public: MWWorld::DoorState mDoorState = MWWorld::DoorState::Idle; - MWWorld::CustomData *clone() const override; + std::unique_ptr<MWWorld::CustomData> clone() const override; DoorCustomData& asDoorCustomData() override { @@ -48,9 +48,9 @@ namespace MWClass } }; - MWWorld::CustomData *DoorCustomData::clone() const + std::unique_ptr<MWWorld::CustomData> DoorCustomData::clone() const { - return new DoorCustomData (*this); + return std::make_unique<DoorCustomData>(*this); } void Door::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const @@ -327,8 +327,7 @@ namespace MWClass { if (!ptr.getRefData().getCustomData()) { - std::unique_ptr<DoorCustomData> data(new DoorCustomData); - ptr.getRefData().setCustomData(data.release()); + ptr.getRefData().setCustomData(std::make_unique<DoorCustomData>()); } } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 5de4c197e..248ef5d01 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -253,7 +253,7 @@ namespace MWClass MWMechanics::Movement mMovement; MWWorld::InventoryStore mInventoryStore; - MWWorld::CustomData *clone() const override; + std::unique_ptr<MWWorld::CustomData> clone() const override; NpcCustomData& asNpcCustomData() override { @@ -265,9 +265,9 @@ namespace MWClass } }; - MWWorld::CustomData *NpcCustomData::clone() const + std::unique_ptr<MWWorld::CustomData> NpcCustomData::clone() const { - return new NpcCustomData (*this); + return std::make_unique<NpcCustomData>(*this); } const Npc::GMST& Npc::getGmst() @@ -397,7 +397,7 @@ namespace MWClass data->mNpcStats.setGoldPool(gold); // store - ptr.getRefData().setCustomData (data.release()); + ptr.getRefData().setCustomData(std::move(data)); getInventoryStore(ptr).autoEquip(ptr); } @@ -1302,8 +1302,7 @@ namespace MWClass if (!ptr.getRefData().getCustomData()) { // Create a CustomData, but don't fill it from ESM records (not needed) - std::unique_ptr<NpcCustomData> data (new NpcCustomData); - ptr.getRefData().setCustomData (data.release()); + ptr.getRefData().setCustomData(std::make_unique<NpcCustomData>()); } } else diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 882f5efc4..bb8ca5273 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -153,7 +153,7 @@ namespace MWWorld virtual ~ContainerStore(); - virtual ContainerStore* clone() { return new ContainerStore(*this); } + virtual std::unique_ptr<ContainerStore> clone() { return std::make_unique<ContainerStore>(*this); } ConstContainerStoreIterator cbegin (int mask = Type_All) const; ConstContainerStoreIterator cend() const; diff --git a/apps/openmw/mwworld/customdata.hpp b/apps/openmw/mwworld/customdata.hpp index 8af45e36a..ee89dd2a8 100644 --- a/apps/openmw/mwworld/customdata.hpp +++ b/apps/openmw/mwworld/customdata.hpp @@ -1,6 +1,8 @@ #ifndef GAME_MWWORLD_CUSTOMDATA_H #define GAME_MWWORLD_CUSTOMDATA_H +#include <memory> + namespace MWClass { class CreatureCustomData; @@ -19,7 +21,7 @@ namespace MWWorld virtual ~CustomData() {} - virtual CustomData *clone() const = 0; + virtual std::unique_ptr<CustomData> clone() const = 0; // Fast version of dynamic_cast<X&>. Needs to be overridden in the respective class. diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 6809e63b2..32dc0d2e9 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -123,7 +123,7 @@ namespace MWWorld InventoryStore& operator= (const InventoryStore& store); - InventoryStore* clone() override { return new InventoryStore(*this); } + std::unique_ptr<ContainerStore> clone() override { return std::make_unique<InventoryStore>(*this); } ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true, bool resolve = true) override; ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index 71ff6d040..f6a445d61 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -40,8 +40,6 @@ namespace MWWorld void RefData::cleanup() { mBaseNode = nullptr; - - delete mCustomData; mCustomData = nullptr; } @@ -223,21 +221,20 @@ namespace MWWorld return mPosition; } - void RefData::setCustomData (CustomData *data) + void RefData::setCustomData(std::unique_ptr<CustomData>&& value) noexcept { mChanged = true; // We do not currently track CustomData, so assume anything with a CustomData is changed - delete mCustomData; - mCustomData = data; + mCustomData = std::move(value); } CustomData *RefData::getCustomData() { - return mCustomData; + return mCustomData.get(); } const CustomData *RefData::getCustomData() const { - return mCustomData; + return mCustomData.get(); } bool RefData::hasChanged() const diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 738a6d53a..5419a261b 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -7,6 +7,7 @@ #include "../mwscript/locals.hpp" #include <string> +#include <memory> namespace SceneUtil { @@ -44,7 +45,7 @@ namespace MWWorld ESM::AnimationState mAnimationState; - CustomData *mCustomData; + std::unique_ptr<CustomData> mCustomData; void copy (const RefData& refData); @@ -117,7 +118,7 @@ namespace MWWorld void setPosition (const ESM::Position& pos); const ESM::Position& getPosition() const; - void setCustomData (CustomData *data); + void setCustomData(std::unique_ptr<CustomData>&& value) noexcept; ///< Set custom data (potentially replacing old custom data). The ownership of \a data is /// transferred to this. From e380470558a1d810d7e5cd51c09a31ace376c1e6 Mon Sep 17 00:00:00 2001 From: elsid <elsid.mail@gmail.com> Date: Sat, 3 Apr 2021 00:49:14 +0200 Subject: [PATCH 2/3] Add move ctor and assignment operator to RefData --- apps/openmw/mwworld/refdata.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 5419a261b..8979c8505 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -5,6 +5,7 @@ #include <components/esm/animationstate.hpp> #include "../mwscript/locals.hpp" +#include "../mwworld/customdata.hpp" #include <string> #include <memory> @@ -69,6 +70,7 @@ namespace MWWorld /// perform these operations). RefData (const RefData& refData); + RefData (RefData&& other) noexcept = default; ~RefData(); @@ -77,6 +79,7 @@ namespace MWWorld /// perform this operations). RefData& operator= (const RefData& refData); + RefData& operator= (RefData&& other) noexcept = default; /// Return base node (can be a null pointer). SceneUtil::PositionAttitudeTransform* getBaseNode(); From bd33fa76b63536398e00ba416d3289a44beaf461 Mon Sep 17 00:00:00 2001 From: elsid <elsid.mail@gmail.com> Date: Sat, 3 Apr 2021 12:59:44 +0200 Subject: [PATCH 3/3] Use CRTP to define CustomData clone function --- apps/openmw/mwclass/container.cpp | 5 ----- apps/openmw/mwclass/container.hpp | 4 +--- apps/openmw/mwclass/creature.cpp | 9 +-------- apps/openmw/mwclass/creaturelevlist.cpp | 9 +-------- apps/openmw/mwclass/door.cpp | 9 +-------- apps/openmw/mwclass/npc.cpp | 9 +-------- apps/openmw/mwworld/customdata.hpp | 9 +++++++++ 7 files changed, 14 insertions(+), 40 deletions(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 2d7f30047..de560608c 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -46,11 +46,6 @@ namespace MWClass mStore.readState(inventory); } - std::unique_ptr<MWWorld::CustomData> ContainerCustomData::clone() const - { - return std::make_unique<ContainerCustomData>(*this); - } - ContainerCustomData& ContainerCustomData::asContainerCustomData() { return *this; diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index fc3e046f1..1c8937006 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -13,15 +13,13 @@ namespace ESM namespace MWClass { - class ContainerCustomData : public MWWorld::CustomData + class ContainerCustomData : public MWWorld::TypedCustomData<ContainerCustomData> { MWWorld::ContainerStore mStore; public: ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell); ContainerCustomData(const ESM::InventoryState& inventory); - std::unique_ptr<MWWorld::CustomData> clone() const override; - ContainerCustomData& asContainerCustomData() override; const ContainerCustomData& asContainerCustomData() const override; diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 2a55fb9fd..6b8d2f3f2 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -51,7 +51,7 @@ namespace namespace MWClass { - class CreatureCustomData : public MWWorld::CustomData + class CreatureCustomData : public MWWorld::TypedCustomData<CreatureCustomData> { public: MWMechanics::CreatureStats mCreatureStats; @@ -62,8 +62,6 @@ namespace MWClass CreatureCustomData(const CreatureCustomData& other); CreatureCustomData(CreatureCustomData&& other) noexcept = default; - std::unique_ptr<MWWorld::CustomData> clone() const override; - CreatureCustomData& asCreatureCustomData() override { return *this; @@ -81,11 +79,6 @@ namespace MWClass { } - std::unique_ptr<MWWorld::CustomData> CreatureCustomData::clone() const - { - return std::make_unique<CreatureCustomData>(*this); - } - const Creature::GMST& Creature::getGmst() { static GMST gmst; diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index 3b401f1a3..f86004c61 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -10,15 +10,13 @@ namespace MWClass { - class CreatureLevListCustomData : public MWWorld::CustomData + class CreatureLevListCustomData : public MWWorld::TypedCustomData<CreatureLevListCustomData> { public: // actorId of the creature we spawned int mSpawnActorId; bool mSpawn; // Should a new creature be spawned? - std::unique_ptr<MWWorld::CustomData> clone() const override; - CreatureLevListCustomData& asCreatureLevListCustomData() override { return *this; @@ -29,11 +27,6 @@ namespace MWClass } }; - std::unique_ptr<MWWorld::CustomData> CreatureLevListCustomData::clone() const - { - return std::make_unique<CreatureLevListCustomData>(*this); - } - std::string CreatureLevList::getName (const MWWorld::ConstPtr& ptr) const { return ""; diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index ae8085586..3a5ff0d9a 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -31,13 +31,11 @@ namespace MWClass { - class DoorCustomData : public MWWorld::CustomData + class DoorCustomData : public MWWorld::TypedCustomData<DoorCustomData> { public: MWWorld::DoorState mDoorState = MWWorld::DoorState::Idle; - std::unique_ptr<MWWorld::CustomData> clone() const override; - DoorCustomData& asDoorCustomData() override { return *this; @@ -48,11 +46,6 @@ namespace MWClass } }; - std::unique_ptr<MWWorld::CustomData> DoorCustomData::clone() const - { - return std::make_unique<DoorCustomData>(*this); - } - void Door::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { if (!model.empty()) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 248ef5d01..c5b352cb4 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -246,15 +246,13 @@ namespace namespace MWClass { - class NpcCustomData : public MWWorld::CustomData + class NpcCustomData : public MWWorld::TypedCustomData<NpcCustomData> { public: MWMechanics::NpcStats mNpcStats; MWMechanics::Movement mMovement; MWWorld::InventoryStore mInventoryStore; - std::unique_ptr<MWWorld::CustomData> clone() const override; - NpcCustomData& asNpcCustomData() override { return *this; @@ -265,11 +263,6 @@ namespace MWClass } }; - std::unique_ptr<MWWorld::CustomData> NpcCustomData::clone() const - { - return std::make_unique<NpcCustomData>(*this); - } - const Npc::GMST& Npc::getGmst() { static GMST gmst; diff --git a/apps/openmw/mwworld/customdata.hpp b/apps/openmw/mwworld/customdata.hpp index ee89dd2a8..7200e7684 100644 --- a/apps/openmw/mwworld/customdata.hpp +++ b/apps/openmw/mwworld/customdata.hpp @@ -40,6 +40,15 @@ namespace MWWorld virtual MWClass::CreatureLevListCustomData& asCreatureLevListCustomData(); virtual const MWClass::CreatureLevListCustomData& asCreatureLevListCustomData() const; }; + + template <class T> + struct TypedCustomData : CustomData + { + std::unique_ptr<CustomData> clone() const final + { + return std::make_unique<T>(*static_cast<const T*>(this)); + } + }; } #endif