Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
VisualScriptEditorPanel_Helpers.cpp
Go to the documentation of this file.
1/**
2 * @file VisualScriptEditorPanel_Helpers.cpp
3 * @brief Helper methods for VisualScriptEditorPanel (node/link allocation and UID generation).
4 * @author Olympe Engine
5 * @date 2026-03-09
6 *
7 * @details This file contains utility helper methods for:
8 * - Node ID allocation (AllocNodeID)
9 * - Link ID allocation (AllocLinkID)
10 * - Attribute UID generation for execution and data pins:
11 * * ExecInAttrUID() — Execution input attribute UID
12 * * ExecOutAttrUID() — Execution output attribute UID
13 * * DataInAttrUID() — Data input attribute UID
14 * * DataOutAttrUID() — Data output attribute UID
15 *
16 * UID Scheme:
17 * The attribute UID system uses a deterministic formula: nodeID * 10000 + offset
18 * This allows rapid attribute lookup and maintains unique IDs across node/pin combinations.
19 * Offsets:
20 * 0–99: Reserved for exec-in pin
21 * 100–199: Exec-out pins (index 0-99)
22 * 200–299: Data-in pins (index 0-99)
23 * 300–399: Data-out pins (index 0-99)
24 *
25 * C++14 compliant — no std::optional, structured bindings, std::filesystem.
26 */
27
29#include "DebugController.h"
30#include "TabManager.h"
32#include "ConditionRegistry.h"
33#include "OperatorRegistry.h"
34#include "BBVariableRegistry.h"
35#include "MathOpOperand.h"
36#include "../system/system_utils.h"
37#include "../system/system_consts.h"
38#include "../NodeGraphCore/GlobalTemplateBlackboard.h"
39
40#include "../third_party/imgui/imgui.h"
41#include "../third_party/imnodes/imnodes.h"
42#include "../json_helper.h"
43#include "../TaskSystem/TaskGraphLoader.h"
44
45#include <fstream>
46#include <iostream>
47#include <algorithm>
48#include <cmath>
49#include <cstring>
50#include <sstream>
51#include <iomanip>
52#include <cstdlib>
53#include <unordered_set>
54
55namespace Olympe {
56
57// ============================================================================
58// ID Allocation Helpers
59// ============================================================================
60
61/**
62 * @brief Allocate a unique node ID
63 *
64 * Returns the next available node ID and increments the internal counter.
65 * Each node in the editor canvas must have a unique ID for:
66 * - ImNodes attribute UID generation (nodeID * 10000 + offset)
67 * - Node lookup in editor node list
68 * - Serialization and deserialization
69 *
70 * @return int Next available node ID (starting from 0)
71 * @note IDs are never reused; once a node is deleted, its ID is permanently consumed.
72 * This prevents potential ID collisions in undo/redo stacks.
73 * @see AddNode(), RemoveNode()
74 */
76{
77 return m_nextNodeID++;
78}
79
80/**
81 * @brief Allocate a unique link ID
82 *
83 * Returns the next available link ID and increments the internal counter.
84 * Each connection between nodes must have a unique ID for:
85 * - ImNodes link tracking
86 * - Link validation and lookup
87 * - Undo/redo serialization
88 *
89 * @return int Next available link ID (starting from 0)
90 * @note Like node IDs, link IDs are never reused to maintain consistency across
91 * undo/redo operations and command history.
92 * @see AddLink(), RemoveLink()
93 */
95{
96 return m_nextLinkID++;
97}
98
99// ============================================================================
100// Attribute UID Generation
101// ============================================================================
102
103/**
104 * @brief Generate a unique attribute UID for the execution input pin of a node
105 *
106 * Formula: nodeID * 10000 + 0
107 *
108 * The execution input (or "In" pin) is where the node receives execution flow from
109 * previous nodes. Only one exec-in pin per node is allowed.
110 *
111 * @param nodeID The node's unique ID
112 * @return int Unique attribute UID for the node's exec-in pin
113 * @note Returns the same value for the same nodeID (deterministic, reversible formula).
114 * ImNodes uses this UID to identify pin endpoints for links.
115 * @see ExecOutAttrUID(), DataInAttrUID(), DataOutAttrUID()
116 */
117int VisualScriptEditorPanel::ExecInAttrUID(int nodeID) const
118{
119 return nodeID * 10000 + 0;
120}
121
122/**
123 * @brief Generate a unique attribute UID for an execution output pin of a node
124 *
125 * Formula: nodeID * 10000 + 100 + pinIndex
126 *
127 * Execution output pins (or "Out" pins) are where the node sends execution flow
128 * to downstream nodes. A node may have multiple exec-out pins for control flow:
129 * - EntryPoint -> {"Out"}
130 * - Branch -> {"Then", "Else"}
131 * - While -> {"Loop", "Completed"}
132 * - Switch -> {"Case_0", "Case_1", ...}
133 *
134 * @param nodeID The node's unique ID
135 * @param pinIndex The index of the output pin (0–99)
136 * @return int Unique attribute UID for the specific exec-out pin
137 * @note Supports up to 100 execution output pins per node (offset range: 100–199).
138 * @see ExecInAttrUID(), DataInAttrUID(), DataOutAttrUID()
139 */
140int VisualScriptEditorPanel::ExecOutAttrUID(int nodeID, int pinIndex) const
141{
142 return nodeID * 10000 + 100 + pinIndex;
143}
144
145/**
146 * @brief Generate a unique attribute UID for a data input pin of a node
147 *
148 * Formula: nodeID * 10000 + 200 + pinIndex
149 *
150 * Data input pins carry variable/parameter values from other nodes:
151 * - MathOp -> {"A", "B"} (input operands for mathematical expressions)
152 * - SetBBValue -> {"Value"} (the value to store in blackboard)
153 * - Branch -> Dynamic condition pins
154 *
155 * Data pins are distinct from execution pins and can coexist on the same node.
156 *
157 * @param nodeID The node's unique ID
158 * @param pinIndex The index of the input pin (0–99)
159 * @return int Unique attribute UID for the specific data-in pin
160 * @note Supports up to 100 data input pins per node (offset range: 200–299).
161 * Index 0–99 allows sufficient room for typical data-heavy nodes.
162 * @see ExecInAttrUID(), ExecOutAttrUID(), DataOutAttrUID()
163 */
164int VisualScriptEditorPanel::DataInAttrUID(int nodeID, int pinIndex) const
165{
166 return nodeID * 10000 + 200 + pinIndex;
167}
168
169/**
170 * @brief Generate a unique attribute UID for a data output pin of a node
171 *
172 * Formula: nodeID * 10000 + 300 + pinIndex
173 *
174 * Data output pins carry computed or retrieved values to downstream nodes:
175 * - GetBBValue -> {"Value"} (the retrieved variable value)
176 * - MathOp -> {"Result"} (the computed result)
177 * - Dynamic operand outputs (from condition presets)
178 *
179 * @param nodeID The node's unique ID
180 * @param pinIndex The index of the output pin (0–99)
181 * @return int Unique attribute UID for the specific data-out pin
182 * @note Supports up to 100 data output pins per node (offset range: 300–399).
183 * @see ExecInAttrUID(), ExecOutAttrUID(), DataInAttrUID()
184 */
185int VisualScriptEditorPanel::DataOutAttrUID(int nodeID, int pinIndex) const
186{
187 return nodeID * 10000 + 300 + pinIndex;
188}
189
190/**
191 * @brief Extracts SubGraph file path from a node definition.
192 *
193 * @details Returns the SubGraphPath if the node is a SubGraph type and has a valid path set.
194 * Otherwise returns an empty string.
195 *
196 * @param def The node definition to check
197 * @return The SubGraphPath if applicable, else empty string
198 */
200{
201 if (def.Type == TaskNodeType::SubGraph && !def.SubGraphPath.empty())
202 {
203 return def.SubGraphPath;
204 }
205 return "";
206}
207
208/**
209 * @brief Handles double-click on a node (opens SubGraph, etc).
210 *
211 * @details If the node is a SubGraph type with a file path set, opens that file
212 * in a new tab via TabManager::OpenFileInTab().
213 *
214 * @param nodeID ID of the node that was double-clicked
215 */
217{
218 // Find the node in m_editorNodes
219 for (size_t i = 0; i < m_editorNodes.size(); ++i)
220 {
221 if (m_editorNodes[i].nodeID == nodeID)
222 {
223 const TaskNodeDefinition& def = m_editorNodes[i].def;
224 std::string subGraphPath = GetNodeSubGraphPath(def);
225
226 if (!subGraphPath.empty())
227 {
228 SYSTEM_LOG << "[VSEditor] Double-clicked SubGraph node #" << nodeID
229 << ", opening: " << subGraphPath << "\n";
230
231 // Open the SubGraph file in a new tab
233 }
234 else
235 {
236 SYSTEM_LOG << "[VSEditor] Double-clicked SubGraph node #" << nodeID
237 << " but no file path is set.\n";
238 }
239 return;
240 }
241 }
242
243 SYSTEM_LOG << "[VSEditor] Double-click: node #" << nodeID << " not found.\n";
244}
245
246} // namespace Olympe
UI-side registry of available atomic tasks with display metadata.
Wrapper around the graph blackboard entries for dropdown editors.
Registry of available condition types for Branch/While node dropdowns.
Runtime debug controller for ATS Visual Scripting (Phase 5).
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
Defines MathOpOperand — operand references for MathOp nodes.
Hardcoded lists of math and comparison operators for dropdown editors.
Central manager for the multi-graph tab system.
ImNodes-based graph editor for ATS Visual Script graphs (Phase 5).
static TabManager & Get()
Returns the global singleton instance.
std::string OpenFileInTab(const std::string &filePath)
Opens a file in a new tab.
void OnNodeDoubleClicked(int nodeID)
Handles double-click on a node (opens SubGraph, etc).
int ExecOutAttrUID(int nodeID, int pinIndex) const
Maps node ID + pin index -> ImNodes attribute UID for exec-out pins.
int DataInAttrUID(int nodeID, int pinIndex) const
Maps node ID + data pin index -> ImNodes attribute UID for data-in pins.
std::string GetNodeSubGraphPath(const TaskNodeDefinition &def) const
Extracts SubGraph file path from a node definition.
int m_nextNodeID
Next available node ID.
int DataOutAttrUID(int nodeID, int pinIndex) const
Maps node ID + data pin index -> ImNodes attribute UID for data-out pins.
int ExecInAttrUID(int nodeID) const
Maps node ID -> ImNodes attribute UID for an exec-in pin.
std::vector< VSEditorNode > m_editorNodes
Editor nodes (mirrors m_template.Nodes + position/selection state)
int m_nextLinkID
Next available ImNodes link ID.
< Provides AssetID and INVALID_ASSET_ID
@ SubGraph
Sub-graph call (SubTask)
Full description of a single node in the task graph.
std::string SubGraphPath
For SubGraph: path to the sub-graph JSON.
TaskNodeType Type
Node role.
#define SYSTEM_LOG