From ecbde7b11e2d57eaf518a17600b0fd80ae79d110 Mon Sep 17 00:00:00 2001 From: Rafael Moura Date: Tue, 14 Feb 2017 19:34:54 +0000 Subject: [PATCH] Added ConstContainerStoreIterator using base template for ContainerStoreIterators less template arguments for ContainerStoreIteratorBase --- apps/openmw/mwclass/container.cpp | 2 +- apps/openmw/mwmechanics/character.hpp | 2 +- apps/openmw/mwworld/containerstore.cpp | 306 +++++++++++++++---------- apps/openmw/mwworld/containerstore.hpp | 218 +++++++++++------- apps/openmw/mwworld/ptr.cpp | 8 + apps/openmw/mwworld/ptr.hpp | 5 +- 6 files changed, 338 insertions(+), 203 deletions(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 47e24f0d6..333473216 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -145,7 +145,7 @@ namespace MWClass // make key id lowercase std::string keyId = ptr.getCellRef().getKey(); Misc::StringUtils::lowerCaseInPlace(keyId); - for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) + for (MWWorld::ConstContainerStoreIterator it = invStore.cbegin(); it != invStore.cend(); ++it) { std::string refId = it->getCellRef().getRefId(); Misc::StringUtils::lowerCaseInPlace(refId); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index f393f0619..9db127084 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -6,12 +6,12 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwrender/animation.hpp" namespace MWWorld { - class ContainerStoreIterator; class InventoryStore; } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 10388a3b0..c3c7f918d 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -127,6 +127,16 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() return ContainerStoreIterator (this); } +MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::cbegin (int mask) const +{ + return ConstContainerStoreIterator (mask, this); +} + +MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::cend() const +{ + return ConstContainerStoreIterator (this); +} + int MWWorld::ContainerStore::count(const std::string &id) { int total=0; @@ -788,53 +798,36 @@ void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory) mLevelledItemMap = inventory.mLevelledItemMap; } - -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container) -: mType (-1), mMask (0), mContainer (container) -{} - -MWWorld::ContainerStoreIterator::ContainerStoreIterator (int mask, ContainerStore *container) -: mType (0), mMask (mask), mContainer (container) +template +template +void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src) { - nextType(); - - if (mType==-1 || (**this).getRefData().getCount()) - return; - - ++*this; -} - -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Potion), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mPotion(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Apparatus), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mApparatus(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Armor), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mArmor(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Book), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mBook(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Clothing), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mClothing(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Ingredient), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mIngredient(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Light), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLight(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Lockpick), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLockpick(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Miscellaneous), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mMiscellaneous(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Probe), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mProbe(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Repair), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mRepair(iterator){} -MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator iterator) - : mType(MWWorld::ContainerStore::Type_Weapon), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mWeapon(iterator){} + mType = src.mType; + mMask = src.mMask; + mContainer = src.mContainer; + mPtr = src.mPtr; -MWWorld::ContainerStoreIterator::ContainerStoreIterator( const ContainerStoreIterator& src ) -{ - copy(src); + switch (src.mType) + { + case MWWorld::ContainerStore::Type_Potion: mPotion = src.mPotion; break; + case MWWorld::ContainerStore::Type_Apparatus: mApparatus = src.mApparatus; break; + case MWWorld::ContainerStore::Type_Armor: mArmor = src.mArmor; break; + case MWWorld::ContainerStore::Type_Book: mBook = src.mBook; break; + case MWWorld::ContainerStore::Type_Clothing: mClothing = src.mClothing; break; + case MWWorld::ContainerStore::Type_Ingredient: mIngredient = src.mIngredient; break; + case MWWorld::ContainerStore::Type_Light: mLight = src.mLight; break; + case MWWorld::ContainerStore::Type_Lockpick: mLockpick = src.mLockpick; break; + case MWWorld::ContainerStore::Type_Miscellaneous: mMiscellaneous = src.mMiscellaneous; break; + case MWWorld::ContainerStore::Type_Probe: mProbe = src.mProbe; break; + case MWWorld::ContainerStore::Type_Repair: mRepair = src.mRepair; break; + case MWWorld::ContainerStore::Type_Weapon: mWeapon = src.mWeapon; break; + case -1: break; + default: assert(0); + } } -void MWWorld::ContainerStoreIterator::incType() +template +void MWWorld::ContainerStoreIteratorBase::incType() { if (mType==0) mType = 1; @@ -847,7 +840,8 @@ void MWWorld::ContainerStoreIterator::incType() } } -void MWWorld::ContainerStoreIterator::nextType() +template +void MWWorld::ContainerStoreIteratorBase::nextType() { while (mType!=-1) { @@ -859,7 +853,8 @@ void MWWorld::ContainerStoreIterator::nextType() } } -bool MWWorld::ContainerStoreIterator::resetIterator() +template +bool MWWorld::ContainerStoreIteratorBase::resetIterator() { switch (mType) { @@ -927,7 +922,8 @@ bool MWWorld::ContainerStoreIterator::resetIterator() return false; } -bool MWWorld::ContainerStoreIterator::incIterator() +template +bool MWWorld::ContainerStoreIteratorBase::incIterator() { switch (mType) { @@ -995,30 +991,63 @@ bool MWWorld::ContainerStoreIterator::incIterator() return true; } -MWWorld::Ptr *MWWorld::ContainerStoreIterator::operator->() const + +template +template +bool MWWorld::ContainerStoreIteratorBase::isEqual (const ContainerStoreIteratorBase& other) const +{ + if (mContainer!=other.mContainer) + return false; + + if (mType!=other.mType) + return false; + + switch (mType) + { + case ContainerStore::Type_Potion: return mPotion==other.mPotion; + case ContainerStore::Type_Apparatus: return mApparatus==other.mApparatus; + case ContainerStore::Type_Armor: return mArmor==other.mArmor; + case ContainerStore::Type_Book: return mBook==other.mBook; + case ContainerStore::Type_Clothing: return mClothing==other.mClothing; + case ContainerStore::Type_Ingredient: return mIngredient==other.mIngredient; + case ContainerStore::Type_Light: return mLight==other.mLight; + case ContainerStore::Type_Lockpick: return mLockpick==other.mLockpick; + case ContainerStore::Type_Miscellaneous: return mMiscellaneous==other.mMiscellaneous; + case ContainerStore::Type_Probe: return mProbe==other.mProbe; + case ContainerStore::Type_Repair: return mRepair==other.mRepair; + case ContainerStore::Type_Weapon: return mWeapon==other.mWeapon; + case -1: return true; + } + + return false; +} + +template +PtrType *MWWorld::ContainerStoreIteratorBase::operator->() const { mPtr = **this; return &mPtr; } -MWWorld::Ptr MWWorld::ContainerStoreIterator::operator*() const +template +PtrType MWWorld::ContainerStoreIteratorBase::operator*() const { - Ptr ptr; + PtrType ptr; switch (mType) { - case ContainerStore::Type_Potion: ptr = MWWorld::Ptr (&*mPotion, 0); break; - case ContainerStore::Type_Apparatus: ptr = MWWorld::Ptr (&*mApparatus, 0); break; - case ContainerStore::Type_Armor: ptr = MWWorld::Ptr (&*mArmor, 0); break; - case ContainerStore::Type_Book: ptr = MWWorld::Ptr (&*mBook, 0); break; - case ContainerStore::Type_Clothing: ptr = MWWorld::Ptr (&*mClothing, 0); break; - case ContainerStore::Type_Ingredient: ptr = MWWorld::Ptr (&*mIngredient, 0); break; - case ContainerStore::Type_Light: ptr = MWWorld::Ptr (&*mLight, 0); break; - case ContainerStore::Type_Lockpick: ptr = MWWorld::Ptr (&*mLockpick, 0); break; - case ContainerStore::Type_Miscellaneous: ptr = MWWorld::Ptr (&*mMiscellaneous, 0); break; - case ContainerStore::Type_Probe: ptr = MWWorld::Ptr (&*mProbe, 0); break; - case ContainerStore::Type_Repair: ptr = MWWorld::Ptr (&*mRepair, 0); break; - case ContainerStore::Type_Weapon: ptr = MWWorld::Ptr (&*mWeapon, 0); break; + case ContainerStore::Type_Potion: ptr = PtrType (&*mPotion, 0); break; + case ContainerStore::Type_Apparatus: ptr = PtrType (&*mApparatus, 0); break; + case ContainerStore::Type_Armor: ptr = PtrType (&*mArmor, 0); break; + case ContainerStore::Type_Book: ptr = PtrType (&*mBook, 0); break; + case ContainerStore::Type_Clothing: ptr = PtrType (&*mClothing, 0); break; + case ContainerStore::Type_Ingredient: ptr = PtrType (&*mIngredient, 0); break; + case ContainerStore::Type_Light: ptr = PtrType (&*mLight, 0); break; + case ContainerStore::Type_Lockpick: ptr = PtrType (&*mLockpick, 0); break; + case ContainerStore::Type_Miscellaneous: ptr = PtrType (&*mMiscellaneous, 0); break; + case ContainerStore::Type_Probe: ptr = PtrType (&*mProbe, 0); break; + case ContainerStore::Type_Repair: ptr = PtrType (&*mRepair, 0); break; + case ContainerStore::Type_Weapon: ptr = PtrType (&*mWeapon, 0); break; } if (ptr.isEmpty()) @@ -1029,7 +1058,8 @@ MWWorld::Ptr MWWorld::ContainerStoreIterator::operator*() const return ptr; } -MWWorld::ContainerStoreIterator& MWWorld::ContainerStoreIterator::operator++() +template +MWWorld::ContainerStoreIteratorBase& MWWorld::ContainerStoreIteratorBase::operator++() { do { @@ -1041,92 +1071,126 @@ MWWorld::ContainerStoreIterator& MWWorld::ContainerStoreIterator::operator++() return *this; } -MWWorld::ContainerStoreIterator MWWorld::ContainerStoreIterator::operator++ (int) +template +MWWorld::ContainerStoreIteratorBase MWWorld::ContainerStoreIteratorBase::operator++ (int) { - ContainerStoreIterator iter (*this); + ContainerStoreIteratorBase iter (*this); ++*this; return iter; } -bool MWWorld::ContainerStoreIterator::isEqual (const ContainerStoreIterator& iter) const +template +MWWorld::ContainerStoreIteratorBase& MWWorld::ContainerStoreIteratorBase::operator= (const ContainerStoreIteratorBase& rhs) { - if (mContainer!=iter.mContainer) - return false; - - if (mType!=iter.mType) - return false; - - switch (mType) + if (this!=&rhs) { - case ContainerStore::Type_Potion: return mPotion==iter.mPotion; - case ContainerStore::Type_Apparatus: return mApparatus==iter.mApparatus; - case ContainerStore::Type_Armor: return mArmor==iter.mArmor; - case ContainerStore::Type_Book: return mBook==iter.mBook; - case ContainerStore::Type_Clothing: return mClothing==iter.mClothing; - case ContainerStore::Type_Ingredient: return mIngredient==iter.mIngredient; - case ContainerStore::Type_Light: return mLight==iter.mLight; - case ContainerStore::Type_Lockpick: return mLockpick==iter.mLockpick; - case ContainerStore::Type_Miscellaneous: return mMiscellaneous==iter.mMiscellaneous; - case ContainerStore::Type_Probe: return mProbe==iter.mProbe; - case ContainerStore::Type_Repair: return mRepair==iter.mRepair; - case ContainerStore::Type_Weapon: return mWeapon==iter.mWeapon; - case -1: return true; + copy(rhs); } - - return false; + return *this; } -int MWWorld::ContainerStoreIterator::getType() const +template +int MWWorld::ContainerStoreIteratorBase::getType() const { return mType; } -const MWWorld::ContainerStore *MWWorld::ContainerStoreIterator::getContainerStore() const +template +const MWWorld::ContainerStore *MWWorld::ContainerStoreIteratorBase::getContainerStore() const { return mContainer; } -void MWWorld::ContainerStoreIterator::copy(const ContainerStoreIterator& src) +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container) +: mType (-1), mMask (0), mContainer (container) +{} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (int mask, ContainerStoreType container) +: mType (0), mMask (mask), mContainer (container) { - mType = src.mType; - mMask = src.mMask; - mContainer = src.mContainer; - mPtr = src.mPtr; + nextType(); - switch (mType) - { - case MWWorld::ContainerStore::Type_Potion: mPotion = src.mPotion; break; - case MWWorld::ContainerStore::Type_Apparatus: mApparatus = src.mApparatus; break; - case MWWorld::ContainerStore::Type_Armor: mArmor = src.mArmor; break; - case MWWorld::ContainerStore::Type_Book: mBook = src.mBook; break; - case MWWorld::ContainerStore::Type_Clothing: mClothing = src.mClothing; break; - case MWWorld::ContainerStore::Type_Ingredient: mIngredient = src.mIngredient; break; - case MWWorld::ContainerStore::Type_Light: mLight = src.mLight; break; - case MWWorld::ContainerStore::Type_Lockpick: mLockpick = src.mLockpick; break; - case MWWorld::ContainerStore::Type_Miscellaneous: mMiscellaneous = src.mMiscellaneous; break; - case MWWorld::ContainerStore::Type_Probe: mProbe = src.mProbe; break; - case MWWorld::ContainerStore::Type_Repair: mRepair = src.mRepair; break; - case MWWorld::ContainerStore::Type_Weapon: mWeapon = src.mWeapon; break; - case -1: break; - default: assert(0); - } -} + if (mType==-1 || (**this).getRefData().getCount()) + return; -MWWorld::ContainerStoreIterator& MWWorld::ContainerStoreIterator::operator=( const ContainerStoreIterator& rhs ) -{ - if (this!=&rhs) - { - copy(rhs); - } - return *this; + ++*this; } -bool MWWorld::operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right) +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Potion), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mPotion(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Apparatus), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mApparatus(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Armor), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mArmor(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Book), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mBook(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Clothing), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mClothing(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Ingredient), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mIngredient(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Light), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLight(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Lockpick), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLockpick(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Miscellaneous), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mMiscellaneous(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Probe), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mProbe(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Repair), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mRepair(iterator){} + +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Weapon), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mWeapon(iterator){} + + +template +bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right) { return left.isEqual (right); } -bool MWWorld::operator!= (const ContainerStoreIterator& left, const ContainerStoreIterator& right) +template +bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right) { return !(left==right); } + +template class MWWorld::ContainerStoreIteratorBase; +template class MWWorld::ContainerStoreIteratorBase; + +template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); + +template void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src); +template void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src); +template void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 0c95d2dba..c10b87fda 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -29,8 +29,15 @@ namespace ESM namespace MWWorld { - class ContainerStoreIterator; + class ContainerStore; + template + class ContainerStoreIteratorBase; + + typedef ContainerStoreIteratorBase ContainerStoreIterator; + typedef ContainerStoreIteratorBase ConstContainerStoreIterator; + + class ContainerStoreListener { public: @@ -70,7 +77,7 @@ namespace MWWorld MWWorld::CellRefList clothes; MWWorld::CellRefList ingreds; MWWorld::CellRefList lights; - MWWorld::CellRefList lockpicks; + MWWorld::CellRefList lockpicks; MWWorld::CellRefList miscItems; MWWorld::CellRefList probes; MWWorld::CellRefList repairs; @@ -99,9 +106,11 @@ namespace MWWorld ESM::InventoryState& inventory, int& index, bool equipable = false) const; + virtual void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const; virtual void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory); + public: ContainerStore(); @@ -114,6 +123,10 @@ namespace MWWorld ContainerStoreIterator end(); + ConstContainerStoreIterator cbegin (int mask = Type_All) const; + + ConstContainerStoreIterator cend() const; + virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool setOwner=false); ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) /// @@ -187,96 +200,143 @@ namespace MWWorld virtual void readState (const ESM::InventoryState& state); - friend class ContainerStoreIterator; + friend class ContainerStoreIteratorBase; + friend class ContainerStoreIteratorBase; }; - /// \brief Iteration over a subset of objects in a ContainerStore - /// - /// \note The iterator will automatically skip over deleted objects. - class ContainerStoreIterator - : public std::iterator + + template + class ContainerStoreIteratorBase + : public std::iterator { - int mType; - int mMask; - ContainerStore *mContainer; - mutable Ptr mPtr; - - MWWorld::CellRefList::List::iterator mPotion; - MWWorld::CellRefList::List::iterator mApparatus; - MWWorld::CellRefList::List::iterator mArmor; - MWWorld::CellRefList::List::iterator mBook; - MWWorld::CellRefList::List::iterator mClothing; - MWWorld::CellRefList::List::iterator mIngredient; - MWWorld::CellRefList::List::iterator mLight; - MWWorld::CellRefList::List::iterator mLockpick; - MWWorld::CellRefList::List::iterator mMiscellaneous; - MWWorld::CellRefList::List::iterator mProbe; - MWWorld::CellRefList::List::iterator mRepair; - MWWorld::CellRefList::List::iterator mWeapon; - - private: - - ContainerStoreIterator (ContainerStore *container); - ///< End-iterator - - ContainerStoreIterator (int mask, ContainerStore *container); - ///< Begin-iterator - - // construct iterator using a CellRefList iterator - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList::List::iterator); - - void copy (const ContainerStoreIterator& src); - - void incType(); - - void nextType(); - - bool resetIterator(); - ///< Reset iterator for selected type. - /// - /// \return Type not empty? - - bool incIterator(); - ///< Increment iterator for selected type. - /// - /// \return reached the end? + template + struct IsConvertible + { + static const bool value = true; + }; + + template + struct IsConvertible + { + static const bool value = false; + }; + + template + struct IteratorTrait + { + typedef typename MWWorld::CellRefList::List::iterator type; + }; + + template + struct IteratorTrait + { + typedef typename MWWorld::CellRefList::List::const_iterator type; + }; + + template + struct Iterator : IteratorTrait + { + }; + + template + struct ContainerStoreTrait + { + typedef ContainerStore* type; + }; + + template + struct ContainerStoreTrait + { + typedef const ContainerStore* type; + }; + + typedef typename ContainerStoreTrait::type ContainerStoreType; + + int mType; + int mMask; + ContainerStoreType mContainer; + mutable PtrType mPtr; + + typename Iterator::type mPotion; + typename Iterator::type mApparatus; + typename Iterator::type mArmor; + typename Iterator::type mBook; + typename Iterator::type mClothing; + typename Iterator::type mIngredient; + typename Iterator::type mLight; + typename Iterator::type mLockpick; + typename Iterator::type mMiscellaneous; + typename Iterator::type mProbe; + typename Iterator::type mRepair; + typename Iterator::type mWeapon; + + ContainerStoreIteratorBase (ContainerStoreType container); + ///< End-iterator + + ContainerStoreIteratorBase (int mask, ContainerStoreType container); + ///< Begin-iterator + + // construct iterator using a CellRefList iterator + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); + + template + void copy (const ContainerStoreIteratorBase& src); + + void incType (); + + void nextType (); + + bool resetIterator (); + ///< Reset iterator for selected type. + /// + /// \return Type not empty? + + bool incIterator (); + ///< Increment iterator for selected type. + /// + /// \return reached the end? public: + template + ContainerStoreIteratorBase (const ContainerStoreIteratorBase& other) + { + char CANNOT_CONVERT_CONST_ITERATOR_TO_ITERATOR[IsConvertible::value ? 1 : -1]; + ((void)CANNOT_CONVERT_CONST_ITERATOR_TO_ITERATOR); + copy (other); + } - ContainerStoreIterator(const ContainerStoreIterator& src); - - Ptr *operator->() const; + template + bool isEqual(const ContainerStoreIteratorBase& other) const; - Ptr operator*() const; + PtrType *operator->() const; + PtrType operator*() const; - ContainerStoreIterator& operator++(); - - ContainerStoreIterator operator++ (int); - - ContainerStoreIterator& operator= (const ContainerStoreIterator& rhs); - - bool isEqual (const ContainerStoreIterator& iter) const; + ContainerStoreIteratorBase& operator++ (); + ContainerStoreIteratorBase operator++ (int); + ContainerStoreIteratorBase& operator= (const ContainerStoreIteratorBase& rhs); int getType() const; - const ContainerStore *getContainerStore() const; - friend class ContainerStore; + friend class ContainerStore; + friend class ContainerStoreIteratorBase; + friend class ContainerStoreIteratorBase; }; - bool operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right); - bool operator!= (const ContainerStoreIterator& left, const ContainerStoreIterator& right); + template + bool operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); + template + bool operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); } - #endif diff --git a/apps/openmw/mwworld/ptr.cpp b/apps/openmw/mwworld/ptr.cpp index 01e7be1d1..12c44b0b3 100644 --- a/apps/openmw/mwworld/ptr.cpp +++ b/apps/openmw/mwworld/ptr.cpp @@ -70,6 +70,14 @@ const MWWorld::LiveCellRefBase *MWWorld::ConstPtr::getBase() const return mRef; } +void MWWorld::ConstPtr::setContainerStore (const ContainerStore *store) +{ + assert (store); + assert (!mCell); + + mContainerStore = store; +} + const MWWorld::ContainerStore *MWWorld::ConstPtr::getContainerStore() const { return mContainerStore; diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index d34f516a7..d7c170e45 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -158,7 +158,10 @@ namespace MWWorld { return (mContainerStore == 0) && (mCell != 0); } - + + void setContainerStore (const ContainerStore *store); + ///< Must not be called on references that are in a cell. + const ContainerStore *getContainerStore() const; ///< May return a 0-pointer, if reference is not in a container.