aboutsummaryrefslogtreecommitdiff
path: root/core/src/Model
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/Model')
-rw-r--r--core/src/Model/GlobalStates.cpp10
-rw-r--r--core/src/Model/GlobalStates.hpp4
-rw-r--r--core/src/Model/Project.cpp106
-rw-r--r--core/src/Model/Project.hpp17
-rw-r--r--core/src/Model/Workflow/Workflow.hpp16
-rw-r--r--core/src/Model/Workflow/Workflow_Main.cpp14
-rw-r--r--core/src/Model/Workflow/fwd.hpp11
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;