Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
VisualScriptEditorPanel_PinHelpers.cpp
Go to the documentation of this file.
1/**
2 * @file VisualScriptEditorPanel_PinHelpers.cpp
3 * @brief Pin name and type helper methods for VisualScriptEditorPanel.
4 * @author Olympe Engine
5 * @date 2026-03-09
6 *
7 * @details This file contains utility methods for querying pin information:
8 * - GetExecInputPins() — Static exec input pins by node type
9 * - GetExecOutputPins() — Static exec output pins by node type
10 * - GetExecOutputPinsForNode() — Exec pins including dynamic pins
11 * - GetDataInputPins() — Static data input pins by node type
12 * - GetDataOutputPins() — Static data output pins by node type
13 *
14 * These helpers are used throughout the editor for:
15 * - Canvas node rendering (determining which pins to draw)
16 * - Connection validation (checking if a link is allowed)
17 * - UID generation (mapping pin names to attribute IDs)
18 * - Serialization (storing connection information)
19 *
20 * C++14 compliant — no std::optional, structured bindings, std::filesystem.
21 */
22
24#include "DebugController.h"
26#include "ConditionRegistry.h"
27#include "OperatorRegistry.h"
28#include "BBVariableRegistry.h"
29#include "MathOpOperand.h"
30#include "../system/system_utils.h"
31#include "../system/system_consts.h"
32#include "../NodeGraphCore/GlobalTemplateBlackboard.h"
33
34#include "../third_party/imgui/imgui.h"
35#include "../third_party/imnodes/imnodes.h"
36#include "../json_helper.h"
37#include "../TaskSystem/TaskGraphLoader.h"
38
39#include <fstream>
40#include <iostream>
41#include <algorithm>
42#include <cmath>
43#include <cstring>
44#include <sstream>
45#include <iomanip>
46#include <cstdlib>
47#include <unordered_set>
48
49namespace Olympe {
50
51// ============================================================================
52// Execution Pin Helpers
53// ============================================================================
54
55/**
56 * @brief Get the static execution input pins for a given node type
57 *
58 * Returns a list of pin names that represent the execution control flow INTO a node.
59 * Most nodes have a single "In" pin, but some special nodes have no exec-in:
60 * - EntryPoint: No exec-in (it's the entry to the graph)
61 * - GetBBValue: No exec-in (data-pure node, no control flow)
62 * - MathOp: No exec-in (data-pure node, no control flow)
63 *
64 * All other node types receive execution from upstream via an "In" pin.
65 *
66 * @param type The node type to query
67 * @return std::vector<std::string> List of exec input pin names (usually empty or {"In"})
68 * @note Phase 24.2: GetBBValue and MathOp are data-pure, not control-flow nodes
69 * @see GetExecOutputPins(), ExecInAttrUID()
70 */
72{
73 switch (type)
74 {
76 return {}; // No exec-in on EntryPoint
78 return {}; // Phase 24.2: Variable (GetBBValue) is data-pure (no execution pins)
80 return {}; // Phase 24.2: MathOp is data-pure (no execution pins)
81 default:
82 return {"In"};
83 }
84}
85
86/**
87 * @brief Get the static execution output pins for a given node type
88 *
89 * Returns a list of pin names that represent the execution control flow OUT OF a node.
90 * Different node types have different numbers of exec-out pins based on their semantics:
91 * - EntryPoint: {"Out"} — single flow entry
92 * - Branch: {"Then", "Else"} — conditional split
93 * - While: {"Loop", "Completed"} — loop control
94 * - ForEach: {"Loop Body", "Completed"} — iteration control
95 * - DoOnce: {"Out"} — single output
96 * - Delay: {"Completed"} — async completion
97 * - SubGraph: {"Completed"} — subgraph completion
98 * - VSSequence: {"Out"} — sequence step (may have dynamic pins)
99 * - Switch: {"Case_0"} — multi-way branch (may have dynamic pins)
100 * - AtomicTask: {"Completed"} — action completion
101 * - GetBBValue: {} — data-pure node (no exec-out)
102 * - SetBBValue: {"Completed"} — update completion
103 * - MathOp: {} — data-pure node (no exec-out)
104 *
105 * VSSequence and Switch nodes may add dynamic pins at runtime, so use
106 * GetExecOutputPinsForNode() to include those.
107 *
108 * @param type The node type to query
109 * @return std::vector<std::string> List of exec output pin names
110 * @note Phase 24.2: GetBBValue and MathOp are data-pure, not control-flow nodes
111 * @see GetExecOutputPinsForNode(), GetExecInputPins(), ExecOutAttrUID()
112 */
113std::vector<std::string> VisualScriptEditorPanel::GetExecOutputPins(TaskNodeType type)
114{
115 switch (type)
116 {
117 case TaskNodeType::EntryPoint: return {"Out"};
118 case TaskNodeType::Branch: return {"Then", "Else"};
119 case TaskNodeType::While: return {"Loop", "Completed"};
120 case TaskNodeType::ForEach: return {"Loop Body", "Completed"};
121 case TaskNodeType::DoOnce: return {"Out"};
122 case TaskNodeType::Delay: return {"Completed"};
123 case TaskNodeType::SubGraph: return {"Completed"};
124 case TaskNodeType::VSSequence: return {"Out"};
125 case TaskNodeType::Switch: return {"Case_0"};
126 case TaskNodeType::AtomicTask: return {"Completed"};
127 case TaskNodeType::GetBBValue: return {}; // Phase 24.2: Variable (GetBBValue) is data-pure (no execution pins)
128 case TaskNodeType::SetBBValue: return {"Completed"}; // SetBBValue needs exec-out for control flow
129 case TaskNodeType::MathOp: return {}; // Phase 24.2: MathOp is data-pure (no execution pins)
130 default: return {"Out"};
131 }
132}
133
134/**
135 * @brief Get execution output pins for a node, including dynamic pins
136 *
137 * This is the full version of GetExecOutputPins() that accounts for dynamically
138 * added pins. Some node types (VSSequence, Switch) can have user-added exec-out pins
139 * that are not in the static list:
140 * - VSSequence nodes may have "Out_2", "Out_3", etc. added by the user
141 * - Switch nodes may have "Case_1", "Case_2", etc. added by the user
142 *
143 * For all other node types, this returns the same as GetExecOutputPins().
144 *
145 * IMPORTANT ARCHITECTURE NOTE (Phase 1-3 Unification Fix):
146 * ─────────────────────────────────────────────────────────
147 * DynamicExecOutputPins is a DERIVED CACHE that must be kept synchronized with
148 * the semantic authority data (switchCases for Switch nodes, sequenceSteps for VSSequence).
149 *
150 * SOURCES OF TRUTH:
151 * - Switch: switchCases[] (semantic data with values, labels) → Authority
152 * - VSSequence: sequenceSteps[] (if applicable) → Authority
153 *
154 * DERIVED (Auto-Generated):
155 * - DynamicExecOutputPins[] (pin names only, used for rendering)
156 *
157 * REGENERATION TRIGGERS:
158 * Phase 1 (Properties): After modal Apply, regenerated in RenderSwitchNodeProperties()
159 * Phase 2 (Load): After loading from JSON in TaskGraphLoader::ParseNodeV4()
160 * Phase 3 (Canvas): Modal opened for safe editing instead of direct modification
161 *
162 * DEPRECATED DIRECT MODIFICATION:
163 * Do NOT modify DynamicExecOutputPins directly (except for VSSequence which has
164 * its own direct-add system). Always use the modal for Switch nodes.
165 *
166 * @param def The node definition to query
167 * @return std::vector<std::string> List of exec output pin names including dynamic pins
168 * @note Required for accurate pin counting during rendering and UID generation
169 * @see GetExecOutputPins(), RenderSwitchNodeProperties(), TaskGraphLoader::ParseNodeV4()
170 */
172 const TaskNodeDefinition& def) const
173{
174 std::vector<std::string> pins = GetExecOutputPins(def.Type);
175 if (def.Type == TaskNodeType::VSSequence || def.Type == TaskNodeType::Switch)
176 {
177 for (size_t i = 0; i < def.DynamicExecOutputPins.size(); ++i)
178 pins.push_back(def.DynamicExecOutputPins[i]);
179 }
180 return pins;
181}
182
183// ============================================================================
184// Data Pin Helpers
185// ============================================================================
186
187/**
188 * @brief Get the static data input pins for a given node type
189 *
190 * Returns a list of pin names that represent VALUE inputs to a node.
191 * Data pins are distinct from execution pins and carry variable values:
192 * - SetBBValue: {"Value"} — the value to store in the blackboard
193 * - MathOp: {"A", "B"} — left and right operands
194 * - Branch: {} — uses ONLY dynamic data-in pins (no static condition pin)
195 * to avoid pin name conflicts when conditions are edited
196 * - All others: {} — no standard data inputs
197 *
198 * Phase 24 Notes:
199 * - Branch nodes use only dynamic pins generated from condition definitions
200 * - This allows Branch conditions to be added/removed without hardcoded pin lists
201 * - No static "Condition" pin is present to prevent naming conflicts
202 *
203 * @param type The node type to query
204 * @return std::vector<std::string> List of data input pin names
205 * @note Data pins are independent of execution pins; a node can have both types
206 * @see GetDataOutputPins(), DataInAttrUID()
207 */
208std::vector<std::string> VisualScriptEditorPanel::GetDataInputPins(TaskNodeType type)
209{
210 switch (type)
211 {
212 case TaskNodeType::SetBBValue: return {"Value"};
213 case TaskNodeType::MathOp: return {"A", "B"};
214 // Phase 24: Branch nodes use ONLY dynamic data-in pins (Pin-in)
215 // No static "Condition" pin to avoid conflicts with dynamic pins
216 case TaskNodeType::Branch: return {};
217 default: return {};
218 }
219}
220
221/**
222 * @brief Get the static data output pins for a given node type
223 *
224 * Returns a list of pin names that represent VALUE outputs from a node.
225 * Data pins carry computed or retrieved values to downstream nodes:
226 * - GetBBValue: {"Value"} — the retrieved variable value
227 * - MathOp: {"Result"} — the computed arithmetic result
228 * - All others: {} — no standard data outputs
229 *
230 * Phase 24 Notes:
231 * - GetBBValue is a data-pure node (no exec-in/out, only data-out)
232 * - MathOp is a data-pure node (no exec-in/out, only data in/out)
233 * - These nodes are used to build data flow networks without control flow
234 *
235 * @param type The node type to query
236 * @return std::vector<std::string> List of data output pin names
237 * @see GetDataInputPins(), DataOutAttrUID()
238 */
239std::vector<std::string> VisualScriptEditorPanel::GetDataOutputPins(TaskNodeType type)
240{
241 switch (type)
242 {
243 case TaskNodeType::GetBBValue: return {"Value"};
244 case TaskNodeType::MathOp: return {"Result"};
245 default: return {};
246 }
247}
248
249} // 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.
ImNodes-based graph editor for ATS Visual Script graphs (Phase 5).
static std::vector< std::string > GetExecInputPins(TaskNodeType type)
Returns the exec-in pin names for a node type.
static std::vector< std::string > GetDataOutputPins(TaskNodeType type)
Returns the data-out pin names for a node type.
static std::vector< std::string > GetDataInputPins(TaskNodeType type)
Returns the data-in pin names for a node type.
std::vector< std::string > GetExecOutputPinsForNode(const TaskNodeDefinition &def) const
Returns exec-out pin names for a node definition, including any dynamically-added pins (VSSequence).
static std::vector< std::string > GetExecOutputPins(TaskNodeType type)
Returns the exec-out pin names for a node type.
< Provides AssetID and INVALID_ASSET_ID
TaskNodeType
Identifies the role of a node in the task graph.
@ AtomicTask
Leaf node that executes a single atomic task.
@ While
Conditional loop (Loop / Completed exec outputs)
@ SubGraph
Sub-graph call (SubTask)
@ DoOnce
Single-fire execution (reset via Reset pin)
@ Delay
Timer (Completed exec output after N seconds)
@ GetBBValue
Data node – reads a Blackboard key.
@ MathOp
Data node – arithmetic operation (+, -, *, /)
@ SetBBValue
Data node – writes a Blackboard key.
@ ForEach
Iterate over BB list (Loop Body / Completed exec outputs)
@ Switch
Multi-branch on value (N exec outputs)
@ EntryPoint
Unique entry node for VS graphs (replaces Root)
@ Branch
If/Else conditional (Then / Else exec outputs)
@ VSSequence
Execute N outputs in order ("VS" prefix avoids collision with BT Sequence=1)