neptools

Modding tools to Neptunia games
git clone https://git.neptards.moe/neptards/neptools.git
Log | Files | Refs | Submodules | README | LICENSE

item_base.hpp (3640B)


      1 #ifndef UUID_02043882_EC07_4CCA_BD13_1BB9F5C7DB9F
      2 #define UUID_02043882_EC07_4CCA_BD13_1BB9F5C7DB9F
      3 #pragma once
      4 
      5 #include "../utils.hpp"
      6 
      7 #include <libshit/assert.hpp>
      8 #include <libshit/meta.hpp>
      9 #include <libshit/shared_ptr.hpp>
     10 #include <libshit/utils.hpp>
     11 #include <libshit/container/intrusive.hpp>
     12 #include <libshit/lua/dynamic_object.hpp>
     13 #include <libshit/lua/function_call_types.hpp>
     14 #include <libshit/lua/type_traits.hpp>
     15 
     16 #include <cstdint>
     17 #include <functional>
     18 #include <boost/intrusive/set_hook.hpp>
     19 
     20 namespace Neptools LIBSHIT_META("alias_file src/format/item.hpp")
     21 {
     22 
     23   class Item;
     24   class Context;
     25 
     26   struct ItemPointer
     27   {
     28     Item* item;
     29     FilePosition offset;
     30 
     31     ItemPointer(Item* item, FilePosition offset = 0)
     32       : item{item}, offset{offset} {}
     33     ItemPointer(Item& item, FilePosition offset = 0)
     34       : item{&item}, offset{offset} {}
     35 
     36     bool operator==(const ItemPointer& o) const
     37     { return item == o.item && offset == o.offset; }
     38     bool operator!=(const ItemPointer& o) const
     39     { return item != o.item || offset != o.offset; }
     40 
     41     Item& operator*() const { return *item; }
     42     Item* operator->() const { return &*item; }
     43 
     44     template <typename T>
     45     T& As() const { return *Libshit::asserted_cast<T*>(item); }
     46 
     47     template <typename T>
     48     T& AsChecked() const { return dynamic_cast<T&>(*item); }
     49 
     50     template <typename T>
     51     T* Maybe() const { return dynamic_cast<T*>(item); }
     52 
     53     template <typename T>
     54     T& As0() const
     55     {
     56       LIBSHIT_ASSERT(offset == 0);
     57       return *Libshit::asserted_cast<T*>(item);
     58     }
     59 
     60     template <typename T>
     61     T& AsChecked0() const
     62     {
     63       LIBSHIT_ASSERT(offset == 0);
     64       return dynamic_cast<T&>(*item);
     65     }
     66 
     67     template <typename T>
     68     T* Maybe0() const
     69     {
     70       LIBSHIT_ASSERT(offset == 0);
     71       return dynamic_cast<T*>(item);
     72     }
     73   };
     74 
     75   using LabelNameHook = boost::intrusive::set_base_hook<
     76     boost::intrusive::tag<struct NameTag>,
     77     boost::intrusive::optimize_size<true>, Libshit::LinkMode>;
     78   using LabelOffsetHook = boost::intrusive::set_base_hook<
     79     boost::intrusive::tag<struct OffsetTag>,
     80     boost::intrusive::optimize_size<true>, Libshit::LinkMode>;
     81 
     82   class Label final :
     83        public Libshit::RefCounted, public Libshit::Lua::DynamicObject,
     84        public LabelNameHook, public LabelOffsetHook
     85   {
     86     LIBSHIT_DYNAMIC_OBJECT;
     87   public:
     88 
     89     Label(std::string name, ItemPointer ptr)
     90       : name{std::move(name)}, ptr{ptr} {}
     91 
     92     const std::string& GetName() const { return name; }
     93     const ItemPointer& GetPtr() const { return ptr; }
     94 
     95     friend class Context;
     96     friend class Item;
     97   private:
     98     std::string name;
     99     ItemPointer ptr;
    100   };
    101 
    102   using LabelPtr = Libshit::RefCountedPtr<Label>;
    103   using WeakLabelPtr = Libshit::WeakRefCountedPtr<Label>;
    104 
    105   // to be used by boost::intrusive::set
    106   struct LabelKeyOfValue
    107   {
    108     using type = std::string;
    109     const type& operator()(const Label& l) { return l.GetName(); }
    110   };
    111 
    112   struct LabelOffsetKeyOfValue
    113   {
    114     using type = FilePosition;
    115     const type& operator()(const Label& l) { return l.GetPtr().offset; }
    116   };
    117 
    118 }
    119 
    120 
    121 template<> struct Libshit::Lua::TupleLike<Neptools::ItemPointer>
    122 {
    123   template <size_t I> static auto& Get(
    124     const Neptools::ItemPointer& ptr) noexcept
    125   {
    126     if constexpr (I == 0) return *ptr.item;
    127     else if constexpr (I == 1) return ptr.offset;
    128   }
    129   static constexpr size_t SIZE = 2;
    130 };
    131 
    132 template<> struct std::hash<::Neptools::ItemPointer>
    133 {
    134   std::size_t operator()(const ::Neptools::ItemPointer& ptr) const
    135   {
    136     return hash<::Neptools::Item*>()(ptr.item) ^
    137       hash<::Neptools::FilePosition>()(ptr.offset);
    138   }
    139 };
    140 
    141 #endif