hnOsmium0001

registry

Oct 12th, 2020
1,163
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include <cstdint>
  3. #include <functional>
  4. #include <limits>
  5. #include <memory>
  6. #include <queue>
  7. #include <string_view>
  8. #include <unordered_map>
  9. #include <utility>
  10.  
  11. constexpr unsigned int INVALID_REGISTRY_ID = std::numeric_limits<unsigned int>::max();
  12.  
  13. template <class T>
  14. class RonlyRegistry {
  15. protected:
  16.     std::unordered_map<std::string_view, T*> mLookup;
  17.     std::vector<std::unique_ptr<T>> mContents;
  18.  
  19. public:
  20.     auto Lookup(std::string_view name) -> T* {
  21.         auto iter = mLookup.find(name);
  22.         if (iter != mLookup.end()) {
  23.             return iter->second;
  24.         } else {
  25.             return nullptr;
  26.         }
  27.     }
  28.  
  29.     auto Lookup(unsigned int id) -> T* {
  30.         if (id < mContents.size()) {
  31.             return mContents[id].get();
  32.         } else {
  33.             return nullptr;
  34.         }
  35.     }
  36.  
  37.     __declspec(property(get = GetLookupTable)) std::unordered_map<std::string_view, T*> const& LookupTable;
  38.     auto GetLookupTable() const -> std::unordered_map<std::string_view, T*> const& {
  39.         return mLookup;
  40.     }
  41. };
  42.  
  43. template <class T>
  44. class RwRegistry : public RonlyRegistry<T> {
  45. protected:
  46.     std::queue<unsigned int> mUnusedIDs;
  47.  
  48. public:
  49.     auto Register(T value) -> std::pair<unsigned int, T*> {
  50.         if (mLookup.find(value.Name) != mLookup.end()) {
  51.             // Register failed, entry with name already exists
  52.             return { 0, nullptr };
  53.         }
  54.  
  55.         if (mUnusedIDs.empty()) {
  56.             mContents.push_back(std::unique_ptr<T>(new T(std::move(value))));
  57.  
  58.             T* ref = mContents.back().get();
  59.             mLookup.insert({ ref->Name, ref });
  60.  
  61.             return { static_cast<unsigned int>(mContents.size() - 1), ref };
  62.         } else {
  63.             unsigned int id = mUnusedIDs.front();
  64.             mUnusedIDs.pop();
  65.  
  66.             mContents[id] = std::unique_ptr<T>(new T(std::move(value)));
  67.  
  68.             T* ref = mContents[id].get();
  69.             mLookup.insert({ ref->Name, ref });
  70.  
  71.             return { id, ref };
  72.         }
  73.     }
  74.  
  75.     auto Unregister(unsigned int id) -> void {
  76.         if (id >= mContents.size()) return;
  77.         if (auto& content = mContents[id]) {
  78.             mLookup.erase(content.Name);
  79.             mContents.erase(id);
  80.             mUnusedIDs.push(id);
  81.         }
  82.     }
  83.  
  84.     auto Unregister(std::string_view name) -> void {
  85.         auto iter = mLookup.find(name);
  86.         if (iter == mLookup.end()) {
  87.             return;
  88.         }
  89.  
  90.         auto& content = *iter->second;
  91.         // Only erases lookup, `content` is still valid
  92.         mLookup.erase(name);
  93.         unsigned int id = content.TypeId;
  94.         mContents[id] = nullptr;
  95.         mUnusedIDs.push(id);
  96.     }
  97. };
  98.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×