192 lines
5.7 KiB
C++
192 lines
5.7 KiB
C++
#pragma once
|
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
|
#include <imgui.h>
|
|
#include <imgui_internal.h> // For ImRect
|
|
#include <imgui_node_editor.h>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include "utilities/uuid_generator.h"
|
|
|
|
namespace ed = ax::NodeEditor;
|
|
|
|
// Return code constants
|
|
enum {
|
|
E_OK = 0 // Success return code
|
|
};
|
|
|
|
// Forward declarations
|
|
class ParameterNode;
|
|
enum class ParameterDisplayMode;
|
|
|
|
// Block display modes
|
|
enum class BlockDisplayMode
|
|
{
|
|
NameOnly, // Just block name (compact)
|
|
NameAndParameters // Block name + parameter labels (default)
|
|
};
|
|
|
|
enum class PinType
|
|
{
|
|
Flow,
|
|
Bool,
|
|
Int,
|
|
Float,
|
|
String,
|
|
Object,
|
|
Function,
|
|
Delegate,
|
|
};
|
|
|
|
enum class PinKind
|
|
{
|
|
Output,
|
|
Input
|
|
};
|
|
|
|
enum class NodeType
|
|
{
|
|
Blueprint,
|
|
Simple,
|
|
Tree,
|
|
Comment,
|
|
Houdini,
|
|
Parameter, // Standalone parameter value node
|
|
Group // Group block node
|
|
};
|
|
|
|
struct Node;
|
|
|
|
struct Pin
|
|
{
|
|
ed::PinId ID; // Runtime ID (dynamic, for imgui-node-editor)
|
|
Uuid64 UUID; // Persistent ID (stable across sessions)
|
|
::Node* Node;
|
|
std::string Name;
|
|
PinType Type;
|
|
PinKind Kind;
|
|
|
|
// Position tracking (updated during rendering)
|
|
ImVec2 LastPivotPosition; // Where links connect (screen space)
|
|
ImRect LastRenderBounds; // Full pin area for hit testing
|
|
bool HasPositionData; // True after first render
|
|
|
|
Pin(int id, const char* name, PinType type):
|
|
ID(id), UUID(0, 0), Node(nullptr), Name(name), Type(type), Kind(PinKind::Input),
|
|
LastPivotPosition(0, 0), LastRenderBounds(ImVec2(0,0), ImVec2(0,0)), HasPositionData(false)
|
|
{
|
|
}
|
|
|
|
// Get pin position relative to its node (implementation after Node is defined)
|
|
ImVec2 GetRelativePivotPosition() const;
|
|
};
|
|
|
|
struct Node
|
|
{
|
|
ed::NodeId ID; // Runtime ID (dynamic, for imgui-node-editor)
|
|
Uuid64 UUID; // Persistent ID (stable across sessions)
|
|
std::string Name;
|
|
std::vector<Pin> Inputs;
|
|
std::vector<Pin> Outputs;
|
|
ImColor Color;
|
|
NodeType Type;
|
|
ImVec2 Size;
|
|
|
|
std::string State;
|
|
std::string SavedState;
|
|
|
|
// Block metadata (only used when (Type == NodeType::Blueprint || Type == NodeType::Group) && IsBlockBased())
|
|
std::string BlockType; // e.g. "Math.Add" or "Group" - empty for hardcoded nodes
|
|
bool IsBlockBased() const { return !BlockType.empty(); }
|
|
::BlockDisplayMode BlockDisplay; // Display mode for blocks
|
|
class Block* BlockInstance; // Block class instance (owns rendering logic) - ONLY set for block-based nodes
|
|
|
|
// Safe getter for BlockInstance - returns nullptr for non-block nodes
|
|
// Full validation (ID match, node type) should be done at call site after including block.h
|
|
class Block* GetBlockInstance() const {
|
|
// Only return BlockInstance for actual block-based nodes
|
|
if (Type == NodeType::Parameter || !IsBlockBased())
|
|
return nullptr;
|
|
return BlockInstance;
|
|
}
|
|
|
|
// Parameter node metadata (only used when Type == NodeType::Parameter)
|
|
PinType ParameterType;
|
|
union {
|
|
bool BoolValue;
|
|
int IntValue;
|
|
float FloatValue;
|
|
};
|
|
std::string StringValue; // For string parameters
|
|
ParameterNode* ParameterInstance; // Parameter class instance (owned by node) - ONLY set for parameter nodes
|
|
|
|
// Safe getter for ParameterInstance - returns nullptr for non-parameter nodes
|
|
ParameterNode* GetParameterInstance() const {
|
|
// Only return ParameterInstance for actual parameter nodes
|
|
if (Type != NodeType::Parameter)
|
|
return nullptr;
|
|
return ParameterInstance;
|
|
}
|
|
|
|
// Unconnected parameter values (for block input parameters)
|
|
// Maps pin ID -> value (stored as string, parsed based on pin type)
|
|
std::map<int, std::string> UnconnectedParamValues;
|
|
|
|
Node(int id, const char* name, ImColor color = ImColor(255, 255, 255)):
|
|
ID(id), UUID(0, 0), Name(name), Color(color), Type(NodeType::Blueprint), Size(0, 0), BlockType(""),
|
|
BlockDisplay(::BlockDisplayMode::NameAndParameters), BlockInstance(nullptr),
|
|
ParameterType(PinType::Float), FloatValue(0.0f), StringValue(""), ParameterInstance(nullptr)
|
|
{
|
|
}
|
|
};
|
|
|
|
struct Link
|
|
{
|
|
ed::LinkId ID; // Runtime ID (dynamic, for imgui-node-editor)
|
|
Uuid64 UUID; // Persistent ID (stable across sessions)
|
|
|
|
ed::PinId StartPinID;
|
|
ed::PinId EndPinID;
|
|
|
|
ImColor Color;
|
|
bool IsParameterLink; // True if parameter → block input (for styling)
|
|
bool UserManipulatedWaypoints; // True if user manually edited waypoints (preserve path, disable auto-adjust)
|
|
float Delay; // Custom delay unit (displayed on hover, editable via double-click)
|
|
|
|
Link(ed::LinkId id, ed::PinId startPinId, ed::PinId endPinId):
|
|
ID(id), UUID(0, 0), StartPinID(startPinId), EndPinID(endPinId), Color(255, 255, 255),
|
|
IsParameterLink(false), UserManipulatedWaypoints(false), Delay(0.0f)
|
|
{
|
|
}
|
|
};
|
|
|
|
struct NodeIdLess
|
|
{
|
|
bool operator()(const ed::NodeId& lhs, const ed::NodeId& rhs) const
|
|
{
|
|
return lhs.AsPointer() < rhs.AsPointer();
|
|
}
|
|
};
|
|
|
|
struct LinkIdLess
|
|
{
|
|
bool operator()(const ed::LinkId& lhs, const ed::LinkId& rhs) const
|
|
{
|
|
return lhs.AsPointer() < rhs.AsPointer();
|
|
}
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Pin method implementations (after Node is fully defined)
|
|
//------------------------------------------------------------------------------
|
|
|
|
inline ImVec2 Pin::GetRelativePivotPosition() const
|
|
{
|
|
if (Node && HasPositionData)
|
|
{
|
|
ImVec2 nodePos = ed::GetNodePosition(Node->ID);
|
|
return LastPivotPosition - nodePos;
|
|
}
|
|
return ImVec2(0, 0);
|
|
}
|