Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
BTEditorCommand.cpp
Go to the documentation of this file.
1// [DEPRECATED - Phase 5 - 2026-03-07]
2// Ce fichier est archivé. Il ne doit plus être inclus ni compilé.
3// Remplacé par : BPCommandSystem (Blueprint::CreateNodeCommand, etc.)
4// Voir : Docs/BLUEPRINT-REFACTOR-MARCH-2026.md
5
6/**
7 * @file BTEditorCommand.cpp
8 * @brief Implementation of command pattern for behavior tree editor
9 */
10
11#include "BTEditorCommand.h"
12#include <iostream>
13#include <algorithm>
14
15namespace Olympe
16{
17 // =============================================================================
18 // BTCommandStack Implementation
19 // =============================================================================
20
21 void BTCommandStack::Execute(std::unique_ptr<BTEditorCommand> cmd)
22 {
23 if (!cmd)
24 return;
25
26 cmd->Execute();
27
28 m_undoStack.push_back(std::move(cmd));
29
30 // Clear redo stack after new action
31 m_redoStack.clear();
32
33 // Limit stack size
34 if (m_undoStack.size() > kMaxStackSize)
35 {
36 m_undoStack.erase(m_undoStack.begin());
37 }
38 }
39
41 {
42 if (!CanUndo())
43 return;
44
45 auto cmd = std::move(m_undoStack.back());
46 m_undoStack.pop_back();
47
48 cmd->Undo();
49
50 m_redoStack.push_back(std::move(cmd));
51 }
52
54 {
55 if (!CanRedo())
56 return;
57
58 auto cmd = std::move(m_redoStack.back());
59 m_redoStack.pop_back();
60
61 cmd->Execute();
62
63 m_undoStack.push_back(std::move(cmd));
64 }
65
67 {
68 return !m_undoStack.empty();
69 }
70
72 {
73 return !m_redoStack.empty();
74 }
75
77 {
78 if (!CanUndo())
79 return "";
80
81 return m_undoStack.back()->GetDescription();
82 }
83
85 {
86 if (!CanRedo())
87 return "";
88
89 return m_redoStack.back()->GetDescription();
90 }
91
93 {
94 m_undoStack.clear();
95 m_redoStack.clear();
96 }
97
98 // =============================================================================
99 // AddNodeCommand Implementation
100 // =============================================================================
101
103 const std::string& name, const Vector& position)
104 : m_tree(tree)
105 , m_nodeType(type)
106 , m_nodeName(name)
107 , m_position(position)
108 , m_createdNodeId(0)
109 {
110 }
111
113 {
114 if (!m_tree)
115 return;
116
118 std::cout << "[AddNodeCommand] Created node ID=" << m_createdNodeId << std::endl;
119 }
120
122 {
123 if (!m_tree || m_createdNodeId == 0)
124 return;
125
127 std::cout << "[AddNodeCommand] Removed node ID=" << m_createdNodeId << std::endl;
128 }
129
131 {
132 return "Add Node: " + m_nodeName;
133 }
134
135 // =============================================================================
136 // DeleteNodeCommand Implementation
137 // =============================================================================
138
140 : m_tree(tree)
141 , m_nodeId(nodeId)
142 {
143 // Save the node data before deletion
144 if (tree)
145 {
146 const BTNode* node = tree->GetNode(nodeId);
147 if (node)
148 {
149 m_savedNode = *node;
150
151 // Save all connections to/from this node
152 for (const auto& otherNode : tree->nodes)
153 {
154 // Check if otherNode is parent of this node
155 for (size_t i = 0; i < otherNode.childIds.size(); ++i)
156 {
157 if (otherNode.childIds[i] == nodeId)
158 {
161 conn.childId = nodeId;
162 conn.isDecorator = false;
163 conn.childIndex = static_cast<int>(i);
164 m_savedConnections.push_back(conn);
165 }
166 }
167
168 if (otherNode.decoratorChildId == nodeId)
169 {
172 conn.childId = nodeId;
173 conn.isDecorator = true;
174 conn.childIndex = 0;
175 m_savedConnections.push_back(conn);
176 }
177 }
178 }
179 }
180 }
181
183 {
184 if (!m_tree)
185 return;
186
188 std::cout << "[DeleteNodeCommand] Deleted node ID=" << m_nodeId << std::endl;
189 }
190
192 {
193 if (!m_tree)
194 return;
195
196 // Restore the node
197 m_tree->nodes.push_back(m_savedNode);
198
199 // Restore connections
200 for (const auto& conn : m_savedConnections)
201 {
202 BTNode* parent = m_tree->GetNode(conn.parentId);
203 if (parent)
204 {
205 if (conn.isDecorator)
206 {
207 parent->decoratorChildId = conn.childId;
208 }
209 else
210 {
211 // Insert at the saved index if possible
212 if (conn.childIndex >= 0 && static_cast<size_t>(conn.childIndex) <= parent->childIds.size())
213 {
214 parent->childIds.insert(parent->childIds.begin() + conn.childIndex, conn.childId);
215 }
216 else
217 {
218 parent->childIds.push_back(conn.childId);
219 }
220 }
221 }
222 }
223
224 std::cout << "[DeleteNodeCommand] Restored node ID=" << m_nodeId << std::endl;
225 }
226
228 {
229 return "Delete Node ID=" + std::to_string(m_nodeId);
230 }
231
232 // =============================================================================
233 // MoveNodeCommand Implementation
234 // =============================================================================
235
237 const Vector& oldPos, const Vector& newPos)
238 : m_tree(tree)
239 , m_nodeId(nodeId)
240 , m_oldPosition(oldPos)
241 , m_newPosition(newPos)
242 {
243 }
244
246 {
247 // Note: In the current implementation, node positions are not stored in BTNode
248 // This would need to be added to BTNode if we want to save positions
249 std::cout << "[MoveNodeCommand] Moved node ID=" << m_nodeId << std::endl;
250 }
251
253 {
254 std::cout << "[MoveNodeCommand] Restored position for node ID=" << m_nodeId << std::endl;
255 }
256
258 {
259 return "Move Node ID=" + std::to_string(m_nodeId);
260 }
261
262 // =============================================================================
263 // ConnectNodesCommand Implementation
264 // =============================================================================
265
267 : m_tree(tree)
268 , m_parentId(parentId)
269 , m_childId(childId)
270 {
271 }
272
274 {
275 if (!m_tree)
276 return;
277
279 std::cout << "[ConnectNodesCommand] Connected " << m_parentId << " -> " << m_childId << std::endl;
280 }
281
283 {
284 if (!m_tree)
285 return;
286
288 std::cout << "[ConnectNodesCommand] Disconnected " << m_parentId << " -X-> " << m_childId << std::endl;
289 }
290
292 {
293 return "Connect " + std::to_string(m_parentId) + " -> " + std::to_string(m_childId);
294 }
295
296 // =============================================================================
297 // DisconnectNodesCommand Implementation
298 // =============================================================================
299
301 : m_tree(tree)
302 , m_parentId(parentId)
303 , m_childId(childId)
304 {
305 }
306
308 {
309 if (!m_tree)
310 return;
311
313 std::cout << "[DisconnectNodesCommand] Disconnected " << m_parentId << " -X-> " << m_childId << std::endl;
314 }
315
317 {
318 if (!m_tree)
319 return;
320
322 std::cout << "[DisconnectNodesCommand] Reconnected " << m_parentId << " -> " << m_childId << std::endl;
323 }
324
326 {
327 return "Disconnect " + std::to_string(m_parentId) + " -X-> " + std::to_string(m_childId);
328 }
329
330 // =============================================================================
331 // EditParameterCommand Implementation
332 // =============================================================================
333
335 const std::string& paramName, const std::string& oldValue,
336 const std::string& newValue, ParamType type)
337 : m_tree(tree)
338 , m_nodeId(nodeId)
339 , m_paramName(paramName)
340 , m_oldValue(oldValue)
341 , m_newValue(newValue)
342 , m_paramType(type)
343 {
344 }
345
347 {
348 if (!m_tree)
349 return;
350
352 if (!node)
353 return;
354
355 // Apply new value based on parameter type
357 {
359 }
360 else if (m_paramType == ParamType::Int)
361 {
362 node->intParams[m_paramName] = std::stoi(m_newValue);
363 }
364 else if (m_paramType == ParamType::Float)
365 {
366 node->floatParams[m_paramName] = std::stof(m_newValue);
367 }
368
369 std::cout << "[EditParameterCommand] Set " << m_paramName << " = " << m_newValue << std::endl;
370 }
371
373 {
374 if (!m_tree)
375 return;
376
378 if (!node)
379 return;
380
381 // Restore old value
383 {
385 }
386 else if (m_paramType == ParamType::Int)
387 {
388 node->intParams[m_paramName] = std::stoi(m_oldValue);
389 }
390 else if (m_paramType == ParamType::Float)
391 {
392 node->floatParams[m_paramName] = std::stof(m_oldValue);
393 }
394
395 std::cout << "[EditParameterCommand] Restored " << m_paramName << " = " << m_oldValue << std::endl;
396 }
397
399 {
400 return "Edit " + m_paramName;
401 }
402
403} // namespace Olympe
Command pattern implementation for behavior tree editor undo/redo.
BTNodeType
Behavior tree node types.
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
std::string GetDescription() const override
Get a human-readable description of the command.
void Undo() override
Undo the command.
BehaviorTreeAsset * m_tree
AddNodeCommand(BehaviorTreeAsset *tree, BTNodeType type, const std::string &name, const Vector &position)
void Execute() override
Execute the command.
std::vector< std::unique_ptr< BTEditorCommand > > m_undoStack
std::string GetUndoDescription() const
Get description of the next undo command.
bool CanRedo() const
Check if redo is available.
void Execute(std::unique_ptr< BTEditorCommand > cmd)
Execute a command and add it to the undo stack.
void Undo()
Undo the last command.
bool CanUndo() const
Check if undo is available.
static const size_t kMaxStackSize
std::string GetRedoDescription() const
Get description of the next redo command.
std::vector< std::unique_ptr< BTEditorCommand > > m_redoStack
void Clear()
Clear all commands.
void Redo()
Redo the last undone command.
std::string GetDescription() const override
Get a human-readable description of the command.
ConnectNodesCommand(BehaviorTreeAsset *tree, uint32_t parentId, uint32_t childId)
void Execute() override
Execute the command.
void Undo() override
Undo the command.
void Undo() override
Undo the command.
std::vector< Connection > m_savedConnections
void Execute() override
Execute the command.
std::string GetDescription() const override
Get a human-readable description of the command.
DeleteNodeCommand(BehaviorTreeAsset *tree, uint32_t nodeId)
BehaviorTreeAsset * m_tree
void Undo() override
Undo the command.
std::string GetDescription() const override
Get a human-readable description of the command.
void Execute() override
Execute the command.
DisconnectNodesCommand(BehaviorTreeAsset *tree, uint32_t parentId, uint32_t childId)
std::string GetDescription() const override
Get a human-readable description of the command.
EditParameterCommand(BehaviorTreeAsset *tree, uint32_t nodeId, const std::string &paramName, const std::string &oldValue, const std::string &newValue, ParamType type)
void Undo() override
Undo the command.
void Execute() override
Execute the command.
std::string GetDescription() const override
Get a human-readable description of the command.
void Undo() override
Undo the command.
MoveNodeCommand(BehaviorTreeAsset *tree, uint32_t nodeId, const Vector &oldPos, const Vector &newPos)
void Execute() override
Execute the command.
< Provides AssetID and INVALID_ASSET_ID
Represents a single node in a behavior tree.
std::vector< uint32_t > childIds
IDs of child nodes.
uint32_t decoratorChildId
std::map< std::string, std::string > stringParams
String parameters.
uint32_t AddNode(BTNodeType type, const std::string &name, const Vector &position)
bool RemoveNode(uint32_t nodeId)
bool ConnectNodes(uint32_t parentId, uint32_t childId)
std::vector< BTNode > nodes
BTNode * GetNode(uint32_t nodeId)
bool DisconnectNodes(uint32_t parentId, uint32_t childId)