From 3dcfcf46cbb3f4b446e27234e2be3361744ad50e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 21 Mar 2012 12:48:05 +0100 Subject: [PATCH] Issue #217: container change tracking --- apps/openmw/mwworld/containerstore.cpp | 18 ++++++++++++++++++ apps/openmw/mwworld/containerstore.hpp | 12 ++++++++++++ apps/openmw/mwworld/inventorystore.cpp | 2 ++ apps/openmw/mwworld/ptr.cpp | 10 ++++++++++ 4 files changed, 42 insertions(+) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 8991f41655..243d5c3516 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -9,6 +9,8 @@ #include "manualref.hpp" +MWWorld::ContainerStore::ContainerStore() : mStateId (0) {} + MWWorld::ContainerStore::~ContainerStore() {} MWWorld::ContainerStoreIterator MWWorld::ContainerStore::begin (int mask) @@ -40,6 +42,8 @@ void MWWorld::ContainerStore::add (const Ptr& ptr) case Type_Repair: repairs.list.push_back (*ptr.get()); break; case Type_Weapon: weapons.list.push_back (*ptr.get()); break; } + + flagAsModified(); } void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const ESMS::ESMStore& store) @@ -58,6 +62,8 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const ESMS: ref.getPtr().getRefData().setCount (iter->count); add (ref.getPtr()); } + + flagAsModified(); } void MWWorld::ContainerStore::clear() @@ -74,6 +80,18 @@ void MWWorld::ContainerStore::clear() probes.list.clear(); repairs.list.clear(); weapons.list.clear(); + + flagAsModified(); +} + +void MWWorld::ContainerStore::flagAsModified() +{ + ++mStateId; +} + +int MWWorld::ContainerStore::getStateId() const +{ + return mStateId; } int MWWorld::ContainerStore::getType (const Ptr& ptr) diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 69e5ba4466..669b394ca8 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -52,9 +52,12 @@ namespace MWWorld ESMS::CellRefList probes; ESMS::CellRefList repairs; ESMS::CellRefList weapons; + int mStateId; public: + ContainerStore(); + virtual ~ContainerStore(); ContainerStoreIterator begin (int mask = Type_All); @@ -75,6 +78,15 @@ namespace MWWorld void clear(); ///< Empty container. + void flagAsModified(); + ///< \attention This function is internal to the world model and should not be called from + /// outside. + + int getStateId() const; + ///< This ID is changed every time the container is modified or items in the container + /// are accessed in a way that may be used to modify the item. + /// \note This method of change-tracking will ocasionally yield false positives. + static int getType (const Ptr& ptr); ///< This function throws an exception, if ptr does not point to an object, that can be /// put into a container. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 264be7bb33..e64c9785f4 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -65,6 +65,8 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite /// \todo unstack item pointed to by iterator if required) mSlots[slot] = iterator; + + flagAsModified(); } MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) diff --git a/apps/openmw/mwworld/ptr.cpp b/apps/openmw/mwworld/ptr.cpp index abe08609be..7c0010c044 100644 --- a/apps/openmw/mwworld/ptr.cpp +++ b/apps/openmw/mwworld/ptr.cpp @@ -3,15 +3,25 @@ #include +#include "containerstore.hpp" + ESM::CellRef& MWWorld::Ptr::getCellRef() const { assert (mCellRef); + + if (mContainerStore) + mContainerStore->flagAsModified(); + return *mCellRef; } MWWorld::RefData& MWWorld::Ptr::getRefData() const { assert (mRefData); + + if (mContainerStore) + mContainerStore->flagAsModified(); + return *mRefData; }