Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
NodeGraphManager.h
Go to the documentation of this file.
1/*
2 * Olympe Blueprint Editor - Node Graph Manager
3 *
4 * Backend for managing behavior tree and HFSM node graphs
5 * Provides CRUD operations and graph serialization
6 */
7
8#pragma once
9
10#include <string>
11#include <vector>
12#include <map>
13#include <memory>
14#include "../../Source/third_party/nlohmann/json.hpp"
15
16namespace Olympe
17{
18 // Node type enumeration
19 enum class NodeType
20 {
21 // Behavior Tree nodes
27
28 // HFSM nodes
31
32 // Generic
34 };
35
36 // Convert NodeType to string
37 inline const char* NodeTypeToString(NodeType type)
38 {
39 switch (type)
40 {
41 case NodeType::BT_Sequence: return "Sequence";
42 case NodeType::BT_Selector: return "Selector";
43 case NodeType::BT_Action: return "Action";
44 case NodeType::BT_Condition: return "Condition";
45 case NodeType::BT_Decorator: return "Decorator";
46 case NodeType::HFSM_State: return "State";
47 case NodeType::HFSM_Transition: return "Transition";
48 case NodeType::Comment: return "Comment";
49 default: return "Unknown";
50 }
51 }
52
53 // Convert string to NodeType
54 inline NodeType StringToNodeType(const std::string& str)
55 {
56 if (str == "Sequence") return NodeType::BT_Sequence;
57 if (str == "Selector") return NodeType::BT_Selector;
58 if (str == "Action") return NodeType::BT_Action;
59 if (str == "Condition") return NodeType::BT_Condition;
60 if (str == "Decorator") return NodeType::BT_Decorator;
61 if (str == "State") return NodeType::HFSM_State;
62 if (str == "Transition") return NodeType::HFSM_Transition;
63 if (str == "Comment") return NodeType::Comment;
64 return NodeType::BT_Action; // Default
65 }
66
67 // Graph node structure
68 struct GraphNode
69 {
70 int id = 0;
72 std::string name;
73 float posX = 0.0f;
74 float posY = 0.0f;
75
76 // For Action nodes
77 std::string actionType;
78
79 // For Condition nodes
80 std::string conditionType;
81
82 // For Decorator nodes
83 std::string decoratorType;
84
85 // Generic parameters (key-value pairs)
86 std::map<std::string, std::string> parameters;
87
88 // Child nodes (for composite nodes)
89 std::vector<int> childIds;
90
91 // Decorator child (single child for decorators)
93
94 GraphNode() = default;
95 GraphNode(int nodeId, NodeType nodeType, const std::string& nodeName = "")
96 : id(nodeId), type(nodeType), name(nodeName) {}
97 };
98
99 // Link between nodes
101 {
102 int fromNode = 0;
103 int toNode = 0;
104 int fromAttr = 0; // Output attribute ID
105 int toAttr = 0; // Input attribute ID
106
107 GraphLink() = default;
109 };
110
111 // Editor metadata for graph
113 {
114 float zoom = 1.0f;
115 float scrollOffsetX = 0.0f;
116 float scrollOffsetY = 0.0f;
117 std::string lastModified;
118
119 EditorMetadata() = default;
120 };
121
122 // Node graph (Behavior Tree or HFSM)
124 {
125 public:
126 NodeGraph();
127 ~NodeGraph() = default;
128
129 // Graph metadata
130 std::string name;
131 std::string type; // "BehaviorTree" or "HFSM"
132 int rootNodeId = -1;
134
135 // Node CRUD
136 int CreateNode(NodeType type, float x, float y, const std::string& name = "");
137 bool DeleteNode(int nodeId);
138 GraphNode* GetNode(int nodeId);
139 const GraphNode* GetNode(int nodeId) const;
140 std::vector<GraphNode*> GetAllNodes();
141 std::vector<const GraphNode*> GetAllNodes() const;
142
143 // Link operations
144 bool LinkNodes(int parentId, int childId);
145 bool UnlinkNodes(int parentId, int childId);
146 std::vector<GraphLink> GetAllLinks() const;
147
148 // Parameter operations
149 bool SetNodeParameter(int nodeId, const std::string& paramName, const std::string& value);
150 std::string GetNodeParameter(int nodeId, const std::string& paramName) const;
151
152 // Serialization
153 nlohmann::json ToJson() const;
154 static NodeGraph FromJson(const nlohmann::json& j);
155
156 // Validation
157 bool ValidateGraph(std::string& errorMsg) const;
158
159 // Utility
160 void Clear();
161 int GetNextNodeId() const { return m_NextNodeId; }
162
163 // Calculate node positions for v1 blueprints (hierarchical layout)
165
166 // Dirty flag tracking for unsaved changes
167 bool IsDirty() const { return m_IsDirty; }
168 void MarkDirty() { m_IsDirty = true; }
169 void ClearDirty() { m_IsDirty = false; }
170
171 // Filepath tracking
172 const std::string& GetFilepath() const { return m_Filepath; }
173 void SetFilepath(const std::string& filepath) { m_Filepath = filepath; }
174 bool HasFilepath() const { return !m_Filepath.empty(); }
175
176 private:
177 std::vector<GraphNode> m_Nodes;
179 bool m_IsDirty = false;
180 std::string m_Filepath;
181
182 // Helper to find node index
183 int FindNodeIndex(int nodeId) const;
184 };
185
186 /**
187 * NodeGraphManager - Manages multiple node graphs
188 * Allows opening multiple behavior trees/FSMs simultaneously
189 */
191 {
192 public:
193 static NodeGraphManager& Instance();
194 static NodeGraphManager& Get() { return Instance(); }
195
196 // Lifecycle
197 void Initialize();
198 void Shutdown();
199
200 // Graph management
201 int CreateGraph(const std::string& name, const std::string& type);
202 bool CloseGraph(int graphId);
203 NodeGraph* GetGraph(int graphId);
204 const NodeGraph* GetGraph(int graphId) const;
205
206 // Active graph
207 void SetActiveGraph(int graphId);
208 int GetActiveGraphId() const { return m_ActiveGraphId; }
210 const NodeGraph* GetActiveGraph() const;
211
212 // Graph list
213 std::vector<int> GetAllGraphIds() const;
214 std::string GetGraphName(int graphId) const;
215 void SetGraphOrder(const std::vector<int>& newOrder);
216
217 // File operations
218 bool SaveGraph(int graphId, const std::string& filepath);
219 int LoadGraph(const std::string& filepath);
220
221 // State
222 bool IsInitialized() const { return m_Initialized; }
223
224 // Dirty flag queries for graphs
225 bool IsGraphDirty(int graphId) const;
226 bool HasUnsavedChanges() const; // Returns true if any graph has unsaved changes
227
228 private:
231
234
235 private:
236 bool m_Initialized = false;
238 int m_LastActiveGraphId = -1; // Track last active for persistence
240 std::map<int, std::unique_ptr<NodeGraph>> m_Graphs;
241 std::vector<int> m_GraphOrder; // Track insertion order for consistent tab rendering
242 };
243}
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
NodeGraphManager - Manages multiple node graphs Allows opening multiple behavior trees/FSMs simultane...
bool IsGraphDirty(int graphId) const
std::vector< int > GetAllGraphIds() const
void SetGraphOrder(const std::vector< int > &newOrder)
int LoadGraph(const std::string &filepath)
NodeGraphManager(const NodeGraphManager &)=delete
void SetActiveGraph(int graphId)
NodeGraph * GetGraph(int graphId)
std::string GetGraphName(int graphId) const
int CreateGraph(const std::string &name, const std::string &type)
std::vector< int > m_GraphOrder
static NodeGraphManager & Instance()
bool SaveGraph(int graphId, const std::string &filepath)
static NodeGraphManager & Get()
std::map< int, std::unique_ptr< NodeGraph > > m_Graphs
NodeGraphManager & operator=(const NodeGraphManager &)=delete
bool UnlinkNodes(int parentId, int childId)
bool DeleteNode(int nodeId)
void CalculateNodePositionsHierarchical()
const std::string & GetFilepath() const
static NodeGraph FromJson(const nlohmann::json &j)
void SetFilepath(const std::string &filepath)
bool LinkNodes(int parentId, int childId)
EditorMetadata editorMetadata
int GetNextNodeId() const
std::vector< GraphLink > GetAllLinks() const
bool HasFilepath() const
bool SetNodeParameter(int nodeId, const std::string &paramName, const std::string &value)
nlohmann::json ToJson() const
~NodeGraph()=default
std::vector< GraphNode * > GetAllNodes()
std::vector< GraphNode > m_Nodes
bool ValidateGraph(std::string &errorMsg) const
int FindNodeIndex(int nodeId) const
GraphNode * GetNode(int nodeId)
std::string GetNodeParameter(int nodeId, const std::string &paramName) const
int CreateNode(NodeType type, float x, float y, const std::string &name="")
const char * NodeTypeToString(NodeType type)
NodeType StringToNodeType(const std::string &str)
nlohmann::json json
GraphNode()=default
std::string conditionType
std::string decoratorType
std::map< std::string, std::string > parameters
GraphNode(int nodeId, NodeType nodeType, const std::string &nodeName="")
std::vector< int > childIds