#include "GlobalStates.hpp" #include "Model/Project.hpp" #include "Utils/StandardDirectories.hpp" #include #include #include #include #include #include #include namespace fs = std::filesystem; static std::unique_ptr globalStateInstance; static fs::path globalDataPath; void GlobalStates::Init() { Init(StandardDirectories::UserData() / "cplt"); } void GlobalStates::Init(std::filesystem::path userDataDir) { globalStateInstance = std::make_unique(); 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::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) { 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(); }