20#include "../system/system_utils.h"
21#include "../system/system_consts.h"
22#include "../NodeGraphCore/GlobalTemplateBlackboard.h"
24#include "../third_party/imgui/imgui.h"
25#include "../third_party/imnodes/imnodes.h"
26#include "../json_helper.h"
27#include "../TaskSystem/TaskGraphLoader.h"
44 const std::string& path)
74 SYSTEM_LOG <<
"[VSEditor] LoadTemplate: initialized Parameters[subgraph_path] from SubGraphPath = '"
89 SYSTEM_LOG <<
"[VSEditor] LoadTemplate: synced SubGraphPath from Parameters[subgraph_path] = '"
98 SYSTEM_LOG <<
"[VSEditor] LoadTemplate: synced Parameters[subgraph_path] from SubGraphPath = '"
119 <<
"' has no embedded presets - starting with empty bank\n";
131 SYSTEM_LOG <<
"[VSEditor] LoadTemplate: initialized EntityBlackboard with "
140 SYSTEM_LOG <<
"[VSEditor] LoadTemplate: restored global variable overrides from graph\n";
167 SYSTEM_LOG <<
"[VisualScriptEditorPanel] Save() called. m_currentPath='"
172 SYSTEM_LOG <<
"[VisualScriptEditorPanel] Save() aborted: m_currentPath is empty\n";
236 SYSTEM_LOG <<
"[VisualScriptEditorPanel] Save() "
243 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SaveAs() called. path='" << path <<
"'\n";
287 SYSTEM_LOG <<
"[VisualScriptEditorPanel::SaveAs] Synced SubGraphPath from Parameters[subgraph_path] = '"
296 pathIt->second.LiteralValue.to_string().empty())))
302 SYSTEM_LOG <<
"[VisualScriptEditorPanel::SaveAs] Created Parameters[subgraph_path] = '"
318 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SaveAs() succeeded: '" << path <<
"'\n";
322 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SaveAs() FAILED: '" << path <<
"'\n";
354 ParameterBinding
bx,
by;
356 bx.LiteralValue = TaskValue(
pos.x);
358 by.LiteralValue = TaskValue(
pos.y);
389 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SyncPresetsFromRegistryToTemplate: synced "
395 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: writing to '" << path <<
"'\n";
400 root[
"schema_version"] = 4;
402 root[
"graphType"] =
"VisualScript";
415 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: skipping invalid blackboard entry"
416 <<
" (key='" <<
entry.Key <<
"', type=None)\n";
423 e[
"isGlobal"] =
entry.IsGlobal;
433 ?
entry.Default.AsBool() :
false;
438 ?
entry.Default.AsInt() : 0;
443 ?
entry.Default.AsFloat() : 0.0f;
446 e[
"type"] =
"String";
448 ?
entry.Default.AsString() : std::string(
"");
451 e[
"type"] =
"EntityID";
452 e[
"value"] = std::to_string(
454 ?
entry.Default.AsEntityID() : 0);
462 ?
entry.Default.AsVector()
468 e[
"type"] =
"Vector";
474 e[
"value"] =
nullptr;
482 <<
" invalid blackboard entries skipped (BUG-001)\n";
492 n[
"id"] = def.NodeID;
493 n[
"label"] = def.NodeName;
497 n[
"taskType"] = def.AtomicTaskID;
499 n[
"delaySeconds"] = def.DelaySeconds;
500 if (!def.BBKey.empty())
501 n[
"bbKey"] = def.BBKey;
502 if (!def.SubGraphPath.empty())
503 n[
"subGraphPath"] = def.SubGraphPath;
504 if (!def.ConditionID.empty())
505 n[
"conditionKey"] = def.ConditionID;
506 if (!def.MathOperator.empty())
507 n[
"mathOp"] = def.MathOperator;
510 if (!def.Parameters.empty())
513 for (
const auto&
paramPair : def.Parameters)
524 <<
"': Type=" <<
static_cast<int>(
binding.Type)
525 <<
" Value='" <<
binding.LiteralValue.to_string() <<
"'\n";
533 if (!
binding.LiteralValue.IsNone())
535 switch (
binding.LiteralValue.GetType())
551 const ::Vector
v =
binding.LiteralValue.AsVector();
611 if (!def.switchVariable.empty())
612 n[
"switchVariable"] = def.switchVariable;
614 if (!def.switchCases.empty())
617 for (
size_t c = 0;
c < def.switchCases.size(); ++
c)
619 const SwitchCaseDefinition&
sc = def.switchCases[
c];
623 if (!
sc.customLabel.empty())
635 n[
"mathOpRef"] = def.mathOpRef.ToJson();
636 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: serialized mathOpRef for MathOp node "
637 << def.NodeID <<
"\n";
642 !def.conditions.empty())
645 for (
size_t ci = 0;
ci < def.conditions.size(); ++
ci)
651 cj[
"leftMode"] =
cond.leftMode;
652 if (!
cond.leftPin.empty())
653 cj[
"leftPin"] =
cond.leftPin;
654 if (!
cond.leftVariable.empty())
655 cj[
"leftVariable"] =
cond.leftVariable;
656 if (
cond.leftMode ==
"Const" && !
cond.leftConstValue.IsNone())
658 const TaskValue&
lv =
cond.leftConstValue;
659 switch (
lv.GetType()) {
669 cj[
"operator"] =
cond.operatorStr;
672 cj[
"rightMode"] =
cond.rightMode;
673 if (!
cond.rightPin.empty())
674 cj[
"rightPin"] =
cond.rightPin;
675 if (!
cond.rightVariable.empty())
676 cj[
"rightVariable"] =
cond.rightVariable;
677 if (
cond.rightMode ==
"Const" && !
cond.rightConstValue.IsNone())
679 const TaskValue&
rv =
cond.rightConstValue;
680 switch (
rv.GetType()) {
702 !def.conditionOperandRefs.empty())
706 for (
size_t i = 0;
i < def.conditionOperandRefs.size(); ++
i)
708 const ConditionRef&
ref = def.conditionOperandRefs[
i];
710 refObj[
"conditionIndex"] =
static_cast<int>(
i);
715 switch (
ref.leftOperand.mode)
718 lj[
"mode"] =
"Variable";
719 lj[
"variableName"] =
ref.leftOperand.variableName;
722 lj[
"mode"] =
"Const";
723 lj[
"constValue"] =
ref.leftOperand.constValue;
727 lj[
"dynamicPinID"] =
ref.leftOperand.dynamicPinID;
730 lj[
"mode"] =
"Const";
741 switch (
ref.rightOperand.mode)
744 rj[
"mode"] =
"Variable";
745 rj[
"variableName"] =
ref.rightOperand.variableName;
748 rj[
"mode"] =
"Const";
749 rj[
"constValue"] =
ref.rightOperand.constValue;
753 rj[
"dynamicPinID"] =
ref.rightOperand.dynamicPinID;
756 rj[
"mode"] =
"Const";
770 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: Phase 24: serialized "
771 << def.conditionOperandRefs.size() <<
" conditionRefs for node "
772 << def.NodeID <<
"\n";
778 !def.conditionRefs.empty())
781 for (
const auto&
ncref : def.conditionRefs)
788 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: Phase 24: serialized "
789 << def.conditionRefs.size() <<
" nodeConditionRefs for node "
790 << def.NodeID <<
"\n";
795 !def.DynamicExecOutputPins.empty())
798 for (
size_t p = 0;
p < def.DynamicExecOutputPins.size(); ++
p)
799 dynPins.push_back(def.DynamicExecOutputPins[
p]);
807 if (!def.InputParams.empty())
810 for (
const auto&
paramPair : def.InputParams)
821 if (!
binding.LiteralValue.IsNone())
823 switch (
binding.LiteralValue.GetType())
839 const ::Vector
v =
binding.LiteralValue.AsVector();
897 if (!def.OutputParams.empty())
900 for (
const auto&
paramPair : def.OutputParams)
931 c[
"fromNode"] =
conn.SourceNodeID;
932 c[
"fromPin"] =
conn.SourcePinName;
933 c[
"toNode"] =
conn.TargetNodeID;
934 c[
"toPin"] =
conn.TargetPinName;
945 c[
"fromNode"] =
conn.SourceNodeID;
946 c[
"fromPin"] =
conn.SourcePinName;
947 c[
"toNode"] =
conn.TargetNodeID;
948 c[
"toPin"] =
conn.TargetPinName;
958 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: Phase 24 - serialized "
959 <<
"global variable values\n";
975 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: Phase 24 - serialized "
980 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite: opening '"
981 << path <<
"' for writing\n";
982 std::ofstream
ofs(path);
985 std::cerr <<
"[VisualScriptEditorPanel] Cannot open file for write: " << path << std::endl;
986 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite FAILED: cannot open '"
993 SYSTEM_LOG <<
"[VisualScriptEditorPanel] SerializeAndWrite succeeded: '" << path <<
"'\n";
Runtime debug controller for ATS Visual Scripting (Phase 5).
ComponentTypeID GetComponentTypeID_Static()
ImNodes-based graph editor for ATS Visual Script graphs (Phase 5).
void LoadFromPresetList(const std::vector< ConditionPreset > &presets)
Loads presets from a vector of ConditionPreset objects (clears existing data first).
void Clear()
Clears all presets and resets error state.
std::vector< std::string > GetAllPresetIDs() const
Returns all preset UUIDs in display order.
ConditionPreset * GetPreset(const std::string &id)
Returns a mutable pointer to the preset, or nullptr if not found.
static void Reload()
Force reload of the registry from file (useful for hot reload)
std::vector< TaskNodeDefinition > Nodes
All graph nodes.
std::vector< ExecPinConnection > ExecConnections
Explicit exec connections (ATS VS only)
std::string Name
Friendly name of this template (e.g. "PatrolBehaviour")
std::vector< BlackboardEntry > Blackboard
Local blackboard declared in this graph.
void BuildLookupCache()
Rebuilds the internal ID-to-node lookup map from the Nodes vector.
json GlobalVariableValues
Stores JSON representation of global variable values for this specific graph instance.
std::vector< DataPinConnection > DataConnections
Explicit data connections (ATS VS only)
std::vector< ConditionPreset > Presets
Presets are now stored in the graph JSON, not in external files.
bool Save()
Saves the current canvas state to JSON v4 at the loaded path.
TaskGraphTemplate m_template
The template currently being edited.
void CommitPendingBlackboardEdits()
Commits any pending key-name edits stored in m_pendingBlackboardEdits.
std::unique_ptr< EntityBlackboard > m_entityBlackboard
Per-entity blackboard instance (combines local + global variables) Created in Initialize() and manage...
std::unique_ptr< NodeConditionsPanel > m_conditionsPanel
Properties-panel sub-widget for the selected Branch node.
void SyncCanvasFromTemplate()
Builds the editor canvas from the in-memory TaskGraphTemplate.
void SyncTemplateFromCanvas()
Builds the in-memory TaskGraphTemplate from the editor nodes/links.
void AfterSave()
Restores the ImNodes canvas panning saved by ResetViewportBeforeSave().
void ValidateAndCleanBlackboardEntries()
Removes blackboard entries with empty keys or VariableType::None.
void SyncPresetsFromRegistryToTemplate()
Syncs ALL presets from the registry to the template.
void ResetViewportBeforeSave()
Resets the ImNodes canvas panning to (0,0) before saving node positions.
std::unordered_set< int > m_positionedNodes
Nodes for which ImNodes has been given a position.
bool SaveAs(const std::string &path)
Saves the current canvas state to a new JSON v4 file.
void SyncNodePositionsFromImNodes()
Pulls the current node positions from ImNodes into m_editorNodes.
bool SerializeAndWrite(const std::string &path)
Serializes the template to JSON v4 and writes to a file.
std::unordered_map< int, std::pair< float, float > > m_nodeDragStartPositions
Per-node drag-start positions used to record a single MoveNodeCommand per drag gesture instead of one...
std::string m_currentPath
bool m_verificationDone
True once RunVerification() has been called at least once for the current graph.
std::vector< VSEditorNode > m_editorNodes
Editor nodes (mirrors m_template.Nodes + position/selection state)
int m_selectedNodeID
Currently selected node (for properties panel)
ConditionPresetRegistry m_presetRegistry
Global registry of ConditionPreset objects.
void LoadTemplate(const TaskGraphTemplate *tmpl, const std::string &path)
Loads a VS graph template into the editor canvas.
@ Condition
Boolean checks (HasTarget, InRange, etc.)
< Provides AssetID and INVALID_ASSET_ID
const char * GetNodeTypeLabel(TaskNodeType type)
Returns a human-readable label for a TaskNodeType.
@ Int
32-bit signed integer
@ Float
Single-precision float.
@ Vector
3-component vector (Vector from vector.h)
@ None
Uninitialized / empty value.
@ EntityID
Entity identifier (uint64_t)
@ MathOperator
Math operator symbol (+, -, *, /, %) (from OperatorRegistry)
@ ConditionID
ID of a condition type (from ConditionRegistry)
@ AtomicTaskID
ID of an atomic task (from AtomicTaskUIRegistry)
@ SubGraphPath
File path to a sub-graph .ats file.
@ LocalVariable
Value is read from the local blackboard at runtime.
@ Literal
Value is embedded directly in the template.
@ ComparisonOp
Comparison operator (==, !=, <, <=, >, >=) (from OperatorRegistry)
@ AtomicTask
Leaf node that executes a single atomic task.
@ While
Conditional loop (Loop / Completed exec outputs)
@ SubGraph
Sub-graph call (SubTask)
@ Delay
Timer (Completed exec output after N seconds)
@ MathOp
Data node – arithmetic operation (+, -, *, /)
@ Switch
Multi-branch on value (N exec outputs)
@ Branch
If/Else conditional (Then / Else exec outputs)
@ VSSequence
Execute N outputs in order ("VS" prefix avoids collision with BT Sequence=1)
static std::string VariableTypeToString(VariableType type)
Converts a VariableType to its canonical string representation.
@ Variable
References a blackboard variable by name.
@ Const
Literal constant value.
@ Pin
External data-input pin on the owning node.