mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-30 02:56:44 +00:00 
			
		
		
		
	Optimize iteration over dialogue records
This commit is contained in:
		
							parent
							
								
									0233640124
								
							
						
					
					
						commit
						26233e082d
					
				
					 2 changed files with 29 additions and 105 deletions
				
			
		|  | @ -1,10 +1,11 @@ | ||||||
| #include "dialoguebindings.hpp" | #include "dialoguebindings.hpp" | ||||||
|  | 
 | ||||||
|  | #include "context.hpp" | ||||||
|  | 
 | ||||||
| #include "apps/openmw/mwbase/environment.hpp" | #include "apps/openmw/mwbase/environment.hpp" | ||||||
| #include "apps/openmw/mwworld/esmstore.hpp" | #include "apps/openmw/mwworld/esmstore.hpp" | ||||||
| #include "apps/openmw/mwworld/store.hpp" | #include "apps/openmw/mwworld/store.hpp" | ||||||
| #include "context.hpp" | 
 | ||||||
| #include "object.hpp" |  | ||||||
| #include <algorithm> |  | ||||||
| #include <components/esm3/loaddial.hpp> | #include <components/esm3/loaddial.hpp> | ||||||
| #include <components/lua/luastate.hpp> | #include <components/lua/luastate.hpp> | ||||||
| #include <components/misc/resourcehelpers.hpp> | #include <components/misc/resourcehelpers.hpp> | ||||||
|  | @ -12,122 +13,44 @@ | ||||||
| 
 | 
 | ||||||
| namespace | namespace | ||||||
| { | { | ||||||
|     template <ESM::Dialogue::Type filter> |     std::vector<const ESM::Dialogue*> makeIndex(const MWWorld::Store<ESM::Dialogue>& store, ESM::Dialogue::Type type) | ||||||
|     class FilteredDialogueStore |  | ||||||
|     { |     { | ||||||
|         const MWWorld::Store<ESM::Dialogue>& mDialogueStore; |         std::vector<const ESM::Dialogue*> result; | ||||||
| 
 |         for (const ESM::Dialogue& v : store) | ||||||
|         const ESM::Dialogue* foundDialogueFilteredOut(const ESM::Dialogue* possibleResult) const |             if (v.mType == type) | ||||||
|         { |                 result.push_back(&v); | ||||||
|             if (possibleResult && possibleResult->mType == filter) |  | ||||||
|             { |  | ||||||
|                 return possibleResult; |  | ||||||
|             } |  | ||||||
|             return nullptr; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     public: |  | ||||||
|         FilteredDialogueStore() |  | ||||||
|             : mDialogueStore{ MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>() } |  | ||||||
|         { |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         class FilteredDialogueIterator |  | ||||||
|         { |  | ||||||
|             using DecoratedIterator = MWWorld::Store<ESM::Dialogue>::iterator; |  | ||||||
|             DecoratedIterator mIter; |  | ||||||
|             DecoratedIterator mEndIter; |  | ||||||
| 
 |  | ||||||
|         public: |  | ||||||
|             using iterator_category = DecoratedIterator::iterator_category; |  | ||||||
|             using value_type = DecoratedIterator::value_type; |  | ||||||
|             using difference_type = DecoratedIterator::difference_type; |  | ||||||
|             using pointer = DecoratedIterator::pointer; |  | ||||||
|             using reference = DecoratedIterator::reference; |  | ||||||
| 
 |  | ||||||
|             FilteredDialogueIterator(const DecoratedIterator& pointingIterator, const DecoratedIterator& end) |  | ||||||
|                 : mIter{ pointingIterator } |  | ||||||
|                 , mEndIter{ end } |  | ||||||
|             { |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             FilteredDialogueIterator& operator++() |  | ||||||
|             { |  | ||||||
|                 if (mIter == mEndIter) |  | ||||||
|                 { |  | ||||||
|                     return *this; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 do |  | ||||||
|                 { |  | ||||||
|                     ++mIter; |  | ||||||
|                 } while (mIter != mEndIter && mIter->mType != filter); |  | ||||||
|                 return *this; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             FilteredDialogueIterator operator++(int) |  | ||||||
|             { |  | ||||||
|                 FilteredDialogueIterator iter = *this; |  | ||||||
|                 ++(*this); |  | ||||||
|                 return iter; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             FilteredDialogueIterator& operator+=(difference_type advance) |  | ||||||
|             { |  | ||||||
|                 while (advance > 0 && mIter != mEndIter) |  | ||||||
|                 { |  | ||||||
|                     ++(*this); |  | ||||||
|                     --advance; |  | ||||||
|                 } |  | ||||||
|                 return *this; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             bool operator==(const FilteredDialogueIterator& x) const { return mIter == x.mIter; } |  | ||||||
| 
 |  | ||||||
|             bool operator!=(const FilteredDialogueIterator& x) const { return !(*this == x); } |  | ||||||
| 
 |  | ||||||
|             const value_type& operator*() const { return *mIter; } |  | ||||||
| 
 |  | ||||||
|             const value_type* operator->() const { return &(*mIter); } |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         using iterator = FilteredDialogueIterator; |  | ||||||
| 
 |  | ||||||
|         const ESM::Dialogue* search(const ESM::RefId& id) const |  | ||||||
|         { |  | ||||||
|             return foundDialogueFilteredOut(mDialogueStore.search(id)); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         const ESM::Dialogue* at(size_t index) const |  | ||||||
|         { |  | ||||||
|             auto result = begin(); |  | ||||||
|             result += index; |  | ||||||
| 
 |  | ||||||
|             if (result == end()) |  | ||||||
|             { |  | ||||||
|                 return nullptr; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return &(*result); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         size_t getSize() const |  | ||||||
|         { |  | ||||||
|             return std::count_if( |  | ||||||
|                 mDialogueStore.begin(), mDialogueStore.end(), [](const auto& d) { return d.mType == filter; }); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         iterator begin() const |  | ||||||
|         { |  | ||||||
|             iterator result{ mDialogueStore.begin(), mDialogueStore.end() }; |  | ||||||
|             while (result != end() && result->mType != filter) |  | ||||||
|             { |  | ||||||
|                 ++result; |  | ||||||
|             } |  | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         iterator end() const { return iterator{ mDialogueStore.end(), mDialogueStore.end() }; } |     template <ESM::Dialogue::Type type> | ||||||
|  |     class FilteredDialogueStore | ||||||
|  |     { | ||||||
|  |         const MWWorld::Store<ESM::Dialogue>& mDialogueStore; | ||||||
|  |         std::vector<const ESM::Dialogue*> mIndex; | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  |         explicit FilteredDialogueStore(const MWWorld::Store<ESM::Dialogue>& store) | ||||||
|  |             : mDialogueStore(store) | ||||||
|  |             , mIndex{ makeIndex(store, type) } | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const ESM::Dialogue* search(const ESM::RefId& id) const | ||||||
|  |         { | ||||||
|  |             const ESM::Dialogue* dialogue = mDialogueStore.search(id); | ||||||
|  |             if (dialogue != nullptr && dialogue->mType == type) | ||||||
|  |                 return dialogue; | ||||||
|  |             return nullptr; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const ESM::Dialogue* at(std::size_t index) const | ||||||
|  |         { | ||||||
|  |             if (index >= mIndex.size()) | ||||||
|  |                 return nullptr; | ||||||
|  |             return mIndex[index]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         std::size_t getSize() const { return mIndex.size(); } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     template <ESM::Dialogue::Type filter> |     template <ESM::Dialogue::Type filter> | ||||||
|  | @ -156,7 +79,7 @@ namespace | ||||||
|         storeBindingsClass[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>(); |         storeBindingsClass[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>(); | ||||||
|         storeBindingsClass[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>(); |         storeBindingsClass[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>(); | ||||||
| 
 | 
 | ||||||
|         table["records"] = StoreT{}; |         table["records"] = StoreT{ MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>() }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     struct DialogueInfos |     struct DialogueInfos | ||||||
|  |  | ||||||
|  | @ -6,7 +6,8 @@ | ||||||
| namespace MWLua | namespace MWLua | ||||||
| { | { | ||||||
|     struct Context; |     struct Context; | ||||||
|     sol::table initCoreDialogueBindings(const Context&); | 
 | ||||||
|  |     sol::table initCoreDialogueBindings(const Context& context); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif // MWLUA_DIALOGUEBINDINGS_H
 | #endif // MWLUA_DIALOGUEBINDINGS_H
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue