aboutsummaryrefslogtreecommitdiff
path: root/app/source/Cplt/Model/GlobalStates.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/source/Cplt/Model/GlobalStates.cpp')
-rw-r--r--app/source/Cplt/Model/GlobalStates.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/app/source/Cplt/Model/GlobalStates.cpp b/app/source/Cplt/Model/GlobalStates.cpp
new file mode 100644
index 0000000..417514f
--- /dev/null
+++ b/app/source/Cplt/Model/GlobalStates.cpp
@@ -0,0 +1,163 @@
+#include "GlobalStates.hpp"
+
+#include <Cplt/Model/Project.hpp>
+#include <Cplt/Utils/StandardDirectories.hpp>
+
+#include <json/reader.h>
+#include <json/value.h>
+#include <json/writer.h>
+#include <cassert>
+#include <filesystem>
+#include <fstream>
+#include <memory>
+
+namespace fs = std::filesystem;
+
+static std::unique_ptr<GlobalStates> globalStateInstance;
+static fs::path globalDataPath;
+
+void GlobalStates::Init()
+{
+ Init(StandardDirectories::UserData() / "cplt");
+}
+
+void GlobalStates::Init(std::filesystem::path userDataDir)
+{
+ globalStateInstance = std::make_unique<GlobalStates>();
+ globalDataPath = userDataDir;
+ fs::create_directories(globalDataPath);
+
+ // Reading recent projects
+ {
+ std::ifstream ifs(globalDataPath / "recents.json");
+ if (!ifs) return;
+
+ Json::Value root;
+ ifs >> root;
+
+ if (!root.isObject()) return;
+ if (auto& recents = root["RecentProjects"]; recents.isArray()) {
+ for (auto& elm : recents) {
+ if (!elm.isString()) continue;
+
+ fs::path path(elm.asCString());
+ if (!fs::exists(path)) continue;
+
+ auto utf8String = path.string();
+ globalStateInstance->mRecentProjects.push_back(RecentProject{
+ .Path = std::move(path),
+ .CachedUtf8String = std::move(utf8String),
+ });
+ }
+ }
+ }
+}
+
+void GlobalStates::Shutdown()
+{
+ if (!globalStateInstance) return;
+
+ globalStateInstance->SetCurrentProject(nullptr);
+
+ if (globalStateInstance->mDirty) {
+ globalStateInstance->WriteToDisk();
+ }
+}
+
+GlobalStates& GlobalStates::GetInstance()
+{
+ return *globalStateInstance;
+}
+
+const std::filesystem::path& GlobalStates::GetUserDataPath()
+{
+ return globalDataPath;
+}
+
+const std::vector<GlobalStates::RecentProject>& GlobalStates::GetRecentProjects() const
+{
+ return mRecentProjects;
+}
+
+void GlobalStates::ClearRecentProjects()
+{
+ mRecentProjects.clear();
+ MarkDirty();
+}
+
+void GlobalStates::AddRecentProject(const Project& project)
+{
+ mRecentProjects.push_back(RecentProject{
+ .Path = project.GetPath(),
+ .CachedUtf8String = project.GetPath().string(),
+ });
+ MarkDirty();
+}
+
+void GlobalStates::MoveProjectToTop(const Project& project)
+{
+ for (auto it = mRecentProjects.begin(); it != mRecentProjects.end(); ++it) {
+ if (it->Path == project.GetPath()) {
+ std::rotate(it, it + 1, mRecentProjects.end());
+ MarkDirty();
+ return;
+ }
+ }
+ AddRecentProject(project);
+}
+
+void GlobalStates::RemoveRecentProject(int idx)
+{
+ assert(idx >= 0 && idx < mRecentProjects.size());
+
+ mRecentProjects.erase(mRecentProjects.begin() + idx);
+ MarkDirty();
+}
+
+bool GlobalStates::HasCurrentProject() const
+{
+ return mCurrentProject != nullptr;
+}
+
+Project* GlobalStates::GetCurrentProject() const
+{
+ return mCurrentProject.get();
+}
+
+void GlobalStates::SetCurrentProject(std::unique_ptr<Project> project)
+{
+ if (mCurrentProject) {
+ mCurrentProject->WriteToDisk();
+ mCurrentProject = nullptr;
+ }
+ if (project) {
+ MoveProjectToTop(*project);
+ }
+ mCurrentProject = std::move(project);
+}
+
+void GlobalStates::WriteToDisk() const
+{
+ Json::Value root;
+
+ auto& recentProjects = root["RecentProjects"] = Json::Value(Json::arrayValue);
+ for (auto& [path, _] : mRecentProjects) {
+ recentProjects.append(Json::Value(path.string()));
+ }
+
+ std::ofstream ofs(globalDataPath / "recents.json");
+ ofs << root;
+
+ mDirty = false;
+}
+
+bool GlobalStates::IsDirty() const
+{
+ return mDirty;
+}
+
+void GlobalStates::MarkDirty()
+{
+ mDirty = true;
+ OnModified();
+}