aboutsummaryrefslogtreecommitdiff
path: root/core/src/Model
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/Model')
-rw-r--r--core/src/Model/Items.cpp83
-rw-r--r--core/src/Model/Items.hpp146
-rw-r--r--core/src/Model/Project.cpp22
-rw-r--r--core/src/Model/Project.hpp13
-rw-r--r--core/src/Model/fwd.hpp8
5 files changed, 271 insertions, 1 deletions
diff --git a/core/src/Model/Items.cpp b/core/src/Model/Items.cpp
new file mode 100644
index 0000000..db2d39f
--- /dev/null
+++ b/core/src/Model/Items.cpp
@@ -0,0 +1,83 @@
+#include "Items.hpp"
+
+#include <limits>
+#include <utility>
+
+ItemBase::ItemBase()
+ : mId{ std::numeric_limits<size_t>::max() } {
+}
+
+ItemBase::ItemBase(size_t id)
+ : mId{ id } {
+}
+
+bool ItemBase::IsInvalid() const {
+ return mId == std::numeric_limits<size_t>::max();
+}
+
+size_t ItemBase::GetId() const {
+ return mId;
+}
+
+ProductItem::ProductItem(size_t id, std::string name)
+ : ItemBase(id)
+ , mName{ std::move(name) } {
+}
+
+const std::string& ProductItem::GetName() const {
+ return mName;
+}
+
+void ProductItem::SetName(std::string name) {
+ mName = std::move(name);
+}
+
+const std::string& ProductItem::GetDescription() const {
+ return mDescription;
+}
+
+void ProductItem::SetDescription(std::string description) {
+ mDescription = std::move(description);
+}
+
+FactoryItem::FactoryItem(size_t id, std::string name)
+ : ItemBase(id)
+ , mName{ std::move(name) } {
+}
+
+const std::string& FactoryItem::GetName() const {
+ return mName;
+}
+
+void FactoryItem::SetName(std::string name) {
+ mName = std::move(name);
+}
+
+const std::string& FactoryItem::GetDescription() const {
+ return mDescription;
+}
+
+void FactoryItem::SetDescription(std::string description) {
+ mDescription = std::move(description);
+}
+
+CustomerItem::CustomerItem(size_t id, std::string name)
+ : ItemBase(id)
+ , mName{ std::move(name) } {
+}
+
+const std::string& CustomerItem::GetName() const {
+ return mName;
+}
+
+void CustomerItem::SetName(std::string name) {
+ mName = std::move(name);
+}
+
+const std::string& CustomerItem::GetDescription() const {
+ return mDescription;
+}
+
+void CustomerItem::SetDescription(std::string description) {
+ mDescription = std::move(description);
+}
diff --git a/core/src/Model/Items.hpp b/core/src/Model/Items.hpp
new file mode 100644
index 0000000..0c7be41
--- /dev/null
+++ b/core/src/Model/Items.hpp
@@ -0,0 +1,146 @@
+#pragma once
+
+#include <tsl/array_map.h>
+#include <cstddef>
+#include <stdexcept>
+#include <string>
+#include <string_view>
+#include <vector>
+
+/// Pointers and references returned by accessors are valid as long as no non-const functions have been called.
+template <class T>
+class ItemList {
+public:
+ class Iterator {
+ private:
+ typename std::vector<T>::const_iterator mBackingIter;
+
+ public:
+ Iterator(typename std::vector<T>::const_iterator it)
+ : mBackingIter{ it } {
+ }
+
+ Iterator& operator++() {
+ ++mBackingIter;
+ return *this;
+ }
+
+ Iterator& operator++(int) {
+ auto tmp = *this;
+ ++mBackingIter;
+ return tmp;
+ }
+
+ Iterator& operator--() {
+ --mBackingIter;
+ return *this;
+ }
+
+ Iterator& operator--(int) {
+ auto tmp = *this;
+ --mBackingIter;
+ return tmp;
+ }
+
+ const T& operator*() const {
+ return *mBackingIter;
+ }
+
+ friend bool operator==(const Iterator&, const Iterator&) = default;
+ };
+
+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.");
+ }
+
+ size_t id = mStorage.size();
+ mNameLookup.insert(name, id);
+ return mStorage.emplace_back(id, std::move(name), std::forward<Args>(args)...);
+ }
+
+ 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;
+ }
+ }
+
+ Iterator begin() const {
+ return Iterator(mStorage.begin());
+ }
+
+ Iterator end() const {
+ return Iterator(mStorage.end());
+ }
+};
+
+class ItemBase {
+private:
+ size_t mId;
+
+public:
+ ItemBase();
+ ItemBase(size_t id);
+
+ bool IsInvalid() const;
+ size_t GetId() const;
+};
+
+class ProductItem : public ItemBase {
+private:
+ std::string mName;
+ std::string mDescription;
+
+public:
+ ProductItem() {}
+ ProductItem(size_t id, std::string name);
+
+ const std::string& GetName() const;
+ void SetName(std::string mName);
+ const std::string& GetDescription() const;
+ void SetDescription(std::string description);
+};
+
+class FactoryItem : public ItemBase {
+private:
+ std::string mName;
+ std::string mDescription;
+
+public:
+ FactoryItem() {}
+ FactoryItem(size_t id, std::string name);
+
+ const std::string& GetName() const;
+ void SetName(std::string name);
+ const std::string& GetDescription() const;
+ void SetDescription(std::string description);
+};
+
+class CustomerItem : public ItemBase {
+private:
+ std::string mName;
+ std::string mDescription;
+
+public:
+ CustomerItem() {}
+ CustomerItem(size_t id, std::string name);
+
+ const std::string& GetName() const;
+ void SetName(std::string name);
+ const std::string& GetDescription() const;
+ void SetDescription(std::string description);
+};
diff --git a/core/src/Model/Project.cpp b/core/src/Model/Project.cpp
index c54a02c..f070940 100644
--- a/core/src/Model/Project.cpp
+++ b/core/src/Model/Project.cpp
@@ -25,11 +25,12 @@ Project Project::Load(const fs::path& path) {
Project proj;
proj.mRootPath = path.parent_path();
+ proj.mRootPathString = proj.mRootPath.string();
Json::Value root;
ifs >> root;
- const auto& croot = root; // Use const reference so that accessors default to returning a null if not found, instead of siliently creating new elements
+ const auto& croot = root; // Use const reference so that accessors default to returning a null if not found, instead of silently creating new elements
if (!croot.isObject()) {
throw std::runtime_error(kInvalidFormatErr);
}
@@ -46,6 +47,7 @@ Project Project::Load(const fs::path& path) {
Project Project::Create(std::string name, const fs::path& path) {
Project proj;
proj.mRootPath = path;
+ proj.mRootPathString = path.string();
proj.mName = std::move(name);
return proj;
}
@@ -54,6 +56,10 @@ const fs::path& Project::GetPath() const {
return mRootPath;
}
+const std::string& Project::GetPathString() const {
+ return mRootPathString;
+}
+
const std::string& Project::GetName() const {
return mName;
}
@@ -61,3 +67,17 @@ const std::string& Project::GetName() const {
void Project::SetName(std::string name) {
mName = std::move(name);
}
+
+Json::Value Project::Serialize() {
+ Json::Value root(Json::objectValue);
+
+ root["Name"] = mName;
+
+ return root;
+}
+
+void Project::WriteToDisk() {
+ auto root = Serialize();
+ std::ofstream ofs(mRootPath / "cplt_project.json");
+ ofs << root;
+}
diff --git a/core/src/Model/Project.hpp b/core/src/Model/Project.hpp
index 7b5c7e3..23eafc1 100644
--- a/core/src/Model/Project.hpp
+++ b/core/src/Model/Project.hpp
@@ -1,11 +1,20 @@
#pragma once
+#include "Model/Items.hpp"
+
#include <filesystem>
#include <string>
+#include <json/forwards.h>
class Project {
public:
+ ItemList<ProductItem> Products;
+ ItemList<FactoryItem> Factories;
+ ItemList<CustomerItem> Customers;
+
+private:
std::filesystem::path mRootPath;
+ std::string mRootPathString;
std::string mName;
public:
@@ -17,10 +26,14 @@ public:
// Path to a *directory* that contains the project file.
const std::filesystem::path& GetPath() const;
+ const std::string& GetPathString() const;
const std::string& GetName() const;
void SetName(std::string name);
+ Json::Value Serialize();
+ void WriteToDisk();
+
private:
Project() = default;
};
diff --git a/core/src/Model/fwd.hpp b/core/src/Model/fwd.hpp
index 6bbc0b7..bf9a8cf 100644
--- a/core/src/Model/fwd.hpp
+++ b/core/src/Model/fwd.hpp
@@ -3,5 +3,13 @@
// GlobalStates.hpp
class GlobalStates;
+// Items.hpp
+template <class T>
+class ItemList;
+class ItemBase;
+class ProductItem;
+class FactoryItem;
+class CustomerItem;
+
// Project.hpp
class Project;