3#include "../../system/system_utils.h"
18 node.componentName = componentName;
19 node.InitializePorts(1, 1);
36 {
for (
size_t i = 0;
i <
m_nodes.size(); ++
i) {
if (
m_nodes[
i].nodeId == nodeId) {
return true; } }
return false; }
49 {
if (*
it == nodeId) {
return; } }
52 if (
node !=
nullptr) {
node->selected =
true; }
60 if (
node !=
nullptr) {
node->selected =
false; }
80 if (spacing < 50.0f) spacing = 200.0f;
155 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Starting load from: " << filePath <<
"\n";
159 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] JSON loaded successfully\n";
162 if (!data.contains(
"data"))
164 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] ERROR: Missing 'data' section\n";
184 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Parsing nodes...\n";
186 for (
const auto&
nodeJson : data[
"data"][
"nodes"])
191 std::string componentType =
nodeJson.value(
"componentType",
"");
192 std::string componentName =
nodeJson.value(
"componentName",
"");
194 if (componentType.empty())
196 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] WARNING: Node missing componentType\n";
209 float x =
nodeJson[
"position"].value(
"x", 0.0f);
210 float y =
nodeJson[
"position"].value(
"y", 0.0f);
211 float z =
nodeJson[
"position"].value(
"z", 0.0f);
218 float x =
nodeJson[
"size"].value(
"x", 150.0f);
219 float y =
nodeJson[
"size"].value(
"y", 80.0f);
220 float z =
nodeJson[
"size"].value(
"z", 0.0f);
235 std::string
key =
it.key();
236 const json& value =
it.value();
238 if (value.is_string())
240 node->properties[
key] = value.get<std::string>();
242 else if (value.is_number())
244 node->properties[
key] = std::to_string(value.get<
double>());
246 else if (value.is_boolean())
248 node->properties[
key] = value.get<
bool>() ?
"true" :
"false";
269 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Loaded node: " << componentName
270 <<
" (type=" << componentType <<
", id=" <<
id <<
")\n";
273 catch (
const std::exception&
e)
275 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] ERROR parsing node: " <<
e.what() <<
"\n";
281 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] WARNING: 'nodes' array not found or invalid\n";
285 if (data[
"data"].
contains(
"connections") && data[
"data"][
"connections"].is_array())
287 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Parsing connections...\n";
289 for (
const auto&
connJson : data[
"data"][
"connections"])
301 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Loaded connection: "
306 catch (
const std::exception&
e)
308 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] ERROR parsing connection: " <<
e.what() <<
"\n";
314 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] WARNING: 'connections' array not found or invalid\n";
318 if (data[
"data"].
contains(
"canvasState") && data[
"data"][
"canvasState"].is_object())
322 float zoom = data[
"data"][
"canvasState"].value(
"zoom", 1.0f);
323 float offsetX = data[
"data"][
"canvasState"].value(
"offsetX", 0.0f);
324 float offsetY = data[
"data"][
"canvasState"].value(
"offsetY", 0.0f);
329 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Canvas state restored: zoom="
330 << zoom <<
", offset=(" << offsetX <<
", " << offsetY <<
")\n";
332 catch (
const std::exception&
e)
334 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] ERROR restoring canvas state: " <<
e.what() <<
"\n";
342 if (data.contains(
"data") && data[
"data"].contains(
"behaviorTreeRef"))
344 std::string
btRef = data[
"data"][
"behaviorTreeRef"].get<std::string>();
347 if (
node.componentType ==
"AIBehavior_data")
349 if (
node.properties.find(
"behaviorTreePath") ==
node.properties.end()
350 ||
node.properties[
"behaviorTreePath"].empty())
352 node.properties[
"behaviorTreePath"] =
btRef;
353 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Fallback: Set behaviorTreePath from root behaviorTreeRef\n";
373 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] Auto-arranging nodes in grid layout\n";
380 catch (
const std::exception&
e)
382 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::LoadFromFile] EXCEPTION: " <<
e.what() <<
"\n";
391 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::SaveToFile] Starting save to: " << filePath <<
"\n";
394 json data = json::object();
395 data[
"blueprintType"] =
"EntityPrefab";
396 data[
"schemaVersion"] = 4;
429 for (
auto it =
node.properties.begin();
it !=
node.properties.end(); ++
it)
460 if (
node.componentType ==
"AIBehavior_data")
462 auto it =
node.properties.find(
"behaviorTreePath");
463 if (
it !=
node.properties.end() && !
it->second.empty())
474 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::SaveToFile] SUCCESS: Saved " <<
m_nodes.size()
475 <<
" nodes and " <<
m_connections.size() <<
" connections\n";
480 catch (
const std::exception&
e)
482 SYSTEM_LOG <<
"[EntityPrefabGraphDocument::SaveToFile] EXCEPTION: " <<
e.what() <<
"\n";
513 SYSTEM_LOG <<
"[EntityPrefabGraphDocument] WARNING: Could not open schemas file\n";
523 SYSTEM_LOG <<
"[EntityPrefabGraphDocument] WARNING: Schemas file missing 'schemas' array\n";
533 std::string componentType =
schemaJson[
"componentType"].get<std::string>();
534 std::map<std::string, std::string>
params;
546 std::string defaultValue;
549 defaultValue =
paramJson[
"defaultValue"].get<std::string>();
553 defaultValue =
paramJson[
"defaultValue"].get<
bool>() ?
"true" :
"false";
566 defaultValue =
paramJson[
"defaultValue"].dump();
574 SYSTEM_LOG <<
"[EntityPrefabGraphDocument] Loaded " <<
params.size() <<
" parameters for " << componentType <<
"\n";
579 catch (
const std::exception&
e)
581 SYSTEM_LOG <<
"[EntityPrefabGraphDocument] ERROR loading schemas: " <<
e.what() <<
"\n";
ComponentTypeID GetComponentTypeID_Static()
std::vector< LayoutNode > CalculateLayout()
const std::vector< NodeId > & GetSelectedNodes() const
void InitializeNodeProperties(ComponentNode &node)
void LoadParameterSchemas(const std::string &schemasFilePath)
std::vector< NodeId > m_selectedNodes
std::vector< std::pair< NodeId, NodeId > > m_connections
void SetDirty(bool dirty)
void SetCanvasOffset(const Vector &offset)
bool SaveToFile(const std::string &filePath)
size_t GetNodeCount() const
bool ValidateConnection(NodeId sourceId, NodeId targetId) const
std::string GetDocumentName() const
std::map< std::string, std::map< std::string, std::string > > m_parameterSchemas
bool HasConnection(NodeId sourceId, NodeId targetId) const
EntityPrefabGraphDocument()
void SetDocumentName(const std::string &name)
~EntityPrefabGraphDocument()
NodeId GetSelectedNode() const
bool LoadFromFile(const std::string &filePath)
bool ConnectNodes(NodeId sourceId, NodeId targetId)
NodeId CreateComponentNode(const std::string &componentType)
void RemoveNode(NodeId nodeId)
void SetCanvasZoom(float zoom)
ComponentNode * GetNode(NodeId nodeId)
std::string m_documentName
void DeselectNode(NodeId nodeId)
const std::vector< ComponentNode > & GetAllNodes() const
bool HasNode(NodeId nodeId) const
bool DisconnectNodes(NodeId sourceId, NodeId targetId)
static EntityPrefabGraphDocument FromJson(const json &data)
const std::vector< std::pair< NodeId, NodeId > > & GetConnections() const
void SelectNode(NodeId nodeId)
std::vector< ComponentNode > m_nodes
Vector GetCanvasOffset() const
void ArrangeNodesInGrid(int gridWidth=4, float spacing=200.0f)
float GetCanvasZoom() const
static void SaveJsonToFile(const std::string &filePath, const json &data)
static json LoadJsonFromFile(const std::string &filePath)
< Provides AssetID and INVALID_ASSET_ID
@ Vector
3-component vector (Vector from vector.h)
const NodeId InvalidNodeId