mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
Module save/load
This commit is contained in:
parent
8aec974f89
commit
65094d88a3
10 changed files with 426 additions and 250 deletions
|
|
@ -19,12 +19,6 @@ public:
|
||||||
|
|
||||||
virtual std::string GetName() const = 0;
|
virtual std::string GetName() const = 0;
|
||||||
|
|
||||||
virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(const std::string &nodeId) = 0;
|
|
||||||
virtual int OutputsCount(const std::string &nodeId) = 0;
|
|
||||||
virtual StoryOptions GetOptions() = 0;
|
|
||||||
|
|
||||||
/* Retourne true si la resource existe déjà et que le code a déjà été généré */
|
|
||||||
virtual bool UseResource(const std::string &label) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "print_node.h"
|
#include "print_node.h"
|
||||||
#include "syscall_node.h"
|
#include "syscall_node.h"
|
||||||
#include "story_project.h"
|
#include "story_project.h"
|
||||||
|
#include "story_primitive.h"
|
||||||
|
|
||||||
static const std::string OperatorNodeUuid = "0226fdac-8f7a-47d7-8584-b23aceb712ec";
|
static const std::string OperatorNodeUuid = "0226fdac-8f7a-47d7-8584-b23aceb712ec";
|
||||||
static const std::string CallFunctionNodeUuid = "02745f38-9b11-49fe-94b1-b2a6b78249fb";
|
static const std::string CallFunctionNodeUuid = "02745f38-9b11-49fe-94b1-b2a6b78249fb";
|
||||||
|
|
@ -35,18 +36,24 @@ public:
|
||||||
{
|
{
|
||||||
// Register node types
|
// Register node types
|
||||||
// registerNode<MediaNode>("media-node");
|
// registerNode<MediaNode>("media-node");
|
||||||
registerNode<OperatorNode>(OperatorNodeUuid, nullptr);
|
registerNode<OperatorNode>(OperatorNodeUuid, std::make_shared<StoryPrimitive>("Operator"));
|
||||||
registerNode<CallFunctionNode>(CallFunctionNodeUuid, nullptr);
|
registerNode<CallFunctionNode>(CallFunctionNodeUuid, std::make_shared<StoryPrimitive>("Call function"));
|
||||||
registerNode<VariableNode>(VariableNodeUuid, nullptr);
|
registerNode<VariableNode>(VariableNodeUuid, std::make_shared<StoryPrimitive>("Variable"));
|
||||||
registerNode<PrintNode>(PrintNodeUuid, nullptr);
|
registerNode<PrintNode>(PrintNodeUuid, std::make_shared<StoryPrimitive>("Print"));
|
||||||
registerNode<SyscallNode>(SyscallNodeUuid, nullptr);
|
registerNode<SyscallNode>(SyscallNodeUuid, std::make_shared<StoryPrimitive>("System call"));
|
||||||
}
|
}
|
||||||
|
|
||||||
~NodesFactory() = default;
|
~NodesFactory() = default;
|
||||||
|
|
||||||
std::vector<std::string> GetNodeTypes() const {
|
struct NodeInfo {
|
||||||
std::vector<std::string> l;
|
std::string uuid;
|
||||||
for(auto const& imap: m_registry) l.push_back(imap.first);
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// key: uuid, value: node name
|
||||||
|
std::vector<NodeInfo> LitOfNodes() const {
|
||||||
|
std::vector<NodeInfo> l;
|
||||||
|
for(auto const& imap: m_registry) l.push_back(NodeInfo{imap.first, imap.second.first->GetName() });
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +85,12 @@ public:
|
||||||
// We have a module here, get the name
|
// We have a module here, get the name
|
||||||
if (n.second.first->GetName() == name)
|
if (n.second.first->GetName() == name)
|
||||||
{
|
{
|
||||||
module = n.second.first;
|
auto p = dynamic_cast<StoryProject*>(n.second.first.get());
|
||||||
|
if (p == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Node is not a StoryProject");
|
||||||
|
}
|
||||||
|
module = p->shared_from_this();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -87,34 +99,71 @@ public:
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveAllModules(ResourceManager &manager)
|
||||||
|
{
|
||||||
|
for (const auto &entry : m_registry)
|
||||||
|
{
|
||||||
|
// Uniquement les modules custom (ici ModuleNodeUuid)
|
||||||
|
if (entry.first == ModuleNodeUuid)
|
||||||
|
{
|
||||||
|
// Get the module from the registry
|
||||||
|
auto module = std::dynamic_pointer_cast<StoryProject>(entry.second.first);
|
||||||
|
if (module)
|
||||||
|
{
|
||||||
|
module->Save(manager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a new empty module (StoryProject) and registers it as a module node.
|
||||||
|
std::shared_ptr<StoryProject> NewModule(const std::string& moduleName = "Untitled Module") {
|
||||||
|
// Create a new StoryProject with the given name
|
||||||
|
auto module = std::make_shared<StoryProject>(m_log);
|
||||||
|
module->New(Uuid().String(), m_rootPath);
|
||||||
|
module->SetName(moduleName);
|
||||||
|
module->SetTitleImage("");
|
||||||
|
module->SetTitleSound("");
|
||||||
|
module->SetDisplayFormat(320, 240);
|
||||||
|
module->SetImageFormat(Resource::ImageFormat::IMG_SAME_FORMAT);
|
||||||
|
module->SetSoundFormat(Resource::SoundFormat::SND_SAME_FORMAT);
|
||||||
|
module->SetDescription("");
|
||||||
|
module->SetProjectType(IStoryProject::PROJECT_TYPE_MODULE);
|
||||||
|
|
||||||
|
// Register as module node if not already in registry
|
||||||
|
registerNode<ModuleNode>(ModuleNodeUuid, module);
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SetModulesRootDirectory(const std::string &rootPath) {
|
void SetModulesRootDirectory(const std::string &rootPath) {
|
||||||
m_rootPath = rootPath;
|
m_rootPath = rootPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScanModules() {
|
void ScanModules() {
|
||||||
// This function should scan the rootPath for modules and register them
|
|
||||||
// For now, we just log the root path
|
|
||||||
std::cout << "Scanning modules in: " << m_rootPath << std::endl;
|
std::cout << "Scanning modules in: " << m_rootPath << std::endl;
|
||||||
// Here you would implement the logic to scan the directory and register modules
|
|
||||||
|
|
||||||
// For example, you could read JSON files in the directory and create nodes based on their content
|
|
||||||
// This is a placeholder for actual scanning logic
|
|
||||||
// Example: registerNode<CustomModuleNode>("custom-module-node");
|
|
||||||
|
|
||||||
// Loop through files in m_rootPath
|
// Loop through files in m_rootPath
|
||||||
// and register them as nodes if they match certain criteria
|
// and register them as nodes if they match certain criteria
|
||||||
for (const auto& entry : std::filesystem::directory_iterator(m_rootPath))
|
for (const auto& entry : std::filesystem::directory_iterator(m_rootPath))
|
||||||
{
|
{
|
||||||
if (entry.is_regular_file() && entry.path().extension() == ".json")
|
// Enter directory and look for .json files
|
||||||
|
if (entry.is_directory())
|
||||||
{
|
{
|
||||||
|
std::cout << "Scanning directory: " << entry.path() << std::endl;
|
||||||
|
for (const auto& subEntry : std::filesystem::directory_iterator(entry.path()))
|
||||||
|
{
|
||||||
|
if (subEntry.is_regular_file() && subEntry.path().extension() == ".json")
|
||||||
|
{
|
||||||
|
std::cout << "Found module file: " << subEntry.path() << std::endl;
|
||||||
// Load the JSON file and register a node based on its content
|
// Load the JSON file and register a node based on its content
|
||||||
std::ifstream file(entry.path());
|
std::ifstream file(subEntry.path());
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
file >> j;
|
file >> j;
|
||||||
|
|
||||||
auto p = std::make_shared<StoryProject>(m_log);
|
auto p = std::make_shared<StoryProject>(m_log);
|
||||||
p->ParseStoryInformation(j);
|
p->ParseStoryInformation(j);
|
||||||
|
|
||||||
if (p->IsModule())
|
if (p->IsModule())
|
||||||
{
|
{
|
||||||
registerNode<ModuleNode>(ModuleNodeUuid, p);
|
registerNode<ModuleNode>(ModuleNodeUuid, p);
|
||||||
|
|
@ -127,6 +176,12 @@ public:
|
||||||
// 2. for each function node, check if it has a "requires" field
|
// 2. for each function node, check if it has a "requires" field
|
||||||
// 3. if it does, check if we have them
|
// 3. if it does, check if we have them
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Skipping non-module project: " << p->GetName() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -143,11 +198,11 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// UUID is the key, and the value is a function that creates the node
|
// UUID is the key, and the value is a function that creates the node
|
||||||
typedef std::map<std::string, std::pair<std::shared_ptr<StoryProject>, GenericCreator>> Registry;
|
typedef std::map<std::string, std::pair<std::shared_ptr<IStoryProject>, GenericCreator>> Registry;
|
||||||
Registry m_registry;
|
Registry m_registry;
|
||||||
|
|
||||||
template<class Derived>
|
template<class Derived>
|
||||||
void registerNode(const std::string& uuid, std::shared_ptr<StoryProject> moduleInfo) {
|
void registerNode(const std::string& uuid, std::shared_ptr<IStoryProject> moduleInfo) {
|
||||||
m_registry.insert(std::make_pair(uuid, std::make_pair(moduleInfo, Factory<Derived>::create_func)));
|
m_registry.insert(std::make_pair(uuid, std::make_pair(moduleInfo, Factory<Derived>::create_func)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
25
core/story-manager/src/story_primitive.h
Normal file
25
core/story-manager/src/story_primitive.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "i_story_project.h"
|
||||||
|
|
||||||
|
|
||||||
|
class StoryPrimitive : public IStoryProject
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
StoryPrimitive(const std::string &name)
|
||||||
|
: m_name(name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
virtual ~StoryPrimitive() {};
|
||||||
|
|
||||||
|
virtual std::string GetName() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -558,8 +558,18 @@ bool StoryProject::Load(ResourceManager &manager, NodesFactory &factory)
|
||||||
|
|
||||||
void StoryProject::Save(ResourceManager &manager)
|
void StoryProject::Save(ResourceManager &manager)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["project"] = { {"name", m_name}, {"uuid", m_uuid}, { "title_image", m_titleImage }, { "title_sound", m_titleSound } };
|
j["project"] = {
|
||||||
|
{"name", m_name},
|
||||||
|
{"uuid", m_uuid},
|
||||||
|
{ "title_image", m_titleImage },
|
||||||
|
{ "title_sound", m_titleSound },
|
||||||
|
{"description", m_description},
|
||||||
|
{"type", (m_projectType == IStoryProject::PROJECT_TYPE_STORY) ? "story" : "module"},
|
||||||
|
{"version", m_version}
|
||||||
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
nlohmann::json resourcesData;
|
nlohmann::json resourcesData;
|
||||||
|
|
@ -617,6 +627,11 @@ void StoryProject::Save(ResourceManager &manager)
|
||||||
|
|
||||||
std::ofstream o(m_project_file_path);
|
std::ofstream o(m_project_file_path);
|
||||||
o << std::setw(4) << j << std::endl;
|
o << std::setw(4) << j << std::endl;
|
||||||
|
}
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << '\n';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
class NodesFactory;
|
class NodesFactory;
|
||||||
|
|
||||||
struct StoryProject : public IStoryProject
|
struct StoryProject : public std::enable_shared_from_this<StoryProject>, public IStoryProject
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -30,6 +30,10 @@ public:
|
||||||
return &m_selected;
|
return &m_selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// std::shared_ptr<StoryProject> shared_from_this() {
|
||||||
|
// return shared_from_this();
|
||||||
|
// }
|
||||||
|
|
||||||
std::string MainUuid() const {
|
std::string MainUuid() const {
|
||||||
return "490745ab-df4d-476d-ae27-027e94b8ee0a";
|
return "490745ab-df4d-476d-ae27-027e94b8ee0a";
|
||||||
}
|
}
|
||||||
|
|
@ -86,14 +90,15 @@ public:
|
||||||
const bool IsInitialized() const { return m_initialized; }
|
const bool IsInitialized() const { return m_initialized; }
|
||||||
const bool IsModule() const { return m_projectType == IStoryProject::PROJECT_TYPE_MODULE; }
|
const bool IsModule() const { return m_projectType == IStoryProject::PROJECT_TYPE_MODULE; }
|
||||||
const bool IsStory() const { return m_projectType == IStoryProject::PROJECT_TYPE_STORY; }
|
const bool IsStory() const { return m_projectType == IStoryProject::PROJECT_TYPE_STORY; }
|
||||||
|
void SetProjectType(IStoryProject::Type type) { m_projectType = type; }
|
||||||
|
|
||||||
bool ParseStoryInformation(nlohmann::json &j);
|
bool ParseStoryInformation(nlohmann::json &j);
|
||||||
|
|
||||||
// From IStoryProject
|
// From IStoryProject
|
||||||
virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(const std::string &nodeId) override;
|
virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(const std::string &nodeId);
|
||||||
virtual int OutputsCount(const std::string &nodeId) override;
|
virtual int OutputsCount(const std::string &nodeId);
|
||||||
virtual StoryOptions GetOptions() override { return m_storyOptions; }
|
StoryOptions GetOptions() { return m_storyOptions; }
|
||||||
virtual bool UseResource(const std::string &label) override;
|
virtual bool UseResource(const std::string &label);
|
||||||
|
|
||||||
// Node interaction
|
// Node interaction
|
||||||
std::shared_ptr<StoryPage> CreatePage(const std::string &uuid);
|
std::shared_ptr<StoryPage> CreatePage(const std::string &uuid);
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ Size=1220,694
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Debug##Default]
|
[Window][Debug##Default]
|
||||||
Pos=60,60
|
Pos=106,62
|
||||||
Size=400,400
|
Size=400,400
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Library Manager]
|
[Window][Library Manager]
|
||||||
Pos=796,26
|
Pos=643,26
|
||||||
Size=484,268
|
Size=637,268
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,0
|
DockId=0x00000003,0
|
||||||
|
|
||||||
|
|
@ -21,20 +21,20 @@ Collapsed=0
|
||||||
DockId=0x00000004,0
|
DockId=0x00000004,0
|
||||||
|
|
||||||
[Window][Emulator]
|
[Window][Emulator]
|
||||||
Pos=796,26
|
Pos=643,26
|
||||||
Size=484,268
|
Size=637,268
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,5
|
DockId=0x00000003,5
|
||||||
|
|
||||||
[Window][Code viewer]
|
[Window][Code viewer]
|
||||||
Pos=796,26
|
Pos=643,26
|
||||||
Size=484,268
|
Size=637,268
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,4
|
DockId=0x00000003,4
|
||||||
|
|
||||||
[Window][Resources]
|
[Window][Resources]
|
||||||
Pos=796,26
|
Pos=643,26
|
||||||
Size=484,268
|
Size=637,268
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,1
|
DockId=0x00000003,1
|
||||||
|
|
||||||
|
|
@ -56,20 +56,20 @@ Collapsed=0
|
||||||
DockId=0x00000005,0
|
DockId=0x00000005,0
|
||||||
|
|
||||||
[Window][CPU]
|
[Window][CPU]
|
||||||
Pos=796,26
|
Pos=643,26
|
||||||
Size=484,268
|
Size=637,268
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,2
|
DockId=0x00000003,2
|
||||||
|
|
||||||
[Window][RAM view]
|
[Window][RAM view]
|
||||||
Pos=796,26
|
Pos=643,26
|
||||||
Size=484,268
|
Size=637,268
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,3
|
DockId=0x00000003,3
|
||||||
|
|
||||||
[Window][Properties]
|
[Window][Properties]
|
||||||
Pos=796,296
|
Pos=643,296
|
||||||
Size=484,169
|
Size=637,169
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000006,0
|
DockId=0x00000006,0
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ Size=60,694
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][QuitConfirm]
|
[Window][QuitConfirm]
|
||||||
Pos=479,312
|
Pos=508,312
|
||||||
Size=321,96
|
Size=264,96
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][ProjectPropertiesPopup]
|
[Window][ProjectPropertiesPopup]
|
||||||
|
|
@ -90,13 +90,13 @@ Collapsed=0
|
||||||
|
|
||||||
[Window][Module editor]
|
[Window][Module editor]
|
||||||
Pos=60,26
|
Pos=60,26
|
||||||
Size=734,439
|
Size=581,439
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000001,1
|
DockId=0x00000001,1
|
||||||
|
|
||||||
[Window][Story editor]
|
[Window][Story editor]
|
||||||
Pos=60,26
|
Pos=60,26
|
||||||
Size=734,439
|
Size=581,439
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000001,0
|
DockId=0x00000001,0
|
||||||
|
|
||||||
|
|
@ -122,9 +122,9 @@ Column 2 Width=124
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=60,26 Size=1220,694 Split=Y
|
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=60,26 Size=1220,694 Split=Y
|
||||||
DockNode ID=0x00000007 Parent=0x08BD597D SizeRef=1220,439 Split=X
|
DockNode ID=0x00000007 Parent=0x08BD597D SizeRef=1220,439 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=734,694 CentralNode=1 Selected=0x93ADCAAB
|
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=581,694 CentralNode=1 Selected=0x54E37131
|
||||||
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=484,694 Split=Y Selected=0x52EB28B5
|
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=637,694 Split=Y Selected=0x52EB28B5
|
||||||
DockNode ID=0x00000003 Parent=0x00000002 SizeRef=718,268 Selected=0x4B07C626
|
DockNode ID=0x00000003 Parent=0x00000002 SizeRef=718,268 Selected=0x63869CAF
|
||||||
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=718,169 Selected=0x8C72BEA8
|
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=718,169 Selected=0x8C72BEA8
|
||||||
DockNode ID=0x00000008 Parent=0x08BD597D SizeRef=1220,253 Split=X Selected=0xEA83D666
|
DockNode ID=0x00000008 Parent=0x08BD597D SizeRef=1220,253 Split=X Selected=0xEA83D666
|
||||||
DockNode ID=0x00000004 Parent=0x00000008 SizeRef=610,192 Selected=0xEA83D666
|
DockNode ID=0x00000004 Parent=0x00000008 SizeRef=610,192 Selected=0xEA83D666
|
||||||
|
|
|
||||||
|
|
@ -34,28 +34,47 @@ NodeEditorWindow::NodeEditorWindow(IStoryManager &manager, NodesFactory &factory
|
||||||
, m_editorType(type)
|
, m_editorType(type)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// g OperatorNodeUuid = "0226fdac-8f7a-47d7-8584-b23aceb712ec";
|
||||||
|
// static const std::string CallFunctionNodeUuid = "02745f38-9b11-49fe-94b1-b2a6b78249fb";
|
||||||
|
// static const std::string VariableNodeUuid = "020cca4e-9cdc-47e7-a6a5-53e4c9152ed0";
|
||||||
|
// static const std::string PrintNodeUuid = "02ee27bc-ff1d-4f94-b700-eab55052ad1c";
|
||||||
|
// static const std::string SyscallNodeUuid = "02225cff-4975-400e-8130-41524d8af773";
|
||||||
|
// static const std::string ModuleNodeUuid = "02e4c728-ef72-4003-b7c8-2bee8834a47e";
|
||||||
|
|
||||||
|
|
||||||
// registerNode<MediaNodeWidget>("media-node");
|
// registerNode<MediaNodeWidget>("media-node");
|
||||||
registerNode<OperatorNodeWidget>("operator-node");
|
registerNode<OperatorNodeWidget>(OperatorNodeUuid);
|
||||||
registerNode<CallFunctionNodeWidget>("call-function-node");
|
registerNode<CallFunctionNodeWidget>(CallFunctionNodeUuid);
|
||||||
registerNode<ModuleNodeWidget>("module-node");
|
// registerNode<ModuleNodeWidget>("module-node");
|
||||||
registerNode<VariableNodeWidget>("variable-node");
|
registerNode<VariableNodeWidget>(VariableNodeUuid);
|
||||||
registerNode<PrintNodeWidget>("print-node");
|
registerNode<PrintNodeWidget>(PrintNodeUuid);
|
||||||
registerNode<SyscallNodeWidget>("syscall-node");
|
registerNode<SyscallNodeWidget>(SyscallNodeUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeEditorWindow::~NodeEditorWindow()
|
NodeEditorWindow::~NodeEditorWindow()
|
||||||
{
|
{
|
||||||
m_pages.clear();
|
Clear();
|
||||||
m_story.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeEditorWindow::Clear()
|
||||||
|
{
|
||||||
|
m_pages.clear();
|
||||||
|
m_story.reset();
|
||||||
|
m_callStack.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void NodeEditorWindow::Initialize()
|
void NodeEditorWindow::Initialize()
|
||||||
{
|
{
|
||||||
m_pages.clear();
|
Clear();
|
||||||
m_callStack.clear();
|
}
|
||||||
|
|
||||||
|
void NodeEditorWindow::InitializeProject()
|
||||||
|
{
|
||||||
|
// Always ensure a main page exists (this matches StoryProject::New)
|
||||||
|
if (!m_story->GetPage(m_story->MainUuid()))
|
||||||
|
{
|
||||||
|
m_story->CreatePage(m_story->MainUuid());
|
||||||
|
}
|
||||||
m_currentPage = std::make_shared<NodeEditorPage>(m_story->MainUuid(), "Main");
|
m_currentPage = std::make_shared<NodeEditorPage>(m_story->MainUuid(), "Main");
|
||||||
m_pages.push_back(m_currentPage);
|
m_pages.push_back(m_currentPage);
|
||||||
m_callStack.push_back(m_currentPage);
|
m_callStack.push_back(m_currentPage);
|
||||||
|
|
@ -108,7 +127,7 @@ void NodeEditorWindow::Load(std::shared_ptr<StoryProject> story)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
BaseNodeWidget::InitId();
|
BaseNodeWidget::InitId();
|
||||||
Initialize();
|
InitializeProject();
|
||||||
|
|
||||||
auto [node_begin, node_end] = m_story->Nodes(m_currentPage->Uuid());
|
auto [node_begin, node_end] = m_story->Nodes(m_currentPage->Uuid());
|
||||||
|
|
||||||
|
|
@ -204,6 +223,11 @@ bool NodeEditorWindow::FillConnection(std::shared_ptr<Connection> c, ed::PinId p
|
||||||
|
|
||||||
std::shared_ptr<BaseNodeWidget> NodeEditorWindow::GetSelectedNode()
|
std::shared_ptr<BaseNodeWidget> NodeEditorWindow::GetSelectedNode()
|
||||||
{
|
{
|
||||||
|
if (!m_currentPage)
|
||||||
|
{
|
||||||
|
return nullptr; // No current page, nothing to select
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<BaseNodeWidget> selected;
|
std::shared_ptr<BaseNodeWidget> selected;
|
||||||
|
|
||||||
m_currentPage->Select();
|
m_currentPage->Select();
|
||||||
|
|
@ -225,6 +249,9 @@ void NodeEditorWindow::Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WindowBase::BeginDraw())
|
if (WindowBase::BeginDraw())
|
||||||
|
{
|
||||||
|
|
||||||
|
if (m_currentPage)
|
||||||
{
|
{
|
||||||
m_currentPage->Select();
|
m_currentPage->Select();
|
||||||
|
|
||||||
|
|
@ -232,7 +259,6 @@ void NodeEditorWindow::Draw()
|
||||||
|
|
||||||
ed::Begin(m_currentPage->Uuid().data(), ImVec2(0.0, 0.0f));
|
ed::Begin(m_currentPage->Uuid().data(), ImVec2(0.0, 0.0f));
|
||||||
|
|
||||||
|
|
||||||
// Draw our nodes
|
// Draw our nodes
|
||||||
m_currentPage->Draw();
|
m_currentPage->Draw();
|
||||||
|
|
||||||
|
|
@ -339,17 +365,17 @@ void NodeEditorWindow::Draw()
|
||||||
{
|
{
|
||||||
auto newNodePostion = openPopupPosition;
|
auto newNodePostion = openPopupPosition;
|
||||||
std::shared_ptr<BaseNode> base;
|
std::shared_ptr<BaseNode> base;
|
||||||
auto nodeTypes = m_nodesFactory.GetNodeTypes();
|
auto nodeTypes = m_nodesFactory.LitOfNodes();
|
||||||
|
|
||||||
for (auto &type : nodeTypes)
|
for (auto &type : nodeTypes)
|
||||||
{
|
{
|
||||||
if (ImGui::MenuItem(type.c_str()))
|
if (ImGui::MenuItem(type.name.c_str()))
|
||||||
{
|
{
|
||||||
base = m_nodesFactory.CreateNode(type);
|
base = m_nodesFactory.CreateNode(type.uuid);
|
||||||
if (base)
|
if (base)
|
||||||
{
|
{
|
||||||
m_story->AddNode(m_currentPage->Uuid(), base);
|
m_story->AddNode(m_currentPage->Uuid(), base);
|
||||||
auto n = CreateNodeWidget(type, m_manager, base);
|
auto n = CreateNodeWidget(type.uuid, m_manager, base);
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
n->Base()->SetPosition(newNodePostion.x, newNodePostion.y);
|
n->Base()->SetPosition(newNodePostion.x, newNodePostion.y);
|
||||||
|
|
@ -374,6 +400,17 @@ void NodeEditorWindow::Draw()
|
||||||
|
|
||||||
ed::End();
|
ed::End();
|
||||||
ed::SetCurrentEditor(nullptr);
|
ed::SetCurrentEditor(nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set background color to light gray
|
||||||
|
// ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.7f, 0.7f, 0.7f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
|
ImGui::Text("Please load or create a project.");
|
||||||
|
|
||||||
|
ImGui::PopStyleColor(1); // Pop both colors
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ public:
|
||||||
virtual void Draw() override;
|
virtual void Draw() override;
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
void InitializeProject();
|
||||||
|
void NewProject();
|
||||||
|
void Clear();
|
||||||
void Load(std::shared_ptr<StoryProject> story);
|
void Load(std::shared_ptr<StoryProject> story);
|
||||||
void SaveNodePositions();
|
void SaveNodePositions();
|
||||||
void OpenFunction(const std::string &uuid, const std::string &name);
|
void OpenFunction(const std::string &uuid, const std::string &name);
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ MainWindow::MainWindow()
|
||||||
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);
|
||||||
|
|
||||||
CloseProject();
|
CloseProject();
|
||||||
|
CloseModule();
|
||||||
|
|
||||||
// define style for all directories
|
// define style for all directories
|
||||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir, "", ImVec4(0.5f, 1.0f, 0.9f, 0.9f), ICON_MDI_FOLDER);
|
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir, "", ImVec4(0.5f, 1.0f, 0.9f, 0.9f), ICON_MDI_FOLDER);
|
||||||
|
|
@ -459,9 +460,18 @@ float MainWindow::DrawMainMenuBar()
|
||||||
OpenProject(m_story->GetUuid());
|
OpenProject(m_story->GetUuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::MenuItem("New module"))
|
if (ImGui::MenuItem("New module"))
|
||||||
{
|
{
|
||||||
|
// Current module project
|
||||||
|
CloseModule();
|
||||||
showNewProject = true;
|
showNewProject = true;
|
||||||
|
NewModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::MenuItem("Save module"))
|
||||||
|
{
|
||||||
|
SaveModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -492,6 +502,8 @@ float MainWindow::DrawMainMenuBar()
|
||||||
SaveProject();
|
SaveProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (ImGui::MenuItem("Close project"))
|
if (ImGui::MenuItem("Close project"))
|
||||||
{
|
{
|
||||||
CloseProject();
|
CloseProject();
|
||||||
|
|
@ -502,6 +514,11 @@ float MainWindow::DrawMainMenuBar()
|
||||||
showParameters = true;
|
showParameters = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::MenuItem("Close module"))
|
||||||
|
{
|
||||||
|
CloseModule();
|
||||||
|
}
|
||||||
|
|
||||||
if (!init)
|
if (!init)
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
|
@ -575,6 +592,8 @@ bool MainWindow::Initialize()
|
||||||
bool success = false;
|
bool success = false;
|
||||||
LoadParams();
|
LoadParams();
|
||||||
|
|
||||||
|
m_nodesFactory.ScanModules();
|
||||||
|
|
||||||
// GUI Init
|
// GUI Init
|
||||||
if (m_gui.Initialize())
|
if (m_gui.Initialize())
|
||||||
{
|
{
|
||||||
|
|
@ -896,6 +915,21 @@ void MainWindow::OpenProject(const std::string &uuid)
|
||||||
RefreshProjectInformation();
|
RefreshProjectInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::NewModule()
|
||||||
|
{
|
||||||
|
auto module = m_nodesFactory.NewModule();
|
||||||
|
m_moduleEditorWindow.Load(module);
|
||||||
|
|
||||||
|
m_moduleEditorWindow.Enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::SaveModule()
|
||||||
|
{
|
||||||
|
m_nodesFactory.SaveAllModules(m_resources);;
|
||||||
|
Log("Modules saved");
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::OpenModule(const std::string &uuid)
|
void MainWindow::OpenModule(const std::string &uuid)
|
||||||
{
|
{
|
||||||
m_module = m_nodesFactory.GetModule(uuid);
|
m_module = m_nodesFactory.GetModule(uuid);
|
||||||
|
|
@ -930,7 +964,7 @@ void MainWindow::CloseProject()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
m_resources.Clear();
|
m_resources.Clear();
|
||||||
m_nodeEditorWindow.Initialize();
|
m_nodeEditorWindow.Clear();
|
||||||
m_nodeEditorWindow.Disable();
|
m_nodeEditorWindow.Disable();
|
||||||
|
|
||||||
m_emulatorWindow.ClearImage();
|
m_emulatorWindow.ClearImage();
|
||||||
|
|
@ -951,7 +985,7 @@ void MainWindow::CloseProject()
|
||||||
|
|
||||||
void MainWindow::CloseModule()
|
void MainWindow::CloseModule()
|
||||||
{
|
{
|
||||||
m_moduleEditorWindow.Initialize();
|
m_moduleEditorWindow.Clear();
|
||||||
m_moduleEditorWindow.Disable();
|
m_moduleEditorWindow.Disable();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1337,6 +1371,12 @@ void MainWindow::SaveParams()
|
||||||
void MainWindow::LoadParams()
|
void MainWindow::LoadParams()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Modules directory
|
||||||
|
std::filesystem::path dlDir = std::filesystem::path(pf::getConfigHome()) / "ost_modules";
|
||||||
|
std::filesystem::create_directories(dlDir);
|
||||||
|
m_nodesFactory.SetModulesRootDirectory(dlDir.string());
|
||||||
|
|
||||||
std::string loc = pf::getConfigHome() + "/ost_settings.json";
|
std::string loc = pf::getConfigHome() + "/ost_settings.json";
|
||||||
// read a JSON file
|
// read a JSON file
|
||||||
std::ifstream i(loc);
|
std::ifstream i(loc);
|
||||||
|
|
@ -1365,6 +1405,6 @@ void MainWindow::LoadParams()
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
|
Log(e.what(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ private:
|
||||||
void CloseProject();
|
void CloseProject();
|
||||||
|
|
||||||
void OpenModule(const std::string &uuid);
|
void OpenModule(const std::string &uuid);
|
||||||
|
void NewModule();
|
||||||
|
void SaveModule();
|
||||||
void CloseModule();
|
void CloseModule();
|
||||||
|
|
||||||
// From IStoryManager (proxy to StoryProject class)
|
// From IStoryManager (proxy to StoryProject class)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue