mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 07:56:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			90 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef COMPONENTS_ESM_ESMBRIDGE
 | |
| #define COMPONENTS_ESM_ESMBRIDGE
 | |
| 
 | |
| #include <string>
 | |
| #include <string_view>
 | |
| #include <variant>
 | |
| 
 | |
| #include <components/esm3/cellref.hpp>
 | |
| #include <components/esm4/loadachr.hpp>
 | |
| #include <components/esm4/loadrefr.hpp>
 | |
| 
 | |
| namespace ESM4
 | |
| {
 | |
|     struct Cell;
 | |
| }
 | |
| 
 | |
| namespace ESM
 | |
| {
 | |
|     struct Cell;
 | |
|     class RefId;
 | |
| 
 | |
|     class CellVariant;
 | |
| 
 | |
|     template <class, class T>
 | |
|     using Substitute = T;
 | |
| 
 | |
|     template <class F, class... T>
 | |
|     using VisitReturnType = std::enable_if_t<(std::is_base_of_v<CellVariant, std::decay_t<T>> && ...),
 | |
|         typename std::invoke_result<F, Substitute<T, const Cell&>...>::type>;
 | |
| 
 | |
|     class CellVariant
 | |
|     {
 | |
|     protected:
 | |
|         std::variant<const ESM4::Cell*, const ESM::Cell*> mVariant;
 | |
| 
 | |
|     public:
 | |
|         explicit CellVariant(const ESM4::Cell& cell)
 | |
|             : mVariant(&cell)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         explicit CellVariant(const ESM::Cell& cell)
 | |
|             : mVariant(&cell)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         bool isEsm4() const { return std::holds_alternative<const ESM4::Cell*>(mVariant); }
 | |
|         const ESM4::Cell& getEsm4() const;
 | |
|         const ESM::Cell& getEsm3() const;
 | |
| 
 | |
|         template <class F, class... T>
 | |
|         friend VisitReturnType<F, T...> visit(F&& f, T&&... v);
 | |
|     };
 | |
| 
 | |
|     struct ReferenceVariant
 | |
|     {
 | |
|         std::variant<ESM::CellRef, ESM4::Reference, ESM4::ActorCharacter> mVariant;
 | |
| 
 | |
|         explicit ReferenceVariant(const ESM4::Reference& ref)
 | |
|             : mVariant(ref)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         explicit ReferenceVariant(const ESM4::ActorCharacter& ref)
 | |
|             : mVariant(ref)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         explicit ReferenceVariant(const ESM::CellRef& ref)
 | |
|             : mVariant(ref)
 | |
|         {
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     template <class F, class... T>
 | |
|     VisitReturnType<F, T...> visit(F&& f, T&&... v)
 | |
|     {
 | |
|         return std::visit([&](auto*... ptr) { return std::forward<F>(f)(*ptr...); }, std::forward<T>(v).mVariant...);
 | |
|     }
 | |
| 
 | |
|     template <class... Ts>
 | |
|     struct VisitOverload : Ts...
 | |
|     {
 | |
|         using Ts::operator()...;
 | |
|     };
 | |
| 
 | |
|     template <class... Ts>
 | |
|     VisitOverload(Ts...) -> VisitOverload<Ts...>;
 | |
| }
 | |
| #endif
 |