Add CellStore::forEachType to help with porting over game logic to the new interfaces

This commit is contained in:
scrawl 2015-12-06 20:19:07 +01:00
parent 0af33b5abd
commit a517f4f9ba

View file

@ -116,15 +116,6 @@ namespace MWWorld
/// Repopulate mMergedRefs. /// Repopulate mMergedRefs.
void updateMergedRefs(); void updateMergedRefs();
template<typename T>
LiveCellRefBase* insertBase(CellRefList<T>& list, const LiveCellRef<T>* ref)
{
mHasState = true;
LiveCellRefBase* ret = &list.insert(*ref);
updateMergedRefs();
return ret;
}
// helper function for forEachInternal // helper function for forEachInternal
template<class Visitor, class List> template<class Visitor, class List>
bool forEachImp (Visitor& visitor, List& list) bool forEachImp (Visitor& visitor, List& list)
@ -167,6 +158,11 @@ namespace MWWorld
forEachImp (visitor, mCreatureLists); forEachImp (visitor, mCreatureLists);
} }
/// @note If you get a linker error here, this means the given type can not be stored in a cell. The supported types are
/// defined at the bottom of this file.
template <class T>
CellRefList<T>& get();
public: public:
/// Moves object from this cell to the given cell. /// Moves object from this cell to the given cell.
@ -179,7 +175,14 @@ namespace MWWorld
/// @note If you get a linker error here, this means the given type can not be inserted into a cell. /// @note If you get a linker error here, this means the given type can not be inserted into a cell.
/// The supported types are defined at the bottom of this file. /// The supported types are defined at the bottom of this file.
template <typename T> template <typename T>
LiveCellRefBase* insert(const LiveCellRef<T>* ref); LiveCellRefBase* insert(const LiveCellRef<T>* ref)
{
mHasState = true;
CellRefList<T>& list = get<T>();
LiveCellRefBase* ret = &list.insert(*ref);
updateMergedRefs();
return ret;
}
/// @param readerList The readers to use for loading of the cell on-demand. /// @param readerList The readers to use for loading of the cell on-demand.
CellStore (const ESM::Cell *cell_, CellStore (const ESM::Cell *cell_,
@ -246,6 +249,41 @@ namespace MWWorld
return true; return true;
} }
/// Call visitor (ref) for each reference of given type. visitor must return a bool. Returning
/// false will abort the iteration.
/// \attention This function also lists deleted (count 0) objects!
/// \return Iteration completed?
template <class T, class Visitor>
bool forEachType(Visitor& visitor)
{
if (mState != State_Loaded)
return false;
mHasState = true;
CellRefList<T>& list = get<T>();
for (typename CellRefList<T>::List::iterator it (list.mList.begin()); it!=list.mList.end(); ++it)
{
LiveCellRefBase* base = &*it;
if (mMovedToAnotherCell.find(base) != mMovedToAnotherCell.end())
continue;
if (base->mData.isDeletedByContentFile())
continue;
if (!visitor(MWWorld::Ptr(base, this)))
return false;
}
for (MovedRefTracker::const_iterator it = mMovedHere.begin(); it != mMovedHere.end(); ++it)
{
LiveCellRefBase* base = it->first;
if (dynamic_cast<LiveCellRef<T>*>(base))
if (!visitor(MWWorld::Ptr(base, this)))
return false;
}
return true;
}
/// \todo add const version of forEach /// \todo add const version of forEach
bool isExterior() const; bool isExterior() const;
@ -295,104 +333,143 @@ namespace MWWorld
}; };
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Activator>(const LiveCellRef<ESM::Activator>* ref) inline CellRefList<ESM::Activator>& CellStore::get<ESM::Activator>()
{ {
return insertBase(mActivators, ref); mHasState = true;
return mActivators;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Potion>(const LiveCellRef<ESM::Potion>* ref) inline CellRefList<ESM::Potion>& CellStore::get<ESM::Potion>()
{ {
return insertBase(mPotions, ref); mHasState = true;
return mPotions;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Apparatus>(const LiveCellRef<ESM::Apparatus>* ref) inline CellRefList<ESM::Apparatus>& CellStore::get<ESM::Apparatus>()
{ {
return insertBase(mAppas, ref); mHasState = true;
return mAppas;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Armor>(const LiveCellRef<ESM::Armor>* ref) inline CellRefList<ESM::Armor>& CellStore::get<ESM::Armor>()
{ {
return insertBase(mArmors, ref); mHasState = true;
return mArmors;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Book>(const LiveCellRef<ESM::Book>* ref) inline CellRefList<ESM::Book>& CellStore::get<ESM::Book>()
{ {
return insertBase(mBooks, ref); mHasState = true;
return mBooks;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Clothing>(const LiveCellRef<ESM::Clothing>* ref) inline CellRefList<ESM::Clothing>& CellStore::get<ESM::Clothing>()
{ {
return insertBase(mClothes, ref); mHasState = true;
return mClothes;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Container>(const LiveCellRef<ESM::Container>* ref) inline CellRefList<ESM::Container>& CellStore::get<ESM::Container>()
{ {
return insertBase(mContainers, ref); mHasState = true;
return mContainers;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Creature>(const LiveCellRef<ESM::Creature>* ref) inline CellRefList<ESM::Creature>& CellStore::get<ESM::Creature>()
{ {
return insertBase(mCreatures, ref); mHasState = true;
return mCreatures;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Door>(const LiveCellRef<ESM::Door>* ref) inline CellRefList<ESM::Door>& CellStore::get<ESM::Door>()
{ {
return insertBase(mDoors, ref); mHasState = true;
return mDoors;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Ingredient>(const LiveCellRef<ESM::Ingredient>* ref) inline CellRefList<ESM::Ingredient>& CellStore::get<ESM::Ingredient>()
{ {
return insertBase(mIngreds, ref); mHasState = true;
return mIngreds;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::CreatureLevList>(const LiveCellRef<ESM::CreatureLevList>* ref) inline CellRefList<ESM::CreatureLevList>& CellStore::get<ESM::CreatureLevList>()
{ {
return insertBase(mCreatureLists, ref); mHasState = true;
return mCreatureLists;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::ItemLevList>(const LiveCellRef<ESM::ItemLevList>* ref) inline CellRefList<ESM::ItemLevList>& CellStore::get<ESM::ItemLevList>()
{ {
return insertBase(mItemLists, ref); mHasState = true;
return mItemLists;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Light>(const LiveCellRef<ESM::Light>* ref) inline CellRefList<ESM::Light>& CellStore::get<ESM::Light>()
{ {
return insertBase(mLights, ref); mHasState = true;
return mLights;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Lockpick>(const LiveCellRef<ESM::Lockpick>* ref) inline CellRefList<ESM::Lockpick>& CellStore::get<ESM::Lockpick>()
{ {
return insertBase(mLockpicks, ref); mHasState = true;
return mLockpicks;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Miscellaneous>(const LiveCellRef<ESM::Miscellaneous>* ref) inline CellRefList<ESM::Miscellaneous>& CellStore::get<ESM::Miscellaneous>()
{ {
return insertBase(mMiscItems, ref); mHasState = true;
return mMiscItems;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::NPC>(const LiveCellRef<ESM::NPC>* ref) inline CellRefList<ESM::NPC>& CellStore::get<ESM::NPC>()
{ {
return insertBase(mNpcs, ref); mHasState = true;
return mNpcs;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Probe>(const LiveCellRef<ESM::Probe>* ref) inline CellRefList<ESM::Probe>& CellStore::get<ESM::Probe>()
{ {
return insertBase(mProbes, ref); mHasState = true;
return mProbes;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Repair>(const LiveCellRef<ESM::Repair>* ref) inline CellRefList<ESM::Repair>& CellStore::get<ESM::Repair>()
{ {
return insertBase(mRepairs, ref); mHasState = true;
return mRepairs;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Static>(const LiveCellRef<ESM::Static>* ref) inline CellRefList<ESM::Static>& CellStore::get<ESM::Static>()
{ {
return insertBase(mStatics, ref); mHasState = true;
return mStatics;
} }
template<> template<>
inline LiveCellRefBase* CellStore::insert<ESM::Weapon>(const LiveCellRef<ESM::Weapon>* ref) inline CellRefList<ESM::Weapon>& CellStore::get<ESM::Weapon>()
{ {
return insertBase(mWeapons, ref); mHasState = true;
return mWeapons;
} }
bool operator== (const CellStore& left, const CellStore& right); bool operator== (const CellStore& left, const CellStore& right);