summaryrefslogtreecommitdiff
path: root/core/src/Model/Items.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/Model/Items.hpp')
-rw-r--r--core/src/Model/Items.hpp253
1 files changed, 0 insertions, 253 deletions
diff --git a/core/src/Model/Items.hpp b/core/src/Model/Items.hpp
deleted file mode 100644
index 859aedf..0000000
--- a/core/src/Model/Items.hpp
+++ /dev/null
@@ -1,253 +0,0 @@
-#pragma once
-
-#include "cplt_fwd.hpp"
-
-#include <json/reader.h>
-#include <json/value.h>
-#include <json/writer.h>
-#include <tsl/array_map.h>
-#include <cstddef>
-#include <limits>
-#include <stdexcept>
-#include <string>
-#include <string_view>
-#include <utility>
-#include <vector>
-
-template <class T>
-class ItemList
-{
-private:
- std::vector<T> mStorage;
- tsl::array_map<char, size_t> mNameLookup;
-
-public:
- template <class... Args>
- T& Insert(std::string name, Args... args)
- {
- auto iter = mNameLookup.find(name);
- if (iter != mNameLookup.end()) {
- throw std::runtime_error("Duplicate key.");
- }
-
- for (size_t i = 0; i < mStorage.size(); ++i) {
- if (mStorage[i].IsInvalid()) {
- mStorage[i] = T(*this, i, std::move(name), std::forward<Args>(args)...);
- mNameLookup.insert(name, i);
- return mStorage[i];
- }
- }
-
- size_t id = mStorage.size();
- mNameLookup.insert(name, id);
- mStorage.emplace_back(*this, id, std::move(name), std::forward<Args>(args)...);
- return mStorage[id];
- }
-
- void Remove(size_t index)
- {
- auto& item = mStorage[index];
- mNameLookup.erase(item.GetName());
- mStorage[index] = T(*this);
- }
-
- T* Find(size_t id)
- {
- return &mStorage[id];
- }
-
- const T* Find(size_t id) const
- {
- return &mStorage[id];
- }
-
- const T* Find(std::string_view name) const
- {
- auto iter = mNameLookup.find(name);
- if (iter != mNameLookup.end()) {
- return &mStorage[iter.value()];
- } else {
- return nullptr;
- }
- }
-
- Json::Value Serialize() const
- {
- Json::Value items(Json::arrayValue);
- for (auto& item : mStorage) {
- if (!item.IsInvalid()) {
- auto elm = item.Serialize();
- elm["Id"] = item.GetId();
- elm["Name"] = item.GetName();
- items.append(elm);
- }
- }
-
- Json::Value root;
- root["MaxItemId"] = mStorage.size();
- root["Items"] = std::move(items);
-
- return root;
- }
-
- ItemList() = default;
-
- ItemList(const Json::Value& root)
- {
- constexpr const char* kMessage = "Failed to load item list from JSON.";
-
- auto& itemCount = root["MaxItemId"];
- if (!itemCount.isIntegral()) throw std::runtime_error(kMessage);
-
- mStorage.resize(itemCount.asInt64(), T(*this));
-
- auto& items = root["Items"];
- if (!items.isArray()) throw std::runtime_error(kMessage);
-
- for (auto& elm : items) {
- if (!elm.isObject()) throw std::runtime_error(kMessage);
-
- auto& id = elm["Id"];
- if (!id.isIntegral()) throw std::runtime_error(kMessage);
- auto& name = elm["Name"];
- if (!name.isString()) throw std::runtime_error(kMessage);
-
- size_t iid = id.asInt64();
- mStorage[iid] = T(*this, iid, name.asString());
- mStorage[iid].Deserialize(elm);
- }
- }
-
- typename decltype(mStorage)::iterator begin()
- {
- return mStorage.begin();
- }
-
- typename decltype(mStorage)::iterator end()
- {
- return mStorage.end();
- }
-
- typename decltype(mStorage)::const_iterator begin() const
- {
- return mStorage.begin();
- }
-
- typename decltype(mStorage)::const_iterator end() const
- {
- return mStorage.end();
- }
-
-private:
- template <class TSelf>
- friend class ItemBase;
-
- void UpdateItemName(const T& item, const std::string& newName)
- {
- mNameLookup.erase(item.GetName());
- mNameLookup.insert(newName, item.GetId());
- }
-};
-
-template <class TSelf>
-class ItemBase
-{
-private:
- ItemList<TSelf>* mList;
- size_t mId;
- std::string mName;
-
-public:
- ItemBase(ItemList<TSelf>& list, size_t id = std::numeric_limits<size_t>::max(), std::string name = "")
- : mList{ &list }
- , mId{ id }
- , mName{ std::move(name) }
- {
- }
-
- bool IsInvalid() const
- {
- return mId == std::numeric_limits<size_t>::max();
- }
-
- ItemList<TSelf>& GetList() const
- {
- return *mList;
- }
-
- size_t GetId() const
- {
- return mId;
- }
-
- const std::string& GetName() const
- {
- return mName;
- }
-
- void SetName(std::string name)
- {
- mList->UpdateItemName(static_cast<TSelf&>(*this), name);
- mName = std::move(name);
- }
-};
-
-class ProductItem : public ItemBase<ProductItem>
-{
-private:
- std::string mDescription;
- int mPrice = 0;
- int mStock = 0;
-
-public:
- using ItemBase::ItemBase;
-
- const std::string& GetDescription() const;
- void SetDescription(std::string description);
- /// Get the price of this item in US cents.
- int GetPrice() const;
- void SetPrice(int price);
- /// Get the current number of this product in warehouse.
- /// This is a housekeeping field and shouldn't be editable by the user from the UI.
- int GetStock() const;
- void SetStock(int stock);
-
- Json::Value Serialize() const;
- void Deserialize(const Json::Value& elm);
-};
-
-class FactoryItem : public ItemBase<FactoryItem>
-{
-private:
- std::string mDescription;
- std::string mEmail;
-
-public:
- using ItemBase::ItemBase;
-
- const std::string& GetDescription() const;
- void SetDescription(std::string description);
- const std::string& GetEmail() const;
- void SetEmail(std::string email);
-
- Json::Value Serialize() const;
- void Deserialize(const Json::Value& elm);
-};
-
-class CustomerItem : public ItemBase<CustomerItem>
-{
-private:
- std::string mDescription;
- std::string mEmail;
-
-public:
- using ItemBase::ItemBase;
-
- const std::string& GetDescription() const;
- void SetDescription(std::string description);
- const std::string& GetEmail() const;
- void SetEmail(std::string email);
-
- Json::Value Serialize() const;
- void Deserialize(const Json::Value& elm);
-};