From 765f78fbc629fa2f608bd7994d30314638708c70 Mon Sep 17 00:00:00 2001 From: "anthony@rabine.fr" Date: Sun, 19 Oct 2025 22:00:39 +0200 Subject: [PATCH] Add all system calls as dedicated nodes --- .../interfaces/i_story_project.h | 3 +- core/story-manager/src/nodes/compare_node.cpp | 18 -- core/story-manager/src/nodes/compare_node.h | 19 -- .../src/nodes/play_media_node.cpp | 35 +++ .../story-manager/src/nodes/play_media_node.h | 21 ++ .../src/nodes/send_signal_node.cpp | 29 +++ .../src/nodes/send_signal_node.h | 21 ++ core/story-manager/src/nodes/syscall_node.cpp | 38 --- core/story-manager/src/nodes/syscall_node.h | 42 ---- .../src/nodes/wait_delay_node.cpp | 29 +++ .../story-manager/src/nodes/wait_delay_node.h | 21 ++ .../src/nodes/wait_event_node.cpp | 74 ++++++ .../story-manager/src/nodes/wait_event_node.h | 35 +++ core/story-manager/src/nodes_factory.h | 16 +- core/story-manager/src/story_primitive.h | 2 +- core/story-manager/src/story_project.cpp | 7 +- core/story-manager/src/story_project.h | 2 +- core/tests/CMakeLists.txt | 6 +- story-editor/CMakeLists.txt | 12 +- story-editor/imgui.ini | 54 ++--- story-editor/src/app/app_controller.cpp | 10 +- story-editor/src/main_window.cpp | 19 +- .../src/node_editor/base_node_widget.h | 2 + .../node_editor/play_media_node_widget.cpp | 51 ++++ .../src/node_editor/play_media_node_widget.h | 21 ++ .../node_editor/send_signal_node_widget.cpp | 39 +++ .../src/node_editor/send_signal_node_widget.h | 20 ++ .../src/node_editor/syscall_node_widget.cpp | 46 ---- .../src/node_editor/syscall_node_widget.h | 27 --- .../src/node_editor/variable_node_widget.cpp | 5 + .../node_editor/wait_delay_node_widget.cpp | 44 ++++ .../src/node_editor/wait_delay_node_widget.h | 20 ++ .../node_editor/wait_event_node_widget.cpp | 224 ++++++++++++++++++ .../src/node_editor/wait_event_node_widget.h | 23 ++ story-editor/src/windows/variables_window.cpp | 2 +- 35 files changed, 789 insertions(+), 248 deletions(-) delete mode 100644 core/story-manager/src/nodes/compare_node.cpp delete mode 100644 core/story-manager/src/nodes/compare_node.h create mode 100644 core/story-manager/src/nodes/play_media_node.cpp create mode 100644 core/story-manager/src/nodes/play_media_node.h create mode 100644 core/story-manager/src/nodes/send_signal_node.cpp create mode 100644 core/story-manager/src/nodes/send_signal_node.h delete mode 100644 core/story-manager/src/nodes/syscall_node.cpp delete mode 100644 core/story-manager/src/nodes/syscall_node.h create mode 100644 core/story-manager/src/nodes/wait_delay_node.cpp create mode 100644 core/story-manager/src/nodes/wait_delay_node.h create mode 100644 core/story-manager/src/nodes/wait_event_node.cpp create mode 100644 core/story-manager/src/nodes/wait_event_node.h create mode 100644 story-editor/src/node_editor/play_media_node_widget.cpp create mode 100644 story-editor/src/node_editor/play_media_node_widget.h create mode 100644 story-editor/src/node_editor/send_signal_node_widget.cpp create mode 100644 story-editor/src/node_editor/send_signal_node_widget.h delete mode 100644 story-editor/src/node_editor/syscall_node_widget.cpp delete mode 100644 story-editor/src/node_editor/syscall_node_widget.h create mode 100644 story-editor/src/node_editor/wait_delay_node_widget.cpp create mode 100644 story-editor/src/node_editor/wait_delay_node_widget.h create mode 100644 story-editor/src/node_editor/wait_event_node_widget.cpp create mode 100644 story-editor/src/node_editor/wait_event_node_widget.h diff --git a/core/story-manager/interfaces/i_story_project.h b/core/story-manager/interfaces/i_story_project.h index f24cb8f..84480bd 100644 --- a/core/story-manager/interfaces/i_story_project.h +++ b/core/story-manager/interfaces/i_story_project.h @@ -43,7 +43,8 @@ public: virtual void SetName(const std::string &name) = 0; virtual void SetUuid(const std::string &uuid) = 0; - virtual void ScanVariable(const std::function element)>& operation) = 0; + // Callback can return false to break the loop + virtual void ScanVariable(const std::function element)>& operation) = 0; virtual void AddVariable() = 0; virtual void DeleteVariable(int i) = 0; diff --git a/core/story-manager/src/nodes/compare_node.cpp b/core/story-manager/src/nodes/compare_node.cpp deleted file mode 100644 index 9048320..0000000 --- a/core/story-manager/src/nodes/compare_node.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "compare_node.h" -#include "story_project.h" -#include "connection.h" -#include "sys_lib.h" - - -CompareNode::CompareNode(const std::string &type) - : BaseNode(type, "Compare Node") -{ - -} - - -void CompareNode::Initialize() -{ - -} - diff --git a/core/story-manager/src/nodes/compare_node.h b/core/story-manager/src/nodes/compare_node.h deleted file mode 100644 index 1624176..0000000 --- a/core/story-manager/src/nodes/compare_node.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include "i_story_manager.h" -#include "base_node.h" -#include "i_script_node.h" -#include "i_story_project.h" - -class CompareNode : public BaseNode -{ -public: - CompareNode(const std::string &type); - - virtual void Initialize() override; - - -private: -}; - diff --git a/core/story-manager/src/nodes/play_media_node.cpp b/core/story-manager/src/nodes/play_media_node.cpp new file mode 100644 index 0000000..d0911da --- /dev/null +++ b/core/story-manager/src/nodes/play_media_node.cpp @@ -0,0 +1,35 @@ +// core/story-manager/src/nodes/play_media_node.cpp +#include "play_media_node.h" + +PlayMediaNode::PlayMediaNode(const std::string &type) + : BaseNode(type, "Play Media") +{ + SetBehavior(BaseNode::BEHAVIOR_EXECUTION); + SetupExecutionPorts(true, 1, true); // IN 0 (exec), OUT 0 (exec) + + // Ports data + AddInputPort(Port::Type::DATA_PORT, "Image"); + AddInputPort(Port::Type::DATA_PORT, "Sound"); + + nlohmann::json j{ + {"status_variable_uuid", m_statusVariableUuid} + }; + SetInternalData(j); +} + +void PlayMediaNode::Initialize() +{ + nlohmann::json j = GetInternalData(); + + if (j.contains("status_variable_uuid")) { + m_statusVariableUuid = j["status_variable_uuid"].get(); + } +} + +void PlayMediaNode::SetStatusVariable(const std::string& varUuid) +{ + m_statusVariableUuid = varUuid; + nlohmann::json j = GetInternalData(); + j["status_variable_uuid"] = m_statusVariableUuid; + SetInternalData(j); +} \ No newline at end of file diff --git a/core/story-manager/src/nodes/play_media_node.h b/core/story-manager/src/nodes/play_media_node.h new file mode 100644 index 0000000..c425b04 --- /dev/null +++ b/core/story-manager/src/nodes/play_media_node.h @@ -0,0 +1,21 @@ +// core/story-manager/src/nodes/play_media_node.h +#pragma once + +#include +#include "base_node.h" +#include "i_story_project.h" + +class PlayMediaNode : public BaseNode +{ +public: + PlayMediaNode(const std::string &type = "play-media-node"); + + void Initialize() override; + + // Variable optionnelle pour le status de retour + std::string GetStatusVariableUuid() const { return m_statusVariableUuid; } + void SetStatusVariable(const std::string& varUuid); + +private: + std::string m_statusVariableUuid; // Optionnel +}; \ No newline at end of file diff --git a/core/story-manager/src/nodes/send_signal_node.cpp b/core/story-manager/src/nodes/send_signal_node.cpp new file mode 100644 index 0000000..6027901 --- /dev/null +++ b/core/story-manager/src/nodes/send_signal_node.cpp @@ -0,0 +1,29 @@ +// core/story-manager/src/nodes/send_signal_node.cpp +#include "send_signal_node.h" + +SendSignalNode::SendSignalNode(const std::string &type) + : BaseNode(type, "Send Signal") +{ + SetBehavior(BaseNode::BEHAVIOR_EXECUTION); + SetupExecutionPorts(true, 1, true); // IN 0, OUT 0 + + AddInputPort(Port::Type::DATA_PORT, "Signal ID"); + + nlohmann::json j{{"signal_id", m_signalId}}; + SetInternalData(j); +} + +void SendSignalNode::Initialize() +{ + nlohmann::json j = GetInternalData(); + if (j.contains("signal_id")) { + m_signalId = j["signal_id"].get(); + } +} + +void SendSignalNode::SetSignalId(uint32_t id) +{ + m_signalId = id; + nlohmann::json j{{"signal_id", m_signalId}}; + SetInternalData(j); +} \ No newline at end of file diff --git a/core/story-manager/src/nodes/send_signal_node.h b/core/story-manager/src/nodes/send_signal_node.h new file mode 100644 index 0000000..64f7083 --- /dev/null +++ b/core/story-manager/src/nodes/send_signal_node.h @@ -0,0 +1,21 @@ +// core/story-manager/src/nodes/send_signal_node.h +#pragma once + +#include +#include "base_node.h" +#include "i_story_project.h" + +class SendSignalNode : public BaseNode +{ +public: + SendSignalNode(const std::string &type = "send-signal-node"); + + void Initialize() override; + + // ID du signal à envoyer + uint32_t GetSignalId() const { return m_signalId; } + void SetSignalId(uint32_t id); + +private: + uint32_t m_signalId{0}; +}; \ No newline at end of file diff --git a/core/story-manager/src/nodes/syscall_node.cpp b/core/story-manager/src/nodes/syscall_node.cpp deleted file mode 100644 index d2c355e..0000000 --- a/core/story-manager/src/nodes/syscall_node.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "syscall_node.h" -#include "story_project.h" -#include "connection.h" -#include "sys_lib.h" - - -SyscallNode::SyscallNode(const std::string &type) - : BaseNode(type, "Syscall Node") -{ - nlohmann::json j{ {"syscall_number", m_syscallNumber} }; - SetInternalData(j); -} - -void SyscallNode::Initialize() -{ - nlohmann::json j = GetInternalData(); - - m_syscallNumber = j["syscall_number"].get(); -} - -int SyscallNode::GetArgumentsSize() const -{ - int size = 0; - - switch (m_syscallNumber) - { - case SYSCALL_PLAY_MEDIA: - size = 2; - break; - default: - break; - } - - - return size; -} - - diff --git a/core/story-manager/src/nodes/syscall_node.h b/core/story-manager/src/nodes/syscall_node.h deleted file mode 100644 index 24e9fee..0000000 --- a/core/story-manager/src/nodes/syscall_node.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - -#include "variable.h" -#include "i_story_manager.h" -#include "base_node.h" -#include "i_script_node.h" -#include "i_story_project.h" - -class SyscallNode : public BaseNode -{ -public: - - enum SysCallType : int { - SYSCALL_PLAY_MEDIA = 1, - SYSCALL_WAIT_EVENT = 2, - SYSCALL_SEND_SIGNAL = 3, - SYSCALL_PRINT = 4, - SYSCALL_WAIT_MILLISEC = 5 - }; - - SyscallNode(const std::string &type = "syscall-node"); - - virtual void Initialize() override; - - int GetSyscallNumber() const { - return m_syscallNumber; - } - - void SetSyscallNumber(int syscallNumber) { - m_syscallNumber = syscallNumber; - SetInternalData({{"syscall_number", m_syscallNumber}}); - } - - int GetArgumentsSize() const; - -private: - int m_syscallNumber{4}; - -}; - diff --git a/core/story-manager/src/nodes/wait_delay_node.cpp b/core/story-manager/src/nodes/wait_delay_node.cpp new file mode 100644 index 0000000..71f0d6b --- /dev/null +++ b/core/story-manager/src/nodes/wait_delay_node.cpp @@ -0,0 +1,29 @@ +// core/story-manager/src/nodes/wait_delay_node.cpp +#include "wait_delay_node.h" + +WaitDelayNode::WaitDelayNode(const std::string &type) + : BaseNode(type, "Wait Delay") +{ + SetBehavior(BaseNode::BEHAVIOR_EXECUTION); + SetupExecutionPorts(true, 1, true); // IN 0, OUT 0 + + AddInputPort(Port::Type::DATA_PORT, "Duration"); + + nlohmann::json j{{"duration_ms", m_durationMs}}; + SetInternalData(j); +} + +void WaitDelayNode::Initialize() +{ + nlohmann::json j = GetInternalData(); + if (j.contains("duration_ms")) { + m_durationMs = j["duration_ms"].get(); + } +} + +void WaitDelayNode::SetDuration(uint32_t ms) +{ + m_durationMs = ms; + nlohmann::json j{{"duration_ms", m_durationMs}}; + SetInternalData(j); +} \ No newline at end of file diff --git a/core/story-manager/src/nodes/wait_delay_node.h b/core/story-manager/src/nodes/wait_delay_node.h new file mode 100644 index 0000000..58ee870 --- /dev/null +++ b/core/story-manager/src/nodes/wait_delay_node.h @@ -0,0 +1,21 @@ +// core/story-manager/src/nodes/wait_delay_node.h +#pragma once + +#include +#include "base_node.h" +#include "i_story_project.h" + +class WaitDelayNode : public BaseNode +{ +public: + WaitDelayNode(const std::string &type = "wait-delay-node"); + + void Initialize() override; + + // Durée en millisecondes + uint32_t GetDuration() const { return m_durationMs; } + void SetDuration(uint32_t ms); + +private: + uint32_t m_durationMs{1000}; +}; \ No newline at end of file diff --git a/core/story-manager/src/nodes/wait_event_node.cpp b/core/story-manager/src/nodes/wait_event_node.cpp new file mode 100644 index 0000000..5c40afe --- /dev/null +++ b/core/story-manager/src/nodes/wait_event_node.cpp @@ -0,0 +1,74 @@ +// core/story-manager/src/nodes/wait_event_node.cpp +#include "wait_event_node.h" + +WaitEventNode::WaitEventNode(const std::string &type) + : BaseNode(type, "Wait Event") +{ + SetBehavior(BaseNode::BEHAVIOR_EXECUTION); + SetupExecutionPorts(true, 1, true); // IN 0 (exec), OUT 0 (exec) + + AddInputPort(Port::Type::DATA_PORT, "Event Mask"); + AddInputPort(Port::Type::DATA_PORT, "Timeout"); + + nlohmann::json j{ + {"event_mask", m_eventMask}, + {"timeout", m_timeout}, + {"result_variable_uuid", m_resultVariableUuid} + }; + SetInternalData(j); +} + +void WaitEventNode::Initialize() +{ + nlohmann::json j = GetInternalData(); + + if (j.contains("event_mask")) { + m_eventMask = j["event_mask"].get(); + } + if (j.contains("timeout")) { + m_timeout = j["timeout"].get(); + } + if (j.contains("result_variable_uuid")) { + m_resultVariableUuid = j["result_variable_uuid"].get(); + } +} + +void WaitEventNode::SetEventMask(uint32_t mask) +{ + m_eventMask = mask; + nlohmann::json j = GetInternalData(); + j["event_mask"] = m_eventMask; + SetInternalData(j); +} + +void WaitEventNode::SetTimeout(uint32_t ms) +{ + m_timeout = ms; + nlohmann::json j = GetInternalData(); + j["timeout"] = m_timeout; + SetInternalData(j); +} + +void WaitEventNode::SetResultVariable(const std::string& varUuid) +{ + m_resultVariableUuid = varUuid; + nlohmann::json j = GetInternalData(); + j["result_variable_uuid"] = m_resultVariableUuid; + SetInternalData(j); +} + +std::shared_ptr WaitEventNode::ResolveResultVariable( + const std::vector>& variables) const +{ + if (m_resultVariableUuid.empty()) { + return nullptr; + } + + for (const auto& var : variables) { + if (var->GetUuid() == m_resultVariableUuid) { + return var; + } + } + + return nullptr; +} \ No newline at end of file diff --git a/core/story-manager/src/nodes/wait_event_node.h b/core/story-manager/src/nodes/wait_event_node.h new file mode 100644 index 0000000..147412b --- /dev/null +++ b/core/story-manager/src/nodes/wait_event_node.h @@ -0,0 +1,35 @@ +// core/story-manager/src/nodes/wait_event_node.h +#pragma once + +#include +#include "base_node.h" +#include "i_story_project.h" +#include "variable.h" + +class WaitEventNode : public BaseNode +{ +public: + WaitEventNode(const std::string &type = "wait-event-node"); + + void Initialize() override; + + // Event mask (bits pour différents types d'événements) + uint32_t GetEventMask() const { return m_eventMask; } + void SetEventMask(uint32_t mask); + + // Timeout en millisecondes (0 = infini) + uint32_t GetTimeout() const { return m_timeout; } + void SetTimeout(uint32_t ms); + + // Variable de destination pour le code de retour + std::string GetResultVariableUuid() const { return m_resultVariableUuid; } + void SetResultVariable(const std::string& varUuid); + + // Helper pour résoudre la variable (utilisé par TAC Generator) + std::shared_ptr ResolveResultVariable(const std::vector>& variables) const; + +private: + uint32_t m_eventMask{0b10000000000}; // Défaut: OK + Home + EndAudio + uint32_t m_timeout{0}; // 0 = infini + std::string m_resultVariableUuid; +}; \ No newline at end of file diff --git a/core/story-manager/src/nodes_factory.h b/core/story-manager/src/nodes_factory.h index 04439ec..b1ed0de 100644 --- a/core/story-manager/src/nodes_factory.h +++ b/core/story-manager/src/nodes_factory.h @@ -12,19 +12,25 @@ #include "variable_node.h" #include "operator_node.h" #include "print_node.h" -#include "syscall_node.h" #include "story_project.h" #include "story_primitive.h" #include "function_entry_node.h" #include "branch_node.h" +#include "wait_delay_node.h" +#include "wait_event_node.h" +#include "play_media_node.h" +#include "send_signal_node.h" static const std::string 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 FunctionEntryNodeUuid = "02fd145a-b3a6-43c2-83ce-6a187e6d4b5b"; static const std::string BranchNodeUuid = "027b723d-2327-4646-a17a-79ddc2e016e4"; +static const std::string WaitEventNodeUuid = "02225cff-4975-400e-8130-41524d8af773"; +static const std::string WaitDelayNodeUuid = "02455ef0-4975-4546-94de-720cae6baae3"; +static const std::string PlayMediaNodeUuid = "0285e90a-2eb7-4605-baa9-b3712a14dff8"; +static const std::string SendSignalNodeUuid = "02c2ce4b-8783-47cb-a55f-90056bebd64b"; typedef std::shared_ptr (*GenericCreator)(const std::string &type); @@ -42,10 +48,12 @@ public: registerNode(CallFunctionNodeUuid, std::make_shared("Call function")); registerNode(VariableNodeUuid, std::make_shared("Variable")); registerNode(PrintNodeUuid, std::make_shared("Print")); - registerNode(SyscallNodeUuid, std::make_shared("System call")); registerNode(FunctionEntryNodeUuid, std::make_shared("Function entry")); registerNode(BranchNodeUuid, std::make_shared("Branch")); - + registerNode(WaitEventNodeUuid, std::make_shared("Wait Event")); + registerNode(WaitDelayNodeUuid, std::make_shared("Wait Delay")); + registerNode(PlayMediaNodeUuid, std::make_shared("Play Media")); + registerNode(SendSignalNodeUuid, std::make_shared("Send Signal")); } ~NodesFactory() = default; diff --git a/core/story-manager/src/story_primitive.h b/core/story-manager/src/story_primitive.h index 47a9ff2..65b1ef5 100644 --- a/core/story-manager/src/story_primitive.h +++ b/core/story-manager/src/story_primitive.h @@ -79,7 +79,7 @@ public: m_uuid = uuid; } - virtual void ScanVariable(const std::function element)>& operation) override { + virtual void ScanVariable(const std::function element)>& operation) override { } virtual void AddVariable() override { diff --git a/core/story-manager/src/story_project.cpp b/core/story-manager/src/story_project.cpp index cea15a9..6011958 100644 --- a/core/story-manager/src/story_project.cpp +++ b/core/story-manager/src/story_project.cpp @@ -11,7 +11,6 @@ #include "variable_node.h" #include "operator_node.h" #include "print_node.h" -#include "syscall_node.h" #include "sys_lib.h" #include "assembly_generator_chip32_tac.h" #include "nodes_factory.h" @@ -225,11 +224,13 @@ std::pair>::iterator, std::list>::iterator, std::list>::iterator>(); } -void StoryProject::ScanVariable(const std::function element)>& operation) +void StoryProject::ScanVariable(const std::function element)>& operation) { for (auto &v : m_variables) { - operation(v); + bool ret = operation(v); + if (!ret) + break; } } diff --git a/core/story-manager/src/story_project.h b/core/story-manager/src/story_project.h index c121d99..1a908cc 100644 --- a/core/story-manager/src/story_project.h +++ b/core/story-manager/src/story_project.h @@ -104,7 +104,7 @@ public: std::pair>::iterator, std::list>::iterator> Links(const std::string_view &page_uuid); - void ScanVariable(const std::function element)>& operation) override; + void ScanVariable(const std::function element)>& operation) override; void AddVariable() override; void DeleteVariable(int i) override; diff --git a/core/tests/CMakeLists.txt b/core/tests/CMakeLists.txt index 8e5e54a..d120ed2 100644 --- a/core/tests/CMakeLists.txt +++ b/core/tests/CMakeLists.txt @@ -36,8 +36,12 @@ add_executable(${PROJECT_NAME} ../story-manager/src/nodes/branch_node.cpp ../story-manager/src/nodes/print_node.cpp ../story-manager/src/nodes/variable_node.cpp - ../story-manager/src/nodes/syscall_node.cpp ../story-manager/src/nodes/connection.cpp + ../story-manager/src/nodes/wait_event_node.cpp + ../story-manager/src/nodes/wait_delay_node.cpp + ../story-manager/src/nodes/play_media_node.cpp + ../story-manager/src/nodes/send_signal_node.cpp + ../chip32/chip32_assembler.cpp ../chip32/chip32_vm.c diff --git a/story-editor/CMakeLists.txt b/story-editor/CMakeLists.txt index d3b38de..a150b9c 100644 --- a/story-editor/CMakeLists.txt +++ b/story-editor/CMakeLists.txt @@ -147,8 +147,11 @@ set(SRCS src/node_editor/variable_node_widget.cpp src/node_editor/operator_node_widget.cpp src/node_editor/print_node_widget.cpp - src/node_editor/syscall_node_widget.cpp src/node_editor/branch_node_widget.cpp + src/node_editor/wait_event_node_widget.cpp + src/node_editor/wait_delay_node_widget.cpp + src/node_editor/play_media_node_widget.cpp + src/node_editor/send_signal_node_widget.cpp src/gui.cpp src/media_converter.cpp @@ -182,12 +185,15 @@ set(SRCS ../core/story-manager/src/nodes/base_node.cpp - ../core/story-manager/src/nodes/compare_node.cpp ../core/story-manager/src/nodes/branch_node.cpp ../core/story-manager/src/nodes/variable_node.cpp ../core/story-manager/src/nodes/module_node.cpp ../core/story-manager/src/nodes/print_node.cpp - ../core/story-manager/src/nodes/syscall_node.cpp + ../core/story-manager/src/nodes/wait_event_node.cpp + ../core/story-manager/src/nodes/wait_delay_node.cpp + ../core/story-manager/src/nodes/play_media_node.cpp + ../core/story-manager/src/nodes/send_signal_node.cpp + ../core/story-manager/src/nodes/connection.cpp ../core/story-manager/src/story_db.cpp ../core/story-manager/src/sys_lib.cpp diff --git a/story-editor/imgui.ini b/story-editor/imgui.ini index 8f3681c..8d6b23d 100644 --- a/story-editor/imgui.ini +++ b/story-editor/imgui.ini @@ -1,6 +1,6 @@ [Window][WindowOverViewport_11111111] Pos=60,26 -Size=1429,832 +Size=1220,694 Collapsed=0 [Window][Debug##Default] @@ -9,32 +9,32 @@ Size=400,400 Collapsed=0 [Window][Library Manager] -Pos=554,26 -Size=935,607 +Pos=710,26 +Size=570,469 Collapsed=0 DockId=0x00000002,0 [Window][Console] -Pos=60,635 -Size=618,223 +Pos=60,497 +Size=527,223 Collapsed=0 DockId=0x00000004,0 [Window][Emulator] -Pos=554,26 -Size=935,607 +Pos=710,26 +Size=570,469 Collapsed=0 DockId=0x00000002,5 [Window][Code viewer] -Pos=554,26 -Size=935,607 +Pos=710,26 +Size=570,469 Collapsed=0 DockId=0x00000002,4 [Window][Resources] -Pos=554,26 -Size=935,607 +Pos=710,26 +Size=570,469 Collapsed=0 DockId=0x00000002,1 @@ -50,32 +50,32 @@ Size=150,42 Collapsed=0 [Window][Variables] -Pos=680,635 -Size=809,223 +Pos=589,497 +Size=691,223 Collapsed=0 DockId=0x00000005,0 [Window][CPU] -Pos=554,26 -Size=935,607 +Pos=710,26 +Size=570,469 Collapsed=0 DockId=0x00000002,2 [Window][RAM view] -Pos=554,26 -Size=935,607 +Pos=710,26 +Size=570,469 Collapsed=0 DockId=0x00000002,3 [Window][Properties] -Pos=680,635 -Size=809,223 +Pos=589,497 +Size=691,223 Collapsed=0 DockId=0x00000005,1 [Window][ToolBar] Pos=0,26 -Size=60,832 +Size=60,694 Collapsed=0 [Window][QuitConfirm] @@ -90,13 +90,13 @@ Collapsed=0 [Window][Module editor] Pos=60,26 -Size=492,607 +Size=648,469 Collapsed=0 DockId=0x00000001,0 [Window][Story editor] Pos=60,26 -Size=492,607 +Size=648,469 Collapsed=0 DockId=0x00000001,1 @@ -106,8 +106,8 @@ Size=687,422 Collapsed=0 [Window][Error List] -Pos=60,635 -Size=618,223 +Pos=60,497 +Size=527,223 Collapsed=0 DockId=0x00000004,1 @@ -155,10 +155,10 @@ Column 2 Weight=1.0000 Column 3 Width=60 [Docking][Data] -DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=60,26 Size=1429,832 Split=Y +DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=60,26 Size=1220,694 Split=Y DockNode ID=0x00000007 Parent=0x08BD597D SizeRef=1220,469 Split=X - DockNode ID=0x00000001 Parent=0x00000007 SizeRef=492,694 CentralNode=1 Selected=0x93ADCAAB - DockNode ID=0x00000002 Parent=0x00000007 SizeRef=935,694 Selected=0x63869CAF + DockNode ID=0x00000001 Parent=0x00000007 SizeRef=648,694 CentralNode=1 Selected=0x93ADCAAB + DockNode ID=0x00000002 Parent=0x00000007 SizeRef=570,694 Selected=0x63869CAF DockNode ID=0x00000008 Parent=0x08BD597D SizeRef=1220,223 Split=X Selected=0xEA83D666 DockNode ID=0x00000004 Parent=0x00000008 SizeRef=621,192 Selected=0xEA83D666 DockNode ID=0x00000005 Parent=0x00000008 SizeRef=813,192 Selected=0x8C72BEA8 diff --git a/story-editor/src/app/app_controller.cpp b/story-editor/src/app/app_controller.cpp index 501926d..45bfa5c 100644 --- a/story-editor/src/app/app_controller.cpp +++ b/story-editor/src/app/app_controller.cpp @@ -20,11 +20,11 @@ AppController::AppController(ILogger& logger, EventBus& eventBus) : m_logger(logger) - , m_eventBus(eventBus) // m_eventBus pour les événements - , m_resources(logger) // m_resources a besoin d'un IStoryManager/IResourceSource - , m_nodesFactory(logger) // m_nodesFactory a besoin d'un IStoryManager/IResourceSource - , m_libraryManager(logger, m_nodesFactory) // m_libraryManager a besoin d'un IStoryManager/INodeFactory - , m_player(*this) // m_player a besoin d'un IAudioEvent + , m_eventBus(eventBus) + , m_resources(logger) + , m_nodesFactory(logger) + , m_libraryManager(logger, m_nodesFactory) + , m_player(*this) , m_webServer(m_libraryManager) { diff --git a/story-editor/src/main_window.cpp b/story-editor/src/main_window.cpp index 3e46c34..1e9d5e6 100644 --- a/story-editor/src/main_window.cpp +++ b/story-editor/src/main_window.cpp @@ -32,9 +32,12 @@ #include "variable_node_widget.h" #include "operator_node_widget.h" #include "print_node_widget.h" -#include "syscall_node_widget.h" #include "function_entry_widget.h" #include "branch_node_widget.h" +#include "play_media_node_widget.h" +#include "send_signal_node_widget.h" +#include "wait_delay_node_widget.h" +#include "wait_event_node_widget.h" MainWindow::MainWindow(ILogger& logger, EventBus& eventBus, AppController& appController) : m_logger(logger) @@ -57,24 +60,18 @@ MainWindow::MainWindow(ILogger& logger, EventBus& eventBus, AppController& appCo // define style for all files ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile, "", ImVec4(1.0f, 1.0f, 1.0f, 1.0f), ICON_MDI_FILE); - - // 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("media-node"); m_widgetFactory.registerNode(OperatorNodeUuid); m_widgetFactory.registerNode(CallFunctionNodeUuid); // m_widgetFactory.registerNode("module-node"); m_widgetFactory.registerNode(VariableNodeUuid); m_widgetFactory.registerNode(PrintNodeUuid); - m_widgetFactory.registerNode(SyscallNodeUuid); m_widgetFactory.registerNode(FunctionEntryNodeUuid); m_widgetFactory.registerNode(BranchNodeUuid); + m_widgetFactory.registerNode(WaitEventNodeUuid); + m_widgetFactory.registerNode(WaitDelayNodeUuid); + m_widgetFactory.registerNode(PlayMediaNodeUuid); + m_widgetFactory.registerNode(SendSignalNodeUuid); m_eventBus.Subscribe([this](const OpenProjectEvent &event) { OpenProject(event.GetUuid()); diff --git a/story-editor/src/node_editor/base_node_widget.h b/story-editor/src/node_editor/base_node_widget.h index 57e121a..1b2020f 100644 --- a/story-editor/src/node_editor/base_node_widget.h +++ b/story-editor/src/node_editor/base_node_widget.h @@ -130,6 +130,8 @@ public: void SetTitle(const std::string& title) { m_title = title; } std::string GetTitle() const { return m_title; } + IStoryManager &Manager() { return m_manager; } + private: IStoryManager &m_manager; std::shared_ptr m_base; diff --git a/story-editor/src/node_editor/play_media_node_widget.cpp b/story-editor/src/node_editor/play_media_node_widget.cpp new file mode 100644 index 0000000..7676faf --- /dev/null +++ b/story-editor/src/node_editor/play_media_node_widget.cpp @@ -0,0 +1,51 @@ +// story-editor/src/node_editor/play_media_node_widget.cpp +#include "play_media_node_widget.h" +#include "IconsMaterialDesignIcons.h" + +PlayMediaNodeWidget::PlayMediaNodeWidget(IStoryManager &manager, std::shared_ptr node) + : BaseNodeWidget(manager, node) +{ + m_playMediaNode = std::dynamic_pointer_cast(node); +} + +void PlayMediaNodeWidget::Initialize() +{ + BaseNodeWidget::Initialize(); +} + +void PlayMediaNodeWidget::DrawProperties(std::shared_ptr story) +{ + ImGui::AlignTextToFramePadding(); + + ImGui::TextWrapped("This node plays media (image and/or sound) at runtime."); + ImGui::Spacing(); + + ImGui::TextColored(ImVec4(0.7f, 0.9f, 1.0f, 1.0f), "Data Inputs:"); + ImGui::BulletText("Port 1: Image name (string)"); + ImGui::Indent(); + ImGui::TextDisabled("Variable or constant with filename"); + ImGui::TextDisabled("Pass 0 or null for no image"); + ImGui::Unindent(); + + ImGui::BulletText("Port 2: Sound name (string)"); + ImGui::Indent(); + ImGui::TextDisabled("Variable or constant with filename"); + ImGui::TextDisabled("Pass 0 or null for no sound"); + ImGui::Unindent(); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.4f, 1.0f), "Note:"); + ImGui::TextWrapped("Connect string variables/constants to the data input ports. " + "The syscall expects filenames relative to the assets folder."); +} + +void PlayMediaNodeWidget::Draw() +{ + ImGui::Text(ICON_MDI_PLAY_CIRCLE " Play Media"); + ImGui::TextDisabled("Data-driven"); + ImGui::TextColored(ImVec4(0.6f, 0.9f, 1.0f, 1.0f), "Image: IN 1"); + ImGui::TextColored(ImVec4(0.6f, 1.0f, 0.9f, 1.0f), "Sound: IN 2"); +} diff --git a/story-editor/src/node_editor/play_media_node_widget.h b/story-editor/src/node_editor/play_media_node_widget.h new file mode 100644 index 0000000..4a0af21 --- /dev/null +++ b/story-editor/src/node_editor/play_media_node_widget.h @@ -0,0 +1,21 @@ +// story-editor/src/node_editor/play_media_node_widget.h +#pragma once + +#include "base_node_widget.h" +#include "i_story_manager.h" +#include "i_story_project.h" +#include "play_media_node.h" + +class PlayMediaNodeWidget : public BaseNodeWidget +{ +public: + PlayMediaNodeWidget(IStoryManager &manager, std::shared_ptr node); + + void Draw() override; + void DrawProperties(std::shared_ptr story) override; + void Initialize() override; + +private: + std::shared_ptr m_playMediaNode; + +}; \ No newline at end of file diff --git a/story-editor/src/node_editor/send_signal_node_widget.cpp b/story-editor/src/node_editor/send_signal_node_widget.cpp new file mode 100644 index 0000000..2de1744 --- /dev/null +++ b/story-editor/src/node_editor/send_signal_node_widget.cpp @@ -0,0 +1,39 @@ +// story-editor/src/node_editor/send_signal_node_widget.cpp +#include "send_signal_node_widget.h" +#include "IconsMaterialDesignIcons.h" + +SendSignalNodeWidget::SendSignalNodeWidget(IStoryManager &manager, std::shared_ptr node) + : BaseNodeWidget(manager, node) +{ + m_sendSignalNode = std::dynamic_pointer_cast(node); +} + +void SendSignalNodeWidget::Initialize() +{ + BaseNodeWidget::Initialize(); +} + +void SendSignalNodeWidget::DrawProperties(std::shared_ptr story) +{ + ImGui::AlignTextToFramePadding(); + + int signalId = static_cast(m_sendSignalNode->GetSignalId()); + if (ImGui::InputInt("Signal ID", &signalId, 1, 10)) + { + if (signalId < 0) signalId = 0; + m_sendSignalNode->SetSignalId(static_cast(signalId)); + } + + ImGui::Spacing(); + ImGui::TextDisabled("Sends a signal to other processes"); + ImGui::TextDisabled("Signal ID: 0x%08X", m_sendSignalNode->GetSignalId()); +} + +void SendSignalNodeWidget::Draw() +{ + uint32_t signalId = m_sendSignalNode->GetSignalId(); + + ImGui::Text(ICON_MDI_SIGNAL " Signal"); + ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.4f, 1.0f), + "ID: 0x%X", signalId); +} \ No newline at end of file diff --git a/story-editor/src/node_editor/send_signal_node_widget.h b/story-editor/src/node_editor/send_signal_node_widget.h new file mode 100644 index 0000000..bbcacc6 --- /dev/null +++ b/story-editor/src/node_editor/send_signal_node_widget.h @@ -0,0 +1,20 @@ +// story-editor/src/node_editor/send_signal_node_widget.h +#pragma once + +#include "base_node_widget.h" +#include "i_story_manager.h" +#include "i_story_project.h" +#include "send_signal_node.h" + +class SendSignalNodeWidget : public BaseNodeWidget +{ +public: + SendSignalNodeWidget(IStoryManager &manager, std::shared_ptr node); + + void Draw() override; + void DrawProperties(std::shared_ptr story) override; + void Initialize() override; + +private: + std::shared_ptr m_sendSignalNode; +}; \ No newline at end of file diff --git a/story-editor/src/node_editor/syscall_node_widget.cpp b/story-editor/src/node_editor/syscall_node_widget.cpp deleted file mode 100644 index 05de0d3..0000000 --- a/story-editor/src/node_editor/syscall_node_widget.cpp +++ /dev/null @@ -1,46 +0,0 @@ - -#include -#include "syscall_node_widget.h" - -#include "IconsMaterialDesignIcons.h" -#include "story_project.h" -#include "uuid.h" - -SyscallNodeWidget::SyscallNodeWidget(IStoryManager &manager, std::shared_ptr node) - : BaseNodeWidget(manager, node) -{ - m_syscallNode = std::dynamic_pointer_cast(node); -} - -void SyscallNodeWidget::Initialize() -{ - BaseNodeWidget::Initialize(); -} - -void SyscallNodeWidget::DrawProperties(std::shared_ptr story) -{ - ImGui::AlignTextToFramePadding(); - static ImGuiComboFlags flags = 0; - - int syscallNumber = m_syscallNode->GetSyscallNumber(); - if (ImGui::InputInt("Syscall Number", &syscallNumber, 1, 1000)) - { - m_syscallNode->SetSyscallNumber(syscallNumber); - } - -} - -void SyscallNodeWidget::Draw() -{ - switch(m_syscallNode->GetSyscallNumber()) - { - case SyscallNode::SYSCALL_PLAY_MEDIA: - ImGui::Text("Play Media"); - break; - default: - ImGui::Text("Unknown syscall"); - break; - } - -} - diff --git a/story-editor/src/node_editor/syscall_node_widget.h b/story-editor/src/node_editor/syscall_node_widget.h deleted file mode 100644 index 566a285..0000000 --- a/story-editor/src/node_editor/syscall_node_widget.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "base_node_widget.h" -#include "i_story_manager.h" -#include "i_story_project.h" -#include "gui.h" -#include "syscall_node.h" -#include "media_node.h" - -class SyscallNodeWidget : public BaseNodeWidget -{ -public: - SyscallNodeWidget(IStoryManager &manager, std::shared_ptr node); - - void Draw() override; - - virtual void DrawProperties(std::shared_ptr story) override; - virtual void Initialize() override; - -private: - std::shared_ptr m_syscallNode; -}; diff --git a/story-editor/src/node_editor/variable_node_widget.cpp b/story-editor/src/node_editor/variable_node_widget.cpp index 2f8f8bd..7858d8b 100644 --- a/story-editor/src/node_editor/variable_node_widget.cpp +++ b/story-editor/src/node_editor/variable_node_widget.cpp @@ -29,7 +29,9 @@ void VariableNodeWidget::DrawProperties(std::shared_ptr story) if (var->GetUuid() == m_selectedVariableUuid) { m_selectedVariableName = var->GetVariableName(); + return false; } + return true; }); } @@ -61,6 +63,7 @@ void VariableNodeWidget::DrawProperties(std::shared_ptr story) } i++; + return true; }); ImGui::EndCombo(); } @@ -72,7 +75,9 @@ void VariableNodeWidget::DrawProperties(std::shared_ptr story) if (var->GetUuid() == m_selectedVariableUuid) { ImGui::Text("Type: %s", Variable::ValueTypeToString(var->GetValueType()).c_str()); ImGui::Text("Value: %s", var->GetValueAsString().c_str()); + return false; } + return true; }); } } diff --git a/story-editor/src/node_editor/wait_delay_node_widget.cpp b/story-editor/src/node_editor/wait_delay_node_widget.cpp new file mode 100644 index 0000000..33b1a87 --- /dev/null +++ b/story-editor/src/node_editor/wait_delay_node_widget.cpp @@ -0,0 +1,44 @@ +// story-editor/src/node_editor/wait_delay_node_widget.cpp +#include "wait_delay_node_widget.h" +#include "IconsMaterialDesignIcons.h" + +WaitDelayNodeWidget::WaitDelayNodeWidget(IStoryManager &manager, std::shared_ptr node) + : BaseNodeWidget(manager, node) +{ + m_waitDelayNode = std::dynamic_pointer_cast(node); +} + +void WaitDelayNodeWidget::Initialize() +{ + BaseNodeWidget::Initialize(); +} + +void WaitDelayNodeWidget::DrawProperties(std::shared_ptr story) +{ + ImGui::AlignTextToFramePadding(); + + int duration = static_cast(m_waitDelayNode->GetDuration()); + if (ImGui::InputInt("Duration (ms)", &duration, 10, 100)) + { + if (duration < 0) duration = 0; + m_waitDelayNode->SetDuration(static_cast(duration)); + } + + ImGui::Spacing(); + ImGui::TextDisabled("Pauses execution for the specified duration"); +} + +void WaitDelayNodeWidget::Draw() +{ + uint32_t duration = m_waitDelayNode->GetDuration(); + + ImGui::Text(ICON_MDI_TIMER_OUTLINE " Wait"); + + if (duration >= 1000) { + ImGui::TextColored(ImVec4(0.7f, 0.9f, 1.0f, 1.0f), + "%.1f sec", duration / 1000.0f); + } else { + ImGui::TextColored(ImVec4(0.7f, 0.9f, 1.0f, 1.0f), + "%u ms", duration); + } +} \ No newline at end of file diff --git a/story-editor/src/node_editor/wait_delay_node_widget.h b/story-editor/src/node_editor/wait_delay_node_widget.h new file mode 100644 index 0000000..0042a3c --- /dev/null +++ b/story-editor/src/node_editor/wait_delay_node_widget.h @@ -0,0 +1,20 @@ +// story-editor/src/node_editor/wait_delay_node_widget.h +#pragma once + +#include "base_node_widget.h" +#include "i_story_manager.h" +#include "i_story_project.h" +#include "wait_delay_node.h" + +class WaitDelayNodeWidget : public BaseNodeWidget +{ +public: + WaitDelayNodeWidget(IStoryManager &manager, std::shared_ptr node); + + void Draw() override; + void DrawProperties(std::shared_ptr story) override; + void Initialize() override; + +private: + std::shared_ptr m_waitDelayNode; +}; \ No newline at end of file diff --git a/story-editor/src/node_editor/wait_event_node_widget.cpp b/story-editor/src/node_editor/wait_event_node_widget.cpp new file mode 100644 index 0000000..ee97291 --- /dev/null +++ b/story-editor/src/node_editor/wait_event_node_widget.cpp @@ -0,0 +1,224 @@ +// story-editor/src/node_editor/wait_event_node_widget.cpp +#include "wait_event_node_widget.h" +#include "IconsMaterialDesignIcons.h" + +WaitEventNodeWidget::WaitEventNodeWidget(IStoryManager &manager, std::shared_ptr node) + : BaseNodeWidget(manager, node) +{ + m_waitEventNode = std::dynamic_pointer_cast(node); +} + +void WaitEventNodeWidget::Initialize() +{ + BaseNodeWidget::Initialize(); +} + +void WaitEventNodeWidget::DrawProperties(std::shared_ptr story) +{ + ImGui::AlignTextToFramePadding(); + + // Event Mask Editor + ImGui::Text("Event Mask:"); + DrawEventMaskEditor(); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + // Timeout + ImGui::Text("Timeout:"); + int timeout = static_cast(m_waitEventNode->GetTimeout()); + if (ImGui::InputInt("ms##timeout", &timeout, 100, 1000)) + { + if (timeout < 0) timeout = 0; + m_waitEventNode->SetTimeout(static_cast(timeout)); + } + + ImGui::SameLine(); + ImGui::TextDisabled("(0 = infinite)"); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + // Result Variable + ImGui::Text("Result Variable:"); + std::string resultVarUuid = m_waitEventNode->GetResultVariableUuid(); + std::string selectedVarName = "(none - use R0 directly)"; + + // Trouver le nom de la variable sélectionnée + story->ScanVariable([this, &resultVarUuid, &selectedVarName](std::shared_ptr var) { + if (var->GetUuid() == resultVarUuid) { + selectedVarName = var->GetVariableName(); + return false; + } + return true; + }); + + + if (ImGui::BeginCombo("##resultvar", selectedVarName.c_str())) { + if (ImGui::Selectable("(none - use R0 directly)", resultVarUuid.empty())) { + m_waitEventNode->SetResultVariable(""); + } + + int i = 0; + story->ScanVariable([&i, &resultVarUuid, this](std::shared_ptr var) { + if (var->GetValueType() == Variable::ValueType::INTEGER) { + bool isSelected = (var->GetUuid() == resultVarUuid); + if (ImGui::Selectable(var->GetVariableName().c_str(), isSelected)) { + m_waitEventNode->SetResultVariable(var->GetUuid()); + } + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + i++; + return true; + }); + + ImGui::EndCombo(); + } + + + ImGui::Spacing(); + ImGui::TextDisabled("The event code will be stored in this variable"); + ImGui::TextDisabled("or in R0 if no variable is selected"); +} + +void WaitEventNodeWidget::DrawEventMaskEditor() +{ + uint32_t mask = m_waitEventNode->GetEventMask(); + bool changed = false; + + // Affichage hexadécimal + ImGui::Text("Hex: 0x%08X", mask); + + ImGui::Spacing(); + + // Bits individuels (exemple de masque d'événements communs) + // Bit 0-7: Boutons numériques + // Bit 8: OK button + // Bit 9: Home button + // Bit 10: End of audio + + ImGui::BeginGroup(); + + bool bit0 = (mask & (1 << 0)) != 0; + if (ImGui::Checkbox("Bit 0 (Button 0)", &bit0)) { + mask = bit0 ? (mask | (1 << 0)) : (mask & ~(1 << 0)); + changed = true; + } + + bool bit1 = (mask & (1 << 1)) != 0; + if (ImGui::Checkbox("Bit 1 (Button 1)", &bit1)) { + mask = bit1 ? (mask | (1 << 1)) : (mask & ~(1 << 1)); + changed = true; + } + + bool bit2 = (mask & (1 << 2)) != 0; + if (ImGui::Checkbox("Bit 2 (Button 2)", &bit2)) { + mask = bit2 ? (mask | (1 << 2)) : (mask & ~(1 << 2)); + changed = true; + } + + bool bit3 = (mask & (1 << 3)) != 0; + if (ImGui::Checkbox("Bit 3 (Button 3)", &bit3)) { + mask = bit3 ? (mask | (1 << 3)) : (mask & ~(1 << 3)); + changed = true; + } + + ImGui::EndGroup(); + ImGui::SameLine(); + ImGui::BeginGroup(); + + bool bit8 = (mask & (1 << 8)) != 0; + if (ImGui::Checkbox("Bit 8 (OK Button)", &bit8)) { + mask = bit8 ? (mask | (1 << 8)) : (mask & ~(1 << 8)); + changed = true; + } + + bool bit9 = (mask & (1 << 9)) != 0; + if (ImGui::Checkbox("Bit 9 (Home Button)", &bit9)) { + mask = bit9 ? (mask | (1 << 9)) : (mask & ~(1 << 9)); + changed = true; + } + + bool bit10 = (mask & (1 << 10)) != 0; + if (ImGui::Checkbox("Bit 10 (End Audio)", &bit10)) { + mask = bit10 ? (mask | (1 << 10)) : (mask & ~(1 << 10)); + changed = true; + } + + ImGui::EndGroup(); + + ImGui::Spacing(); + + // Presets communs + if (ImGui::Button("Preset: All Events")) { + mask = 0xFFFFFFFF; + changed = true; + } + ImGui::SameLine(); + if (ImGui::Button("Preset: Media End")) { + mask = 0b10000000000; // OK + Home + EndAudio + changed = true; + } + ImGui::SameLine(); + if (ImGui::Button("Clear All")) { + mask = 0; + changed = true; + } + + if (changed) { + m_waitEventNode->SetEventMask(mask); + } +} + +void WaitEventNodeWidget::Draw() +{ + uint32_t mask = m_waitEventNode->GetEventMask(); + uint32_t timeout = m_waitEventNode->GetTimeout(); + + ImGui::Text(ICON_MDI_TIMER_SAND " Wait Event"); + + // Description du masque + std::string desc = GetEventMaskDescription(mask); + ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.4f, 1.0f), "%s", desc.c_str()); + + // Timeout si défini + if (timeout > 0) { + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), + "Timeout: %u ms", timeout); + } +} + +std::string WaitEventNodeWidget::GetEventMaskDescription(uint32_t mask) +{ + if (mask == 0) { + return "No events"; + } + if (mask == 0xFFFFFFFF) { + return "All events"; + } + + // Compter les bits actifs + int bitCount = 0; + for (int i = 0; i < 32; i++) { + if (mask & (1 << i)) bitCount++; + } + + if (bitCount == 1) { + // Un seul événement + for (int i = 0; i < 32; i++) { + if (mask & (1 << i)) { + if (i == 8) return "OK button"; + if (i == 9) return "Home button"; + if (i == 10) return "End audio"; + return "Event bit " + std::to_string(i); + } + } + } + + // Plusieurs événements + return std::to_string(bitCount) + " events"; +} \ No newline at end of file diff --git a/story-editor/src/node_editor/wait_event_node_widget.h b/story-editor/src/node_editor/wait_event_node_widget.h new file mode 100644 index 0000000..d2103a6 --- /dev/null +++ b/story-editor/src/node_editor/wait_event_node_widget.h @@ -0,0 +1,23 @@ +// story-editor/src/node_editor/wait_event_node_widget.h +#pragma once + +#include "base_node_widget.h" +#include "i_story_manager.h" +#include "i_story_project.h" +#include "wait_event_node.h" + +class WaitEventNodeWidget : public BaseNodeWidget +{ +public: + WaitEventNodeWidget(IStoryManager &manager, std::shared_ptr node); + + void Draw() override; + void DrawProperties(std::shared_ptr story) override; + void Initialize() override; + +private: + std::shared_ptr m_waitEventNode; + + void DrawEventMaskEditor(); + std::string GetEventMaskDescription(uint32_t mask); +}; \ No newline at end of file diff --git a/story-editor/src/windows/variables_window.cpp b/story-editor/src/windows/variables_window.cpp index 6eaa7f6..f892592 100644 --- a/story-editor/src/windows/variables_window.cpp +++ b/story-editor/src/windows/variables_window.cpp @@ -100,7 +100,7 @@ void VariablesWindow::DrawVariableEditor(std::shared_ptr story) } ImGui::PopID(); i++; - + return true; }); }