Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
DynamicDataPinManager.h
Go to the documentation of this file.
1/**
2 * @file DynamicDataPinManager.h
3 * @brief Engine for generating and tracking dynamic data pins (Phase 24.3).
4 * @author Olympe Engine
5 * @date 2026-03-17
6 *
7 * @details
8 * DynamicDataPinManager is responsible for keeping the set of DynamicDataPins
9 * on a NodeBranch in sync with its NodeConditionRef list. Whenever the node's
10 * conditions change (preset added, removed, or updated), the manager
11 * regenerates the pin set to match.
12 *
13 * Design constraints:
14 * - Pin UUIDs are stable between calls to SyncPins() as long as the
15 * condition-index and operand-side are the same. This allows the host to
16 * persist pin IDs across saves.
17 * - O(1) pin lookup by UUID via an internal `std::map`.
18 * - Color coding: dynamic data pins are yellow (ImVec4(1,1,0,1)).
19 * - Labels use the format: "In #<N><L|R>: <condPreview>"
20 * e.g. "In #3L: [Pin:1] <= [Pin:2]"
21 *
22 * Usage:
23 * @code
24 * DynamicDataPinManager mgr(registry);
25 * mgr.SyncPins(node.conditions); // regenerate / keep existing
26 * node.dynamicPins = mgr.GetAllPins(); // write back to node
27 *
28 * // When a preset is deleted:
29 * mgr.InvalidatePreset(deletedPresetID);
30 * node.dynamicPins = mgr.GetAllPins();
31 * @endcode
32 *
33 * C++14 compliant — no std::optional, structured bindings, std::filesystem.
34 */
35
36#pragma once
37
38#include <string>
39#include <vector>
40#include <map>
41
42#include "ConditionPreset.h"
44#include "NodeConditionRef.h"
45#include "DynamicDataPin.h"
46#include "../../BlueprintEditor/ConditionRef.h" // Phase 24: for operand data (Optional parameter)
47
48namespace Olympe {
49
50/**
51 * @class DynamicDataPinManager
52 * @brief Generates, tracks, and invalidates DynamicDataPin objects for a node.
53 *
54 * @details
55 * The manager is bound to a single NodeBranch (one per node). It operates
56 * on the node's `conditions` list and produces the matching `dynamicPins` list.
57 *
58 * Thread safety: single-threaded editor context only.
59 */
61public:
62
63 /**
64 * @brief Constructs the manager bound to the global preset registry.
65 * @param registry Global ConditionPresetRegistry (must outlive this manager).
66 */
68
70
71 // Non-copyable (manages unique IDs)
74
75 // -----------------------------------------------------------------------
76 // Synchronization
77 // -----------------------------------------------------------------------
78
79 /**
80 * @brief Rebuilds the pin set to match the given condition list.
81 *
82 * The method:
83 * 1. Walks every NodeConditionRef in `conditionRefs`.
84 * 2. For each one, looks up the ConditionPreset in the registry.
85 * 3. If the preset's left operand is Pin-mode -> ensures a Left DynamicDataPin
86 * exists for that condition index.
87 * 4. Same for the right operand.
88 * 5. Removes any existing pins that no longer correspond to a
89 * Pin-mode operand in a valid preset.
90 *
91 * Pre-existing pin UUIDs are reused when condition-index + operand-side
92 * match, so graph connections survive minor edits.
93 *
94 * Also updates the `leftPinID` and `rightPinID` fields inside each
95 * NodeConditionRef in the provided vector.
96 *
97 * Phase 24: When operandRefs is provided, pin labels are built from the
98 * ACTUAL operand data (not the static preset preview), allowing dynamic
99 * updates when users change operand modes (e.g., Const -> Pin).
100 *
101 * @param conditionRefs Node's condition list (modified in-place to store
102 * assigned pin IDs).
103 * @param operandRefs Optional: actual operand data for dynamic label building.
104 * If empty, falls back to preset preview.
105 */
106 void SyncPins(std::vector<NodeConditionRef>& conditionRefs,
107 const std::vector<ConditionRef>& operandRefs = std::vector<ConditionRef>());
108
109 /**
110 * @brief Regenerates pins from the current condition list.
111 *
112 * Convenience alias for SyncPins(). Called by NodeBranchRenderer and
113 * NodeConditionsPanel after the user confirms changes in the edit modal.
114 *
115 * Walks every NodeConditionRef, looks up the ConditionPreset in the
116 * registry, and creates/destroys yellow DynamicDataPins for every
117 * operand whose BindingType is Pin. Pre-existing pin UUIDs are reused
118 * so that graph connections survive minor edits.
119 *
120 * Also updates leftPinID / rightPinID inside each NodeConditionRef.
121 *
122 * Phase 24: When operandRefs is provided, pin labels are built from the
123 * ACTUAL operand data (not the static preset preview), allowing dynamic
124 * updates when users change operand modes (e.g., Const -> Pin).
125 *
126 * @param conditionRefs Node's condition list (modified in-place).
127 * @param operandRefs Optional: actual operand data for dynamic label building.
128 * If empty, falls back to preset preview.
129 */
130 void RegeneratePinsFromConditions(std::vector<NodeConditionRef>& conditionRefs,
131 const std::vector<ConditionRef>& operandRefs = std::vector<ConditionRef>());
132
133 // -----------------------------------------------------------------------
134 // Query
135 // -----------------------------------------------------------------------
136
137 /**
138 * @brief Returns all current DynamicDataPins in creation order.
139 */
140 const std::vector<DynamicDataPin>& GetAllPins() const;
141
142 /**
143 * @brief Returns a pointer to the pin with the given UUID, or nullptr.
144 * @param pinID UUID to look up (O(1) via internal map).
145 */
146 const DynamicDataPin* GetPinByID(const std::string& pinID) const;
147
148 /**
149 * @brief Returns a mutable pointer to the pin with the given UUID.
150 * @param pinID UUID to look up.
151 */
152 DynamicDataPin* GetPinByID(const std::string& pinID);
153
154 /**
155 * @brief Returns all pins associated with a specific condition index.
156 * @param conditionIndex Zero-based condition index.
157 */
158 std::vector<const DynamicDataPin*>
159 GetPinsForCondition(int conditionIndex) const;
160
161 /**
162 * @brief Returns the total number of managed pins.
163 */
164 size_t GetPinCount() const;
165
166 // -----------------------------------------------------------------------
167 // Invalidation
168 // -----------------------------------------------------------------------
169
170 /**
171 * @brief Removes all pins that belong to the given preset.
172 *
173 * Should be called when a preset is deleted from the registry so that
174 * stale pins are cleaned up. Also clears leftPinID / rightPinID in any
175 * cached condition refs that pointed to the deleted preset's pins.
176 *
177 * @param deletedPresetID UUID of the preset being deleted.
178 */
179 void InvalidatePreset(const std::string& deletedPresetID);
180
181 /**
182 * @brief Removes all managed pins.
183 */
184 void Clear();
185
186 // -----------------------------------------------------------------------
187 // ImGui color helper
188 // -----------------------------------------------------------------------
189
190 /**
191 * @brief Returns the RGBA color used to render dynamic data pins.
192 *
193 * Always returns yellow: { 1.0f, 1.0f, 0.0f, 1.0f }.
194 * The caller can pass this to ImGui::PushStyleColor(ImGuiCol_Text, …).
195 */
196 static void GetDynamicPinColor(float& r, float& g, float& b, float& a);
197
198private:
199
200 // -----------------------------------------------------------------------
201 // Internal helpers
202 // -----------------------------------------------------------------------
203
204 /**
205 * @brief Looks for an existing pin matching (conditionIndex, position).
206 *
207 * Returns a pointer into m_pins, or nullptr if not found.
208 */
210
211 /**
212 * @brief Builds a unique key for the (conditionIndex, position) pair used
213 * in the lookup map.
214 */
215 static std::string MakePinKey(int conditionIndex, OperandPosition pos);
216
217 // -----------------------------------------------------------------------
218 // State
219 // -----------------------------------------------------------------------
220
221 ConditionPresetRegistry& m_registry; ///< Shared global registry
222 std::vector<DynamicDataPin> m_pins; ///< Ordered pin list
223 std::map<std::string, size_t> m_idIndex; ///< UUID -> index in m_pins (O(1))
224 std::map<std::string, size_t> m_keyIndex; ///< (condIdx,side) -> index in m_pins
225};
226
227} // namespace Olympe
Global registry for ConditionPreset objects, with CRUD, persistence, and validation.
Defines ConditionPreset — a reusable, globally-stored condition expression.
Defines DynamicDataPin — a runtime data-input pin attached to a node.
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
Defines NodeConditionRef — a node's reference to a global ConditionPreset.
Manages the global pool of ConditionPreset objects.
Generates, tracks, and invalidates DynamicDataPin objects for a node.
static std::string MakePinKey(int conditionIndex, OperandPosition pos)
Builds a unique key for the (conditionIndex, position) pair used in the lookup map.
size_t GetPinCount() const
Returns the total number of managed pins.
const DynamicDataPin * GetPinByID(const std::string &pinID) const
Returns a pointer to the pin with the given UUID, or nullptr.
ConditionPresetRegistry & m_registry
Shared global registry.
void SyncPins(std::vector< NodeConditionRef > &conditionRefs, const std::vector< ConditionRef > &operandRefs=std::vector< ConditionRef >())
Rebuilds the pin set to match the given condition list.
const std::vector< DynamicDataPin > & GetAllPins() const
Returns all current DynamicDataPins in creation order.
std::vector< const DynamicDataPin * > GetPinsForCondition(int conditionIndex) const
Returns all pins associated with a specific condition index.
std::map< std::string, size_t > m_keyIndex
(condIdx,side) -> index in m_pins
void RegeneratePinsFromConditions(std::vector< NodeConditionRef > &conditionRefs, const std::vector< ConditionRef > &operandRefs=std::vector< ConditionRef >())
Regenerates pins from the current condition list.
std::vector< DynamicDataPin > m_pins
Ordered pin list.
DynamicDataPin * FindExistingPin(int conditionIndex, OperandPosition pos)
Looks for an existing pin matching (conditionIndex, position).
DynamicDataPinManager(const DynamicDataPinManager &)=delete
DynamicDataPinManager & operator=(const DynamicDataPinManager &)=delete
std::map< std::string, size_t > m_idIndex
UUID -> index in m_pins (O(1))
void InvalidatePreset(const std::string &deletedPresetID)
Removes all pins that belong to the given preset.
static void GetDynamicPinColor(float &r, float &g, float &b, float &a)
Returns the RGBA color used to render dynamic data pins.
void Clear()
Removes all managed pins.
< Provides AssetID and INVALID_ASSET_ID
OperandPosition
Identifies which operand side a DynamicDataPin serves.
A data-input pin created dynamically for a Pin-mode operand.