#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 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(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 InputNodes = Node->GetInputNodes(); TArray 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 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; }