diff options
Diffstat (limited to 'core/src/Model')
-rw-r--r-- | core/src/Model/GlobalStates.cpp | 10 | ||||
-rw-r--r-- | core/src/Model/GlobalStates.hpp | 4 | ||||
-rw-r--r-- | core/src/Model/Project.cpp | 106 | ||||
-rw-r--r-- | core/src/Model/Project.hpp | 17 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow.hpp | 16 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow_Main.cpp | 14 | ||||
-rw-r--r-- | core/src/Model/Workflow/fwd.hpp | 11 |
7 files changed, 157 insertions, 21 deletions
diff --git a/core/src/Model/GlobalStates.cpp b/core/src/Model/GlobalStates.cpp index 4004f4a..a9b6806 100644 --- a/core/src/Model/GlobalStates.cpp +++ b/core/src/Model/GlobalStates.cpp @@ -45,8 +45,8 @@ void GlobalStates::Init(std::filesystem::path userDataDir) auto utf8String = path.string(); globalStateInstance->mRecentProjects.push_back(RecentProject{ - .path = std::move(path), - .cachedUtf8String = std::move(utf8String), + .Path = std::move(path), + .CachedUtf8String = std::move(utf8String), }); } } @@ -85,8 +85,8 @@ void GlobalStates::ClearRecentProjects() void GlobalStates::AddRecentProject(const Project& project) { mRecentProjects.push_back(RecentProject{ - .path = project.GetPath(), - .cachedUtf8String = project.GetPath().string(), + .Path = project.GetPath(), + .CachedUtf8String = project.GetPath().string(), }); MarkDirty(); } @@ -94,7 +94,7 @@ void GlobalStates::AddRecentProject(const Project& project) void GlobalStates::MoveProjectToTop(const Project& project) { for (auto it = mRecentProjects.begin(); it != mRecentProjects.end(); ++it) { - if (it->path == project.GetPath()) { + if (it->Path == project.GetPath()) { std::rotate(it, it + 1, mRecentProjects.end()); MarkDirty(); return; diff --git a/core/src/Model/GlobalStates.hpp b/core/src/Model/GlobalStates.hpp index d88f752..6970642 100644 --- a/core/src/Model/GlobalStates.hpp +++ b/core/src/Model/GlobalStates.hpp @@ -19,8 +19,8 @@ public: struct RecentProject { - std::filesystem::path path; - std::string cachedUtf8String; + std::filesystem::path Path; + std::string CachedUtf8String; }; public: diff --git a/core/src/Model/Project.cpp b/core/src/Model/Project.cpp index 74e7142..2d7c82a 100644 --- a/core/src/Model/Project.cpp +++ b/core/src/Model/Project.cpp @@ -1,5 +1,8 @@ #include "Project.hpp" +#include "Model/Workflow/Workflow.hpp" +#include "Utils/Macros.hpp" + #include <json/reader.h> #include <json/value.h> #include <json/writer.h> @@ -25,7 +28,7 @@ void ReadItemList(ItemList<T>& list, const fs::path& filePath) Project::Project(const fs::path& rootPath) : mRootPath{ rootPath } , mRootPathString{ mRootPath.string() } - , mDb(*this) + , Database(*this) { // TODO better diagnostic const char* kInvalidFormatErr = "Failed to load project: invalid format."; @@ -59,13 +62,30 @@ Project::Project(const fs::path& rootPath) ReadItemList(Products, itemsDir / "products.json"); ReadItemList(Factories, itemsDir / "factories.json"); ReadItemList(Customers, itemsDir / "customers.json"); + + auto workflowsDir = mRootPath / "workflows"; + fs::create_directories(workflowsDir); + + for (auto& entry : fs::directory_iterator(workflowsDir)) { + if (!entry.is_regular_file()) continue; + auto& path = entry.path(); + if (path.extension() != ".cplt-workflow") continue; + + auto name = path.stem().string(); + auto [it, DISCARD] = mWorkflows.insert(name, WorkflowInfo{}); + auto& info = it.value(); + + info.Name = std::move(name); + info.PathStringCache = path.string(); + info.Path = path; + } } Project::Project(std::filesystem::path rootPath, std::string name) : mRootPath{ std::move(rootPath) } , mRootPathString{ mRootPath.string() } , mName{ std::move(name) } - , mDb(*this) + , Database(*this) { } @@ -89,14 +109,68 @@ void Project::SetName(std::string name) mName = std::move(name); } -const TransactionModel& Project::GetTransactionsModel() const +const decltype(Project::mWorkflows)& Project::GetWorkflows() const +{ + return mWorkflows; +} + +std::unique_ptr<Workflow> Project::LoadWorkflow(std::string_view name) +{ + auto iter = mWorkflows.find(name); + if (iter == mWorkflows.end()) { + return iter.value().LoadFromDisk(); + } else { + return nullptr; + } +} + +std::unique_ptr<Workflow> Project::CreateWorkflow(std::string_view name) { - return mDb; + if (mWorkflows.find(name) != mWorkflows.end()) { + // Workflow with name already exists + return nullptr; + } + + auto workflow = std::make_unique<Workflow>(); + auto [it, DISCARD] = mWorkflows.insert(name, WorkflowInfo{}); + auto& info = it.value(); + + info.Name = name; + info.Path = GetWorkflowPath(name); + + return workflow; } -TransactionModel& Project::GetTransactionsModel() +bool Project::RemoveWorkflow(std::string_view name) { - return mDb; + auto iter = mWorkflows.find(name); + if (iter == mWorkflows.end()) { + return false; + } + auto& info = iter.value(); + + fs::remove(info.Path); + mWorkflows.erase(iter); + + return true; +} + +bool Project::RenameWorkflow(std::string_view name, std::string_view newName) +{ + auto iter = mWorkflows.find(name); + if (iter == mWorkflows.end()) return false; + + auto info = std::move(iter.value()); + + auto& oldPath = info.Path; + auto newPath = GetWorkflowPath(newName); + fs::rename(oldPath, newPath); + info.Path = std::move(newPath); + + mWorkflows.insert(newName, std::move(info)); + mWorkflows.erase(iter); + + return true; } Json::Value Project::Serialize() @@ -127,3 +201,23 @@ void Project::WriteToDisk() WriteItemList(Factories, itemsDir / "factories.json"); WriteItemList(Customers, itemsDir / "customers.json"); } + +std::filesystem::path Project::GetDatabasesDirectory() const +{ + return mRootPath / "databases"; +} + +std::filesystem::path Project::GetItemsDirectory() const +{ + return mRootPath / "items"; +} + +std::filesystem::path Project::GetWorkflowsDirectory() const +{ + return mRootPath / "workflows"; +} + +std::filesystem::path Project::GetWorkflowPath(std::string_view name) const +{ + return (mRootPath / "workflows" / name).concat(".cplt-workflow"); +} diff --git a/core/src/Model/Project.hpp b/core/src/Model/Project.hpp index 998befb..5f26532 100644 --- a/core/src/Model/Project.hpp +++ b/core/src/Model/Project.hpp @@ -4,8 +4,10 @@ #include "Model/TransactionsModel.hpp" #include <json/forwards.h> +#include <tsl/array_map.h> #include <filesystem> #include <string> +#include <string_view> class Project { @@ -13,12 +15,13 @@ public: ItemList<ProductItem> Products; ItemList<FactoryItem> Factories; ItemList<CustomerItem> Customers; + TransactionModel Database; private: + tsl::array_map<char, WorkflowInfo> mWorkflows; std::filesystem::path mRootPath; std::string mRootPathString; std::string mName; - TransactionModel mDb; public: /// Load the project from a directory containing the cplt_project.json file. @@ -32,11 +35,19 @@ public: const std::filesystem::path& GetPath() const; const std::string& GetPathString() const; + std::filesystem::path GetDatabasesDirectory() const; + std::filesystem::path GetItemsDirectory() const; + std::filesystem::path GetWorkflowsDirectory() const; + std::filesystem::path GetWorkflowPath(std::string_view name) const; + const std::string& GetName() const; void SetName(std::string name); - const TransactionModel& GetTransactionsModel() const; - TransactionModel& GetTransactionsModel(); + const decltype(mWorkflows)& GetWorkflows() const; + std::unique_ptr<Workflow> LoadWorkflow(std::string_view name); + std::unique_ptr<Workflow> CreateWorkflow(std::string_view name); + bool RemoveWorkflow(std::string_view name); + bool RenameWorkflow(std::string_view name, std::string_view newName); Json::Value Serialize(); void WriteToDisk(); diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp index 0aabcdc..99e4e90 100644 --- a/core/src/Model/Workflow/Workflow.hpp +++ b/core/src/Model/Workflow/Workflow.hpp @@ -7,6 +7,7 @@ #include <imgui_node_editor.h> #include <cstddef> #include <cstdint> +#include <filesystem> #include <iosfwd> #include <limits> #include <memory> @@ -135,14 +136,14 @@ public: void DisconnectInput(uint32_t pinId); void DrawInputPinDebugInfo(uint32_t pinId) const; - const InputPin& GetInputPin(uint32_t pinId)const ; + const InputPin& GetInputPin(uint32_t pinId) const; ImNodes::PinId GetInputPinUniqueId(uint32_t pinId) const; void ConnectOutput(uint32_t pinId, WorkflowNode& dstNode, uint32_t dstPinId); void DisconnectOutput(uint32_t pinId); - void DrawOutputPinDebugInfo(uint32_t pinId)const; - const OutputPin& GetOutputPin(uint32_t pinId)const ; + void DrawOutputPinDebugInfo(uint32_t pinId) const; + const OutputPin& GetOutputPin(uint32_t pinId) const; ImNodes::PinId GetOutputPinUniqueId(uint32_t pinId) const; virtual void Evaluate(WorkflowEvaluationContext& ctx) = 0; @@ -170,6 +171,15 @@ protected: void OnDetach(); }; +struct WorkflowInfo +{ + std::string Name; + std::string PathStringCache = Path.string(); + std::filesystem::path Path; + + std::unique_ptr<Workflow> LoadFromDisk() const; +}; + class Workflow { private: diff --git a/core/src/Model/Workflow/Workflow_Main.cpp b/core/src/Model/Workflow/Workflow_Main.cpp index c9ae328..bfe007c 100644 --- a/core/src/Model/Workflow/Workflow_Main.cpp +++ b/core/src/Model/Workflow/Workflow_Main.cpp @@ -4,6 +4,7 @@ #include <imgui_node_editor.h> #include <tsl/robin_set.h> #include <cassert> +#include <fstream> #include <iostream> #include <queue> #include <utility> @@ -319,6 +320,19 @@ void WorkflowNode::OnDetach() { } +std::unique_ptr<Workflow> WorkflowInfo::LoadFromDisk() const +{ + std::ifstream ifs(this->Path); + if (!ifs) return nullptr; + + auto workflow = std::make_unique<Workflow>(); + if (workflow->ReadFrom(ifs) == Workflow::RR_Success) { + return workflow; + } + + return nullptr; +} + const std::vector<WorkflowConnection>& Workflow::GetConnections() const { return mConnections; diff --git a/core/src/Model/Workflow/fwd.hpp b/core/src/Model/Workflow/fwd.hpp index 2323a91..b541e52 100644 --- a/core/src/Model/Workflow/fwd.hpp +++ b/core/src/Model/Workflow/fwd.hpp @@ -3,12 +3,19 @@ #include "Model/Workflow/Nodes/fwd.hpp" #include "Model/Workflow/Values/fwd.hpp" +// Evaluation.hpp +class WorkflowEvaluationError; +class WorkflowEvaluationContext; + +// SavedWorkflow.hpp +class SavedWorkflowCache; +class SavedWorkflow; + // Value.hpp class BaseValue; // Workflow.hpp class WorkflowConnection; class WorkflowNode; +struct WorkflowInfo; class Workflow; -class WorkflowEvaluationError; -class WorkflowEvaluationContext; |