Factorised more code in LabraryManager and StoryProject, used widely

This commit is contained in:
Anthony Rabine 2024-01-16 13:18:59 +01:00
parent 4bcb8e4490
commit 6a610200d0
12 changed files with 135 additions and 187 deletions

View file

@ -1,9 +1,11 @@
#include "library_manager.h" #include "library_manager.h"
#include "tlv.h" #include "tlv.h"
#include <filesystem> #include <filesystem>
#include <regex>
#include "json.hpp" #include "json.hpp"
#include "story_project.h" #include "story_project.h"
#include "uuid.h"
LibraryManager::LibraryManager() {} LibraryManager::LibraryManager() {}
@ -13,14 +15,6 @@ void LibraryManager::Initialize(const std::string &library_path)
Scan(); Scan();
} }
bool IsUUIDV4(const std::string& input) {
// Le motif regex pour un UUID V4
std::regex uuidRegex("^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$",std::regex_constants::icase);
// Vérifier si la chaîne correspond au motif UUID V4
return std::regex_match(input, uuidRegex);
}
void LibraryManager::Scan() void LibraryManager::Scan()
{ {
std::filesystem::path directoryPath(m_library_path); std::filesystem::path directoryPath(m_library_path);
@ -33,7 +27,7 @@ void LibraryManager::Scan()
{ {
// Si c'est un sous-répertoire, récursivement scanner le contenu // Si c'est un sous-répertoire, récursivement scanner le contenu
std::string uuid = entry.path().filename(); std::string uuid = entry.path().filename();
if (IsUUIDV4(uuid)) if (UUID::IsValid(uuid))
{ {
std::cout << "Found story directory" << std::endl; std::cout << "Found story directory" << std::endl;
// Look for a story.json file in this directory // Look for a story.json file in this directory
@ -49,6 +43,7 @@ void LibraryManager::Scan()
if (proj->ParseStoryInformation(j)) if (proj->ParseStoryInformation(j))
{ {
// Valid project file, add it to the list // Valid project file, add it to the list
proj->SetPaths(uuid, m_library_path);
m_projectsList.push_back(proj); m_projectsList.push_back(proj);
} }
} }
@ -63,6 +58,32 @@ void LibraryManager::Scan()
} }
} }
std::shared_ptr<StoryProject> LibraryManager::NewProject()
{
auto story = std::make_shared<StoryProject>();
std::string uuid = UUID().String();
story->New(uuid, m_library_path);
story->SetDisplayFormat(320, 240);
story->SetImageFormat(StoryProject::IMG_FORMAT_QOIF);
story->SetSoundFormat(StoryProject::SND_FORMAT_WAV);
story->SetName("New project");
return story;
}
std::shared_ptr<StoryProject> LibraryManager::GetStory(const std::string &uuid)
{
std::shared_ptr<StoryProject> current;
for (const auto &s : m_projectsList)
{
if (s->GetUuid() == uuid)
{
current = s;
}
}
return current;
}
void LibraryManager::Save() void LibraryManager::Save()
{ {
auto p = std::filesystem::path(m_library_path) / "index.ost"; auto p = std::filesystem::path(m_library_path) / "index.ost";

View file

@ -22,6 +22,11 @@ public:
void Save(); void Save();
void Scan(); void Scan();
std::shared_ptr<StoryProject> NewProject();
std::shared_ptr<StoryProject> GetStory(const std::string &uuid);
private: private:
std::string m_library_path; std::string m_library_path;
std::vector<std::shared_ptr<StoryProject>> m_projectsList; std::vector<std::shared_ptr<StoryProject>> m_projectsList;

View file

@ -2,7 +2,6 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <queue>
#include <filesystem> #include <filesystem>
#include "json.hpp" #include "json.hpp"
@ -16,34 +15,27 @@ StoryProject::~StoryProject()
{ {
} }
void StoryProject::SetPaths(const std::string &uuid, const std::string &library_path)
void StoryProject::New(const std::string &uuid, const std::string &file_path)
{ {
m_uuid = uuid; m_uuid = uuid;
Initialize(file_path); m_project_file_path = std::filesystem::path(library_path) / uuid / std::filesystem::path("project.json");
m_working_dir = m_project_file_path.parent_path().generic_string();
m_assetsPath = m_working_dir / std::filesystem::path("assets");
std::cout << "Working dir is: " << m_working_dir << std::endl;
} }
void StoryProject::SaveStory(const std::vector<uint8_t> &m_program) void StoryProject::New(const std::string &uuid, const std::string &library_path)
{ {
std::ofstream o(m_working_dir / "story.c32", std::ios::out | std::ios::binary); SetPaths(uuid, library_path);
o.write(reinterpret_cast<const char*>(m_program.data()), m_program.size());
o.close();
}
void StoryProject::Initialize(const std::string &file_path)
{
m_story_file_path = file_path;
std::filesystem::path p(file_path);
m_working_dir= p.parent_path().generic_string();
// First try to create the working directory // First try to create the working directory
if (!std::filesystem::is_directory(m_working_dir)) if (!std::filesystem::is_directory(m_working_dir))
{ {
std::filesystem::create_directories(m_working_dir); std::filesystem::create_directories(m_working_dir);
} }
m_assetsPath = std::filesystem::path(m_working_dir) / "assets";
std::filesystem::create_directories(m_assetsPath); std::filesystem::create_directories(m_assetsPath);
@ -51,6 +43,13 @@ void StoryProject::Initialize(const std::string &file_path)
} }
void StoryProject::SaveBinary(const std::vector<uint8_t> &m_program)
{
std::ofstream o(m_working_dir / "story.c32", std::ios::out | std::ios::binary);
o.write(reinterpret_cast<const char*>(m_program.data()), m_program.size());
o.close();
}
bool StoryProject::ParseStoryInformation(nlohmann::json &j) bool StoryProject::ParseStoryInformation(nlohmann::json &j)
{ {
bool success = false; bool success = false;
@ -71,22 +70,12 @@ bool StoryProject::ParseStoryInformation(nlohmann::json &j)
} }
bool StoryProject::Load(const std::string &file_path, nlohmann::json &model, ResourceManager &manager) bool StoryProject::Load(nlohmann::json &model, ResourceManager &manager)
{ {
std::ifstream f(file_path);
bool success = false;
std::filesystem::path p(file_path);
m_working_dir= p.parent_path().generic_string();
std::cout << "Working dir is: " << m_working_dir << std::endl;
try { try {
std::ifstream f(m_project_file_path);
nlohmann::json j = nlohmann::json::parse(f); nlohmann::json j = nlohmann::json::parse(f);
// m_nodes.clear();
manager.Clear(); manager.Clear();
if (ParseStoryInformation(j)) if (ParseStoryInformation(j))
@ -109,7 +98,7 @@ bool StoryProject::Load(const std::string &file_path, nlohmann::json &model, Res
if (j.contains("nodegraph")) if (j.contains("nodegraph"))
{ {
model = j["nodegraph"]; model = j["nodegraph"];
success = true; m_initialized = true;
} }
} }
} }
@ -180,7 +169,7 @@ bool StoryProject::Load(const std::string &file_path, nlohmann::json &model, Res
std::cout << e.what() << std::endl; std::cout << e.what() << std::endl;
} }
return success; return m_initialized;
} }
void StoryProject::Save(const nlohmann::json &model, ResourceManager &manager) void StoryProject::Save(const nlohmann::json &model, ResourceManager &manager)
@ -206,7 +195,7 @@ void StoryProject::Save(const nlohmann::json &model, ResourceManager &manager)
j["nodegraph"] = model; j["nodegraph"] = model;
std::ofstream o(m_story_file_path); std::ofstream o(m_project_file_path);
o << std::setw(4) << j << std::endl; o << std::setw(4) << j << std::endl;
} }
/* /*
@ -248,7 +237,7 @@ void StoryProject::Clear()
{ {
m_uuid = ""; m_uuid = "";
m_working_dir = ""; m_working_dir = "";
m_story_file_path = ""; m_project_file_path = "";
m_initialized = false; m_initialized = false;
} }
@ -339,7 +328,7 @@ void StoryProject::SetDisplayFormat(int w, int h)
std::string StoryProject::GetProjectFilePath() const std::string StoryProject::GetProjectFilePath() const
{ {
return m_story_file_path; return m_project_file_path;
} }
std::string StoryProject::GetWorkingDir() const std::string StoryProject::GetWorkingDir() const

View file

@ -59,8 +59,11 @@ public:
StoryNode *m_tree; StoryNode *m_tree;
*/ */
bool Load(const std::string &file_path, nlohmann::json &model, ResourceManager &manager); void New(const std::string &uuid, const std::string &library_path);
bool Load(nlohmann::json &model, ResourceManager &manager);
void Save(const nlohmann::json &model, ResourceManager &manager); void Save(const nlohmann::json &model, ResourceManager &manager);
void SaveBinary(const std::vector<uint8_t> &m_program);
void SetPaths(const std::string &uuid, const std::string &library_path);
void CreateTree(); void CreateTree();
void Clear(); void Clear();
@ -95,14 +98,13 @@ public:
std::string GetTitleSound() const { return m_titleSound; } std::string GetTitleSound() const { return m_titleSound; }
// Initialize with an existing project // Initialize with an existing project
void Initialize(const std::string &file_path);
const bool IsInitialized() const { return m_initialized; } const bool IsInitialized() const { return m_initialized; }
void New(const std::string &uuid, const std::string &file_path);
static void EraseString(std::string &theString, const std::string &toErase); static void EraseString(std::string &theString, const std::string &toErase);
static std::string ToUpper(const std::string &input); static std::string ToUpper(const std::string &input);
void SaveStory(const std::vector<uint8_t> &m_program);
bool ParseStoryInformation(nlohmann::json &j); bool ParseStoryInformation(nlohmann::json &j);
private: private:
@ -119,7 +121,7 @@ private:
bool m_initialized{false}; bool m_initialized{false};
std::filesystem::path m_working_dir; /// Temporary folder based on the uuid, where the archive is unzipped std::filesystem::path m_working_dir; /// Temporary folder based on the uuid, where the archive is unzipped
std::string m_story_file_path; /// JSON project file std::filesystem::path m_project_file_path; /// JSON project file
int m_display_w{320}; int m_display_w{320};
int m_display_h{240}; int m_display_h{240};

View file

@ -3,6 +3,7 @@
#include <string> #include <string>
#include <random> #include <random>
#include <regex>
// Encaasulate the genaeration of a Version 4 UUID object // Encaasulate the genaeration of a Version 4 UUID object
// A Version 4 UUID is a universally unique identifier that is generated using random numbers. // A Version 4 UUID is a universally unique identifier that is generated using random numbers.
@ -46,6 +47,13 @@ public:
return uuid; return uuid;
} }
static bool IsValid(const std::string& input) {
// Le motif regex pour un UUID V4
std::regex uuidRegex("^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$",std::regex_constants::icase);
// Vérifier si la chaîne correspond au motif UUID V4
return std::regex_match(input, uuidRegex);
}
unsigned char _data[16] = {0}; unsigned char _data[16] = {0};
}; };

View file

@ -14,7 +14,7 @@ class IStoryManager
public: public:
virtual ~IStoryManager() {} virtual ~IStoryManager() {}
virtual void OpenProject(const std::string &filename) = 0; virtual void OpenProject(const std::string &uuid) = 0;
virtual void Log(const std::string &txt, bool critical = false) = 0; virtual void Log(const std::string &txt, bool critical = false) = 0;
virtual void PlaySoundFile(const std::string &fileName) = 0; virtual void PlaySoundFile(const std::string &fileName) = 0;
virtual std::string BuildFullAssetsPath(const std::string &fileName) const = 0; virtual std::string BuildFullAssetsPath(const std::string &fileName) const = 0;

View file

@ -2,6 +2,8 @@
#include "gui.h" #include "gui.h"
#include "ImGuiFileDialog.h" #include "ImGuiFileDialog.h"
#include <filesystem> #include <filesystem>
#include "IconsMaterialDesignIcons.h"
LibraryWindow::LibraryWindow(IStoryManager &project, LibraryManager &library) LibraryWindow::LibraryWindow(IStoryManager &project, LibraryManager &library)
: WindowBase("Library Manager") : WindowBase("Library Manager")
@ -40,7 +42,7 @@ void LibraryWindow::Draw()
WindowBase::BeginDraw(); WindowBase::BeginDraw();
ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver); ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
if (ImGui::Button("Select directory")) if (ImGui::Button( ICON_MDI_FOLDER " Select directory"))
{ {
ImGuiFileDialog::Instance()->OpenDialog("ChooseLibraryDirDialog", "Choose a library directory", nullptr, ".", 1, nullptr, ImGuiFileDialogFlags_Modal); ImGuiFileDialog::Instance()->OpenDialog("ChooseLibraryDirDialog", "Choose a library directory", nullptr, ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
} }
@ -96,8 +98,7 @@ void LibraryWindow::Draw()
if (ImGui::SmallButton("Load")) if (ImGui::SmallButton("Load"))
{ {
auto filename = std::filesystem::path(m_libraryManager.LibraryPath()) / p->GetUuid() / std::filesystem::path("project.json"); m_storyManager.OpenProject(p->GetUuid());
m_storyManager.OpenProject(filename);
} }
ImGui::SameLine(); ImGui::SameLine();

View file

@ -1,14 +1,6 @@
#include "main_window.h" #include "main_window.h"
#include <iostream> // std::cerr
#include <exception> // std::set_terminate
#include <cstdlib> // std::abort
#include <csignal>
#include <iostream>
// Main code // Main code
int main(int, char**) int main(int, char**)
{ {

View file

@ -2,7 +2,7 @@
#include <filesystem> #include <filesystem>
#include <SDL.h> #include <SDL.h>
#include "platform_folders.h" #include "platform_folders.h"
#include "uuid.h"
#include "media_converter.h" #include "media_converter.h"
#ifdef USE_WINDOWS_OS #ifdef USE_WINDOWS_OS
@ -15,7 +15,6 @@
#pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "ws2_32.lib")
#endif #endif
#include "IconsMaterialDesignIcons.h"
#include "ImGuiFileDialog.h" #include "ImGuiFileDialog.h"
MainWindow::MainWindow() MainWindow::MainWindow()
@ -40,8 +39,6 @@ MainWindow::MainWindow()
Callback<uint8_t(chip32_ctx_t *, uint8_t)>::func = std::bind(&MainWindow::Syscall, this, std::placeholders::_1, std::placeholders::_2); Callback<uint8_t(chip32_ctx_t *, uint8_t)>::func = std::bind(&MainWindow::Syscall, this, std::placeholders::_1, std::placeholders::_2);
m_chip32_ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(chip32_ctx_t *, uint8_t)>::callback); m_chip32_ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(chip32_ctx_t *, uint8_t)>::callback);
m_story.Clear();
CloseProject(); CloseProject();
} }
@ -187,7 +184,7 @@ uint8_t MainWindow::Syscall(chip32_ctx_t *ctx, uint8_t code)
if (m_chip32_ctx.registers[R0] != 0) if (m_chip32_ctx.registers[R0] != 0)
{ {
// image file name address is in R0 // image file name address is in R0
std::string imageFile = m_story.BuildFullAssetsPath(GetFileNameFromMemory(m_chip32_ctx.registers[R0])); std::string imageFile = m_story->BuildFullAssetsPath(GetFileNameFromMemory(m_chip32_ctx.registers[R0]));
Log("Image: " + imageFile); Log("Image: " + imageFile);
m_emulatorWindow.SetImage(imageFile); m_emulatorWindow.SetImage(imageFile);
} }
@ -199,7 +196,7 @@ uint8_t MainWindow::Syscall(chip32_ctx_t *ctx, uint8_t code)
if (m_chip32_ctx.registers[R1] != 0) if (m_chip32_ctx.registers[R1] != 0)
{ {
// sound file name address is in R1 // sound file name address is in R1
std::string soundFile = m_story.BuildFullAssetsPath(GetFileNameFromMemory(m_chip32_ctx.registers[R1])); std::string soundFile = m_story->BuildFullAssetsPath(GetFileNameFromMemory(m_chip32_ctx.registers[R1]));
Log(", Sound: " + soundFile); Log(", Sound: " + soundFile);
m_player.Play(soundFile); m_player.Play(soundFile);
} }
@ -267,11 +264,6 @@ void MainWindow::DrawMainMenuBar()
showNewProject = true; showNewProject = true;
} }
/* /*
if (ImGui::MenuItem("Open project"))
{
showOpenProject = true;
}
if (ImGui::BeginMenu("Open Recent")) if (ImGui::BeginMenu("Open Recent"))
{ {
for (auto &e : m_recentProjects) for (auto &e : m_recentProjects)
@ -289,7 +281,7 @@ void MainWindow::DrawMainMenuBar()
} }
*/ */
bool init = m_story.IsInitialized(); // local copy because CloseProject() changes the status between BeginDisabled/EndDisabled bool init = m_story ? true : false; // local copy because CloseProject() changes the status between BeginDisabled/EndDisabled
if (!init) if (!init)
ImGui::BeginDisabled(); ImGui::BeginDisabled();
@ -334,9 +326,13 @@ void MainWindow::DrawMainMenuBar()
if (showParameters) if (showParameters)
{ {
if (m_story.IsInitialized()) if (m_story)
{ {
ImGui::OpenPopup("ProjectPropertiesPopup"); ImGui::OpenPopup("ProjectPropertiesPopup");
// Init some variables
std::size_t length = m_story->GetName().copy(m_project_name, sizeof(m_project_name));
m_project_name[length] = '\0';
} }
} }
@ -345,12 +341,6 @@ void MainWindow::DrawMainMenuBar()
ImGuiFileDialog::Instance()->OpenDialog("ChooseDirDialog", "Choose a parent directory for your project", nullptr, ".", 1, nullptr, ImGuiFileDialogFlags_Modal); ImGuiFileDialog::Instance()->OpenDialog("ChooseDirDialog", "Choose a parent directory for your project", nullptr, ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
} }
if (showOpenProject)
{
std::string home = pf::getUserHome() + "/";
ImGuiFileDialog::Instance()->OpenDialog("OpenProjectDlgKey", "Choose File", ".json", home, 1, nullptr, ImGuiFileDialogFlags_Modal);
}
// Always center this window when appearing // Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter(); ImVec2 center = ImGui::GetMainViewport()->GetCenter();
//ImVec2 parent_pos = ImGui::GetWindowPos(); //ImVec2 parent_pos = ImGui::GetWindowPos();
@ -426,27 +416,6 @@ bool MainWindow::ShowQuitConfirm()
} }
void MainWindow::OpenProjectDialog()
{
ImGui::SetNextWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
if (ImGuiFileDialog::Instance()->Display("OpenProjectDlgKey"))
{
// ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
// action if OK
if (ImGuiFileDialog::Instance()->IsOk())
{
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
OpenProject(filePathName);
}
// close
ImGuiFileDialog::Instance()->Close();
}
}
void MainWindow::NewProjectPopup() void MainWindow::NewProjectPopup()
{ {
// Always center this window when appearing // Always center this window when appearing
@ -463,19 +432,13 @@ void MainWindow::NewProjectPopup()
if (!std::filesystem::is_directory(projdir)) if (!std::filesystem::is_directory(projdir))
{ {
m_story = m_libraryManager.NewProject();
std::string uuid = UUID().String(); if (m_story)
auto p = std::filesystem::path(projdir) / uuid / std::filesystem::path("project.json"); {
m_story.Initialize(p.generic_string()); SaveProject();
OpenProject(m_story->GetUuid());
m_story.SetDisplayFormat(320, 240); }
m_story.SetImageFormat(StoryProject::IMG_FORMAT_QOIF);
m_story.SetSoundFormat(StoryProject::SND_FORMAT_WAV);
m_story.SetName("New project");
m_story.SetUuid(uuid);
SaveProject();
OpenProject(p.generic_string());
} }
} }
@ -486,45 +449,15 @@ void MainWindow::NewProjectPopup()
void MainWindow::ProjectPropertiesPopup() void MainWindow::ProjectPropertiesPopup()
{ {
static std::string projdir;
// Always center this window when appearing // Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter(); ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("ProjectPropertiesPopup", NULL, ImGuiWindowFlags_AlwaysAutoResize)) if (ImGui::BeginPopupModal("ProjectPropertiesPopup", NULL, ImGuiWindowFlags_AlwaysAutoResize))
{ {
ImGui::Text("New project parameters (directory must be empty)");
ImGui::Separator();
ImGui::Text("Directory: "); ImGui::SameLine();
static char project_dir[256] = "";
ImGui::InputTextWithHint("##project_path", "Project path", project_dir, IM_ARRAYSIZE(project_dir));
ImGui::SameLine();
if (ImGui::Button( ICON_MDI_FOLDER " ..."))
{
ImGuiFileDialog::Instance()->OpenDialog("ChooseDirDialog", "Choose File", nullptr, ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
}
// display
if (ImGuiFileDialog::Instance()->Display("ChooseDirDialog"))
{
// action if OK
if (ImGuiFileDialog::Instance()->IsOk())
{
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
projdir = ImGuiFileDialog::Instance()->GetCurrentPath();
}
// close
ImGuiFileDialog::Instance()->Close();
}
ImGui::Text("Project name: "); ImGui::SameLine(); ImGui::Text("Project name: "); ImGui::SameLine();
static char project_name[256] = ""; ImGui::InputTextWithHint("##project_name", "Project name", m_project_name, IM_ARRAYSIZE(m_project_name));
ImGui::InputTextWithHint("##project_name", "Project name", project_name, IM_ARRAYSIZE(project_name));
ImGui::Text("Size of display screen: "); ImGui::Text("Size of display screen: ");
ImGui::SameLine(); ImGui::SameLine();
@ -630,33 +563,23 @@ void MainWindow::ProjectPropertiesPopup()
if (ImGui::Button("OK", ImVec2(120, 0))) if (ImGui::Button("OK", ImVec2(120, 0)))
{ {
bool valid{true}; if (display_item_current_idx == 0)
if (!std::filesystem::is_directory(projdir))
{ {
valid = false; m_story->SetDisplayFormat(320, 240);
}
else
{
m_story->SetDisplayFormat(640, 480);
} }
if (valid) m_story->SetImageFormat(GetImageFormat(image_item_current_idx));
{ m_story->SetSoundFormat(GetSoundFormat(sound_item_current_idx));
m_story->SetName(m_project_name);
if (display_item_current_idx == 0) SaveProject();
{
m_story.SetDisplayFormat(320, 240);
}
else
{
m_story.SetDisplayFormat(640, 480);
}
m_story.SetImageFormat(GetImageFormat(image_item_current_idx)); ImGui::CloseCurrentPopup();
m_story.SetSoundFormat(GetSoundFormat(sound_item_current_idx));
m_story.SetName(project_name);
SaveProject();
ImGui::CloseCurrentPopup();
}
} }
ImGui::SetItemDefaultFocus(); ImGui::SetItemDefaultFocus();
ImGui::SameLine(); ImGui::SameLine();
@ -666,29 +589,31 @@ void MainWindow::ProjectPropertiesPopup()
} }
ImGui::EndPopup(); ImGui::EndPopup();
} }
else
{
projdir = "";
}
} }
void MainWindow::SaveProject() void MainWindow::SaveProject()
{ {
nlohmann::json model; nlohmann::json model;
m_nodeEditorWindow.Save(model); m_nodeEditorWindow.Save(model);
m_story.Save(model, m_resources); m_story->Save(model, m_resources);
} }
void MainWindow::OpenProject(const std::string &filename) void MainWindow::OpenProject(const std::string &uuid)
{ {
CloseProject(); CloseProject();
nlohmann::json model; nlohmann::json model;
if (m_story.Load(filename, model, m_resources)) m_story = m_libraryManager.GetStory(uuid);
if (!m_story)
{
Log("Cannot find story: " + uuid);
}
else if (m_story->Load(model, m_resources))
{ {
Log("Open project success"); Log("Open project success");
m_nodeEditorWindow.Load(model); m_nodeEditorWindow.Load(model);
auto proj = m_story.GetProjectFilePath(); auto proj = m_story->GetProjectFilePath();
// Add to recent if not exists // Add to recent if not exists
if (std::find(m_recentProjects.begin(), m_recentProjects.end(), proj) == m_recentProjects.end()) if (std::find(m_recentProjects.begin(), m_recentProjects.end(), proj) == m_recentProjects.end())
{ {
@ -719,14 +644,23 @@ void MainWindow::OpenProject(const std::string &filename)
void MainWindow::RefreshProjectInformation() void MainWindow::RefreshProjectInformation()
{ {
std::string fullText = "Story Editor " + LibraryManager::GetVersion() + " - " + m_story.GetProjectFilePath(); std::string fullText = "Story Editor " + LibraryManager::GetVersion();
if (m_story)
{
fullText += " - " + m_story->GetProjectFilePath();
}
m_gui.SetWindowTitle(fullText); m_gui.SetWindowTitle(fullText);
} }
void MainWindow::CloseProject() void MainWindow::CloseProject()
{ {
m_story.Clear(); if (m_story)
{
m_story->Clear();
}
m_resources.Clear(); m_resources.Clear();
m_nodeEditorWindow.Clear(); m_nodeEditorWindow.Clear();
@ -782,7 +716,6 @@ void MainWindow::Loop()
} }
NewProjectPopup(); NewProjectPopup();
OpenProjectDialog();
ProjectPropertiesPopup(); ProjectPropertiesPopup();
if (aboutToClose) if (aboutToClose)
@ -816,7 +749,7 @@ void MainWindow::PlaySoundFile(const std::string &fileName)
std::string MainWindow::BuildFullAssetsPath(const std::string &fileName) const std::string MainWindow::BuildFullAssetsPath(const std::string &fileName) const
{ {
return m_story.BuildFullAssetsPath(fileName); return m_story->BuildFullAssetsPath(fileName);
} }
std::pair<FilterIterator, FilterIterator> MainWindow::Images() std::pair<FilterIterator, FilterIterator> MainWindow::Images()
@ -915,7 +848,7 @@ void MainWindow::GenerateBinary()
// FIXME // FIXME
// m_ramView->SetMemory(m_ram_data, sizeof(m_ram_data)); // m_ramView->SetMemory(m_ram_data, sizeof(m_ram_data));
// m_romView->SetMemory(m_rom_data, m_program.size()); // m_romView->SetMemory(m_rom_data, m_program.size());
m_story.SaveStory(m_program); m_story->SaveBinary(m_program);
chip32_initialize(&m_chip32_ctx); chip32_initialize(&m_chip32_ctx);
m_dbg.run_result = VM_READY; m_dbg.run_result = VM_READY;
UpdateVmView(); UpdateVmView();
@ -976,8 +909,8 @@ void MainWindow::ConvertResources()
auto [b, e] = m_resources.Items(); auto [b, e] = m_resources.Items();
for (auto it = b; it != e; ++it) for (auto it = b; it != e; ++it)
{ {
std::string inputfile = m_story.BuildFullAssetsPath((*it)->file.c_str()); std::string inputfile = m_story->BuildFullAssetsPath((*it)->file.c_str());
std::string outputfile = std::filesystem::path(m_story.AssetsPath() / StoryProject::RemoveFileExtension((*it)->file)).string(); std::string outputfile = std::filesystem::path(m_story->AssetsPath() / StoryProject::RemoveFileExtension((*it)->file)).string();
int retCode = 0; int retCode = 0;
if ((*it)->format == "PNG") if ((*it)->format == "PNG")

View file

@ -93,7 +93,7 @@ public:
private: private:
enum VmEventType { EvNoEvent, EvStep, EvOkButton, EvPreviousButton, EvNextButton, EvAudioFinished}; enum VmEventType { EvNoEvent, EvStep, EvOkButton, EvPreviousButton, EvNextButton, EvAudioFinished};
StoryProject m_story; std::shared_ptr<StoryProject> m_story;
// VM // VM
uint8_t m_rom_data[16*1024]; uint8_t m_rom_data[16*1024];
@ -119,6 +119,8 @@ private:
ConsoleWindow m_consoleWindow; ConsoleWindow m_consoleWindow;
CodeEditor m_editorWindow; CodeEditor m_editorWindow;
char m_project_name[256] = "";
ResourcesWindow m_resourcesWindow; ResourcesWindow m_resourcesWindow;
NodeEditorWindow m_nodeEditorWindow; NodeEditorWindow m_nodeEditorWindow;
@ -138,7 +140,7 @@ private:
// From IStoryManager (proxy to StoryProject class) // From IStoryManager (proxy to StoryProject class)
virtual void OpenProject(const std::string &filename) override; virtual void OpenProject(const std::string &uuid) override;
virtual void Log(const std::string &txt, bool critical = false) override; virtual void Log(const std::string &txt, bool critical = false) override;
virtual void PlaySoundFile(const std::string &fileName) override;; virtual void PlaySoundFile(const std::string &fileName) override;;
virtual std::string BuildFullAssetsPath(const std::string &fileName) const override; virtual std::string BuildFullAssetsPath(const std::string &fileName) const override;
@ -170,7 +172,6 @@ private:
void NewProjectPopup(); void NewProjectPopup();
void SaveProject(); void SaveProject();
void CloseProject(); void CloseProject();
void OpenProjectDialog();
void DrawStatusBar(); void DrawStatusBar();
bool CompileToAssembler(); bool CompileToAssembler();

View file

@ -1,6 +1,5 @@
#include "resources_window.h" #include "resources_window.h"
#include "imgui.h" #include "imgui.h"
#include <random>
#include <filesystem> #include <filesystem>
#include <memory> #include <memory>
#include "resource.h" #include "resource.h"

View file

@ -1,8 +1,5 @@
#pragma once #pragma once
#include <vector>
#include <map>
#include <mutex>
#include "i_story_manager.h" #include "i_story_manager.h"
#include "window_base.h" #include "window_base.h"