mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 04:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			77 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "esmdata.hpp"
 | |
| #include "lessbyid.hpp"
 | |
| #include "record.hpp"
 | |
| 
 | |
| #include <components/esm/defs.hpp>
 | |
| #include <components/esm3/loadacti.hpp>
 | |
| #include <components/esm3/loadcont.hpp>
 | |
| #include <components/esm3/loaddoor.hpp>
 | |
| #include <components/esm3/loadgmst.hpp>
 | |
| #include <components/esm3/loadland.hpp>
 | |
| #include <components/esm3/loadstat.hpp>
 | |
| #include <components/esm3/variant.hpp>
 | |
| #include <components/misc/strings/lower.hpp>
 | |
| 
 | |
| #include <algorithm>
 | |
| #include <stdexcept>
 | |
| #include <string>
 | |
| #include <string_view>
 | |
| #include <type_traits>
 | |
| #include <utility>
 | |
| #include <vector>
 | |
| 
 | |
| namespace EsmLoader
 | |
| {
 | |
|     namespace
 | |
|     {
 | |
|         template <class F>
 | |
|         auto returnAs(F&& f)
 | |
|         {
 | |
|             using Result = decltype(std::forward<F>(f)(ESM::Static {}));
 | |
|             if constexpr (!std::is_same_v<Result, void>)
 | |
|                 return Result {};
 | |
|         }
 | |
| 
 | |
|         template <class T, class F>
 | |
|         auto withStatic(std::string_view refId, const std::vector<T>& values, F&& f)
 | |
|         {
 | |
|             const auto it = std::lower_bound(values.begin(), values.end(), refId, LessById {});
 | |
| 
 | |
|             if (it == values.end() || it->mId != refId)
 | |
|                 return returnAs(std::forward<F>(f));
 | |
| 
 | |
|             return std::forward<F>(f)(*it);
 | |
|         }
 | |
| 
 | |
|         template <class F>
 | |
|         auto withStatic(std::string_view refId, ESM::RecNameInts type, const EsmData& content, F&& f)
 | |
|         {
 | |
|             switch (type)
 | |
|             {
 | |
|                 case ESM::REC_ACTI: return withStatic(refId, content.mActivators, std::forward<F>(f));
 | |
|                 case ESM::REC_CONT: return withStatic(refId, content.mContainers, std::forward<F>(f));
 | |
|                 case ESM::REC_DOOR: return withStatic(refId, content.mDoors, std::forward<F>(f));
 | |
|                 case ESM::REC_STAT: return withStatic(refId, content.mStatics, std::forward<F>(f));
 | |
|                 default: break;
 | |
|             }
 | |
| 
 | |
|             return returnAs(std::forward<F>(f));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     EsmData::~EsmData() {}
 | |
| 
 | |
|     std::string_view getModel(const EsmData& content, std::string_view refId, ESM::RecNameInts type)
 | |
|     {
 | |
|         return withStatic(refId, type, content, [] (const auto& v) { return std::string_view(v.mModel); });
 | |
|     }
 | |
| 
 | |
|     ESM::Variant getGameSetting(const std::vector<ESM::GameSetting>& records, std::string_view id)
 | |
|     {
 | |
|         const std::string lower = Misc::StringUtils::lowerCase(id);
 | |
|         auto it = std::lower_bound(records.begin(), records.end(), lower, LessById {});
 | |
|         if (it == records.end() || it->mId != lower)
 | |
|             throw std::runtime_error("Game settings \"" + std::string(id) + "\" is not found");
 | |
|         return it->mValue;
 | |
|     }
 | |
| }
 |