diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 28305c394e..de560608c0 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -46,11 +46,6 @@ namespace MWClass mStore.readState(inventory); } - MWWorld::CustomData *ContainerCustomData::clone() const - { - return new ContainerCustomData (*this); - } - ContainerCustomData& ContainerCustomData::asContainerCustomData() { return *this; @@ -72,7 +67,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); // store - ptr.getRefData().setCustomData (std::make_unique(*ref->mBase, ptr.getCell()).release()); + ptr.getRefData().setCustomData (std::make_unique(*ref->mBase, ptr.getCell())); MWBase::Environment::get().getWorld()->addContainerScripts(ptr, ptr.getCell()); } @@ -317,7 +312,7 @@ namespace MWClass return; const ESM::ContainerState& containerState = state.asContainerState(); - ptr.getRefData().setCustomData(std::make_unique(containerState.mInventory).release()); + ptr.getRefData().setCustomData(std::make_unique(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 2dc0c06cae..1c89370068 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 { MWWorld::ContainerStore mStore; public: ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell); ContainerCustomData(const ESM::InventoryState& inventory); - 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 31341db730..6b8d2f3f25 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -51,14 +51,16 @@ namespace namespace MWClass { - class CreatureCustomData : public MWWorld::CustomData + class CreatureCustomData : public MWWorld::TypedCustomData { public: MWMechanics::CreatureStats mCreatureStats; - MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures + std::unique_ptr 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; CreatureCustomData& asCreatureCustomData() override { @@ -68,16 +70,13 @@ 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; } const Creature::GMST& Creature::getGmst() @@ -148,16 +147,16 @@ namespace MWClass // inventory bool hasInventory = hasInventoryStore(ptr); if (hasInventory) - data->mContainerStore = new MWWorld::InventoryStore(); + data->mContainerStore = std::make_unique(); else - data->mContainerStore = new MWWorld::ContainerStore(); + data->mContainerStore = std::make_unique(); 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 +757,11 @@ namespace MWClass std::unique_ptr data (new CreatureCustomData); if (hasInventoryStore(ptr)) - data->mContainerStore = new MWWorld::InventoryStore(); + data->mContainerStore = std::make_unique(); else - data->mContainerStore = new MWWorld::ContainerStore(); + data->mContainerStore = std::make_unique(); - 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 e3e52901e0..f86004c619 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 { public: // actorId of the creature we spawned int mSpawnActorId; bool mSpawn; // Should a new creature be spawned? - MWWorld::CustomData *clone() const override; - CreatureLevListCustomData& asCreatureLevListCustomData() override { return *this; @@ -29,11 +27,6 @@ namespace MWClass } }; - MWWorld::CustomData *CreatureLevListCustomData::clone() const - { - return new CreatureLevListCustomData (*this); - } - std::string CreatureLevList::getName (const MWWorld::ConstPtr& ptr) const { return ""; @@ -138,11 +131,11 @@ namespace MWClass { if (!ptr.getRefData().getCustomData()) { - std::unique_ptr data (new CreatureLevListCustomData); + std::unique_ptr data = std::make_unique(); 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 25f7fc4568..3a5ff0d9ae 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 { public: MWWorld::DoorState mDoorState = MWWorld::DoorState::Idle; - MWWorld::CustomData *clone() const override; - DoorCustomData& asDoorCustomData() override { return *this; @@ -48,11 +46,6 @@ namespace MWClass } }; - MWWorld::CustomData *DoorCustomData::clone() const - { - return new DoorCustomData (*this); - } - void Door::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { if (!model.empty()) @@ -327,8 +320,7 @@ namespace MWClass { if (!ptr.getRefData().getCustomData()) { - std::unique_ptr data(new DoorCustomData); - ptr.getRefData().setCustomData(data.release()); + ptr.getRefData().setCustomData(std::make_unique()); } } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 5de4c197e6..c5b352cb42 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 { public: MWMechanics::NpcStats mNpcStats; MWMechanics::Movement mMovement; MWWorld::InventoryStore mInventoryStore; - MWWorld::CustomData *clone() const override; - NpcCustomData& asNpcCustomData() override { return *this; @@ -265,11 +263,6 @@ namespace MWClass } }; - MWWorld::CustomData *NpcCustomData::clone() const - { - return new NpcCustomData (*this); - } - const Npc::GMST& Npc::getGmst() { static GMST gmst; @@ -397,7 +390,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 +1295,7 @@ namespace MWClass if (!ptr.getRefData().getCustomData()) { // Create a CustomData, but don't fill it from ESM records (not needed) - std::unique_ptr data (new NpcCustomData); - ptr.getRefData().setCustomData (data.release()); + ptr.getRefData().setCustomData(std::make_unique()); } } else diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 882f5efc44..bb8ca52737 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 clone() { return std::make_unique(*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 8af45e36ad..7200e7684c 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 + namespace MWClass { class CreatureCustomData; @@ -19,7 +21,7 @@ namespace MWWorld virtual ~CustomData() {} - virtual CustomData *clone() const = 0; + virtual std::unique_ptr clone() const = 0; // Fast version of dynamic_cast. Needs to be overridden in the respective class. @@ -38,6 +40,15 @@ namespace MWWorld virtual MWClass::CreatureLevListCustomData& asCreatureLevListCustomData(); virtual const MWClass::CreatureLevListCustomData& asCreatureLevListCustomData() const; }; + + template + struct TypedCustomData : CustomData + { + std::unique_ptr clone() const final + { + return std::make_unique(*static_cast(this)); + } + }; } #endif diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 6809e63b29..32dc0d2e91 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 clone() override { return std::make_unique(*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 71ff6d040d..f6a445d619 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&& 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 738a6d53a8..8979c8505d 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -5,8 +5,10 @@ #include #include "../mwscript/locals.hpp" +#include "../mwworld/customdata.hpp" #include +#include namespace SceneUtil { @@ -44,7 +46,7 @@ namespace MWWorld ESM::AnimationState mAnimationState; - CustomData *mCustomData; + std::unique_ptr mCustomData; void copy (const RefData& refData); @@ -68,6 +70,7 @@ namespace MWWorld /// perform these operations). RefData (const RefData& refData); + RefData (RefData&& other) noexcept = default; ~RefData(); @@ -76,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(); @@ -117,7 +121,7 @@ namespace MWWorld void setPosition (const ESM::Position& pos); const ESM::Position& getPosition() const; - void setCustomData (CustomData *data); + void setCustomData(std::unique_ptr&& value) noexcept; ///< Set custom data (potentially replacing old custom data). The ownership of \a data is /// transferred to this.