231 lines
5.9 KiB
C++
231 lines
5.9 KiB
C++
#include "FLESHGraph/FLESHGraph.h"
|
|
#include "FLESHGraph/FLESHGraphNode.h"
|
|
#include "Logging/LogMacros.h"
|
|
|
|
// Define log category
|
|
DEFINE_LOG_CATEGORY_STATIC(LogFLESHGraph, Log, All);
|
|
|
|
UFLESHGraph::UFLESHGraph()
|
|
{
|
|
// Initialize default values
|
|
RootNode = nullptr;
|
|
}
|
|
|
|
void UFLESHGraph::Initialize()
|
|
{
|
|
// Clear graph
|
|
ClearGraph();
|
|
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH graph initialized"));
|
|
}
|
|
|
|
UFLESHGraphNode* UFLESHGraph::AddNode(TSubclassOf<UFLESHGraphNode> NodeClass, const FVector2D& Position)
|
|
{
|
|
// Check if node class is valid
|
|
if (!NodeClass)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Invalid node class"));
|
|
return nullptr;
|
|
}
|
|
|
|
// Create new node
|
|
UFLESHGraphNode* NewNode = NewObject<UFLESHGraphNode>(this, NodeClass);
|
|
if (!NewNode)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Failed to create node"));
|
|
return nullptr;
|
|
}
|
|
|
|
// Set node position
|
|
NewNode->SetNodePosition(Position);
|
|
|
|
// Add to node list
|
|
Nodes.Add(NewNode);
|
|
|
|
// If it's the first node, set as root node
|
|
if (Nodes.Num() == 1)
|
|
{
|
|
RootNode = NewNode;
|
|
}
|
|
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Added new node: %s"), *NewNode->GetNodeTitle());
|
|
|
|
return NewNode;
|
|
}
|
|
|
|
bool UFLESHGraph::RemoveNode(UFLESHGraphNode* Node)
|
|
{
|
|
// Check if node is valid
|
|
if (!Node)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Trying to remove invalid node"));
|
|
return false;
|
|
}
|
|
|
|
// Disconnect from other nodes
|
|
TArray<UFLESHGraphNode*> InputNodes = Node->GetInputNodes();
|
|
TArray<UFLESHGraphNode*> OutputNodes = Node->GetOutputNodes();
|
|
|
|
for (UFLESHGraphNode* InputNode : InputNodes)
|
|
{
|
|
DisconnectNodes(InputNode, Node);
|
|
}
|
|
|
|
for (UFLESHGraphNode* OutputNode : OutputNodes)
|
|
{
|
|
DisconnectNodes(Node, OutputNode);
|
|
}
|
|
|
|
// If it's the root node, reset root node
|
|
if (Node == RootNode)
|
|
{
|
|
RootNode = nullptr;
|
|
|
|
// If there are other nodes, choose the first one as the new root node
|
|
if (Nodes.Num() > 1)
|
|
{
|
|
for (UFLESHGraphNode* OtherNode : Nodes)
|
|
{
|
|
if (OtherNode != Node)
|
|
{
|
|
RootNode = OtherNode;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove from node list
|
|
bool bRemoved = Nodes.Remove(Node) > 0;
|
|
|
|
if (bRemoved)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Removed node: %s"), *Node->GetNodeTitle());
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Node is not in graph: %s"), *Node->GetNodeTitle());
|
|
}
|
|
|
|
return bRemoved;
|
|
}
|
|
|
|
bool UFLESHGraph::ConnectNodes(UFLESHGraphNode* SourceNode, UFLESHGraphNode* TargetNode)
|
|
{
|
|
// Check if nodes are valid
|
|
if (!SourceNode || !TargetNode)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Trying to connect invalid nodes"));
|
|
return false;
|
|
}
|
|
|
|
// Add connection
|
|
bool bSourceAdded = SourceNode->AddOutputNode(TargetNode);
|
|
bool bTargetAdded = TargetNode->AddInputNode(SourceNode);
|
|
|
|
if (bSourceAdded && bTargetAdded)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Connected nodes: %s -> %s"),
|
|
*SourceNode->GetNodeTitle(), *TargetNode->GetNodeTitle());
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// If adding failed, rollback changes
|
|
if (bSourceAdded)
|
|
{
|
|
SourceNode->RemoveOutputNode(TargetNode);
|
|
}
|
|
|
|
if (bTargetAdded)
|
|
{
|
|
TargetNode->RemoveInputNode(SourceNode);
|
|
}
|
|
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Connecting nodes failed: %s -> %s"),
|
|
*SourceNode->GetNodeTitle(), *TargetNode->GetNodeTitle());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool UFLESHGraph::DisconnectNodes(UFLESHGraphNode* SourceNode, UFLESHGraphNode* TargetNode)
|
|
{
|
|
// Check if nodes are valid
|
|
if (!SourceNode || !TargetNode)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Trying to disconnect invalid nodes"));
|
|
return false;
|
|
}
|
|
|
|
// Remove connection
|
|
bool bSourceRemoved = SourceNode->RemoveOutputNode(TargetNode);
|
|
bool bTargetRemoved = TargetNode->RemoveInputNode(SourceNode);
|
|
|
|
if (bSourceRemoved && bTargetRemoved)
|
|
{
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Disconnected nodes: %s -> %s"),
|
|
*SourceNode->GetNodeTitle(), *TargetNode->GetNodeTitle());
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Disconnecting nodes failed: %s -> %s"),
|
|
*SourceNode->GetNodeTitle(), *TargetNode->GetNodeTitle());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
TArray<UFLESHGraphNode*> UFLESHGraph::GetAllNodes() const
|
|
{
|
|
return Nodes;
|
|
}
|
|
|
|
UFLESHGraphNode* UFLESHGraph::GetRootNode() const
|
|
{
|
|
return RootNode;
|
|
}
|
|
|
|
void UFLESHGraph::SetRootNode(UFLESHGraphNode* InRootNode)
|
|
{
|
|
// Check if node is in graph
|
|
if (InRootNode && Nodes.Contains(InRootNode))
|
|
{
|
|
RootNode = InRootNode;
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Set new root node: %s"), *RootNode->GetNodeTitle());
|
|
}
|
|
else if (!InRootNode)
|
|
{
|
|
RootNode = nullptr;
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Clear root node"));
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogFLESHGraph, Warning, TEXT("FLESH: Trying to set node not in graph as root node"));
|
|
}
|
|
}
|
|
|
|
void UFLESHGraph::ClearGraph()
|
|
{
|
|
// Clear node list
|
|
Nodes.Empty();
|
|
|
|
// Clear root node
|
|
RootNode = nullptr;
|
|
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Cleared graph"));
|
|
}
|
|
|
|
bool UFLESHGraph::SaveGraph()
|
|
{
|
|
// TODO: implement graph saving feature
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Graph saving feature not implemented"));
|
|
return false;
|
|
}
|
|
|
|
bool UFLESHGraph::LoadGraph()
|
|
{
|
|
// TODO: implement graph loading feature
|
|
UE_LOG(LogFLESHGraph, Log, TEXT("FLESH: Graph loading feature not implemented"));
|
|
return false;
|
|
}
|