From 689364d8ec585b3e17ee7ac2c7b2ede93be59246 Mon Sep 17 00:00:00 2001 From: Daethalus Date: Sat, 18 May 2024 17:01:27 +0100 Subject: [PATCH] GraphEditor - Inputs --- .../Fyrion/Editor/Editor/GraphEditor.cpp | 88 +++++++++++++++---- .../Fyrion/Editor/Editor/GraphEditor.hpp | 47 +++++----- .../Editor/Window/GraphEditorWindow.cpp | 28 +++++- .../Fyrion/Graphics/GraphicsTypeRegister.cpp | 4 + 4 files changed, 125 insertions(+), 42 deletions(-) diff --git a/Editor/Source/Fyrion/Editor/Editor/GraphEditor.cpp b/Editor/Source/Fyrion/Editor/Editor/GraphEditor.cpp index 0faaac7..6f6b5d5 100644 --- a/Editor/Source/Fyrion/Editor/Editor/GraphEditor.cpp +++ b/Editor/Source/Fyrion/Editor/Editor/GraphEditor.cpp @@ -15,6 +15,14 @@ namespace Fyrion { ResourceObject nodeObject = Repository::Read(node); + Array inputValues = nodeObject.GetSubObjectSetAsArray(GraphNodeAsset::InputValues); + HashMap inputCache; + + for (RID input : inputValues) + { + ResourceObject valueObject = Repository::Read(input); + inputCache.Insert(valueObject[GraphNodeValue::Input].Value(), input); + } GraphEditorNode* graphEditorNode = m_nodes.Emplace(node, MakeUnique(GraphEditorNode{ .rid = node, @@ -41,7 +49,7 @@ namespace Fyrion .node = node, .name = param.GetName() }, MakeUnique(GraphEditorNodePin{ - .node = node, + .node = graphEditorNode, .label = FormatName(param.GetName()), .name = param.GetName(), .typeId = param.GetFieldInfo().typeInfo.typeId, @@ -60,12 +68,13 @@ namespace Fyrion .node = node, .name = param.GetName(), }, MakeUnique(GraphEditorNodePin{ - .node = node, + .node = graphEditorNode, .label = FormatName(param.GetName()), .name = param.GetName(), .typeId = param.GetFieldInfo().typeInfo.typeId, .kind = GraphEditorPinKind::Output })).first->second.Get(); + graphEditorNode->outputs.EmplaceBack(pin); } } @@ -87,7 +96,7 @@ namespace Fyrion .node = node, .name = field->GetName(), }, MakeUnique(GraphEditorNodePin{ - .node = node, + .node = graphEditorNode, .label = FormatName(field->GetName()), .name = field->GetName(), .typeId = field->GetFieldInfo().typeInfo.typeId, @@ -100,6 +109,35 @@ namespace Fyrion } else { + graphEditorNode->addOutputPin = MakeUnique(GraphEditorNodePin{ + .node = graphEditorNode, + .kind = GraphEditorPinKind::AddOutputPin + }); + + for (RID inputValue : inputValues) + { + ResourceObject valueObject = Repository::Read(inputValue); + + String name = valueObject[GraphNodeValue::Input].Value(); + RID valueSuboject = valueObject.GetSubObject(GraphNodeValue::Value); + + GraphEditorNodePin* pin = m_pins.Emplace(GraphEditorNodePinLookup{ + .node = node, + .name = name, + }, MakeUnique(GraphEditorNodePin{ + .node = graphEditorNode, + .label = FormatName(name), + .name = name, + // .typeId = Repository::GetResourceTypeHandler(valueSuboject)->GetTypeInfo().typeId, + .value = Repository::ReadData(valueSuboject), + .kind = GraphEditorPinKind::Output, + .publicValue = valueObject[GraphNodeValue::PublicValue].Value() + })).first->second.Get(); + + graphEditorNode->outputs.EmplaceBack(pin); + } + + if (graphEditorNode->label.Empty()) { graphEditorNode->label = "Input"; @@ -118,25 +156,15 @@ namespace Fyrion return; } - GraphEditorLink* editorLink = m_links.Emplace(link, MakeUnique(GraphEditorLink{ + m_links.Emplace(link, MakeUnique(GraphEditorLink{ .rid = link, - .index = m_linksArray.Size(), .inputPin = inputPin, .outputPin = outputPin, .linkType = outputPin->typeId - })).first->second.Get(); - - m_linksArray.EmplaceBack(editorLink); + })); - if (const auto& it = m_nodes.Find(inputPin->node)) - { - it->second->links.Insert(link); - } - - if (const auto& it = m_nodes.Find(outputPin->node)) - { - it->second->links.Insert(link); - } + inputPin->links.Emplace(link); + outputPin->links.Emplace(link); } GraphEditorNodePin* GraphEditor::GetPin(GraphEditorNodePin* left, GraphEditorNodePin* right, GraphEditorPinKind disiredKind) @@ -190,6 +218,23 @@ namespace Fyrion } } + void GraphEditor::AddInputNode(const Vec2& position) + { + RID nodeAsset = Repository::CreateResource(); + + ResourceObject nodeObject = Repository::Write(nodeAsset); + nodeObject[GraphNodeAsset::Position] = position; + nodeObject.Commit(); + + ResourceObject graphAsset = Repository::Write(m_graph); + graphAsset.AddToSubObjectSet(ResourceGraphAsset::Nodes, nodeAsset); + graphAsset.Commit(); + + Repository::SetUUID(nodeAsset, UUID::RandomUUID()); + AddNodeCache(nodeAsset); + m_assetTree.MarkDirty(); + } + void GraphEditor::AddOutput(TypeHandler* outputType, const Vec2& position) { RID nodeAsset = Repository::CreateResource(); @@ -265,6 +310,13 @@ namespace Fyrion void GraphEditor::DeleteLink(RID link) { Repository::DestroyResource(link); + + if (const auto& it = m_links.Find(link)) + { + it->second->inputPin->links.Erase(link); + it->second->outputPin->links.Erase(link); + } + m_links.Erase(link); m_assetTree.MarkDirty(); } @@ -296,7 +348,7 @@ namespace Fyrion void GraphEditor::DeletePin(GraphEditorNodePin* pin) { m_pins.Erase(GraphEditorNodePinLookup{ - .node = pin->node, + .node = pin->node->rid, .name = pin->name, }); } diff --git a/Editor/Source/Fyrion/Editor/Editor/GraphEditor.hpp b/Editor/Source/Fyrion/Editor/Editor/GraphEditor.hpp index fa4913b..13076a4 100644 --- a/Editor/Source/Fyrion/Editor/Editor/GraphEditor.hpp +++ b/Editor/Source/Fyrion/Editor/Editor/GraphEditor.hpp @@ -11,21 +11,27 @@ namespace Fyrion class AssetTree; class TypeHandler; class FunctionHandler; - + struct GraphEditorLink; + struct GraphEditorNode; enum class GraphEditorPinKind { Input, Output, + AddOutputPin, + AddInputPin }; struct GraphEditorNodePin { - RID node; + GraphEditorNode* node; String label; String name; TypeID typeId; + ConstPtr value; GraphEditorPinKind kind; + HashSet links{}; + bool publicValue = false; }; struct GraphEditorNodePinLookup @@ -54,22 +60,22 @@ namespace Fyrion struct GraphEditorNode { - RID rid{}; - TypeHandler* typeHandler{}; - FunctionHandler* functionHandler{}; - Vec2 position{}; - String label{}; - bool initialized{}; - - Array inputs{}; - Array outputs{}; - HashSet links{}; + RID rid{}; + TypeHandler* typeHandler{}; + FunctionHandler* functionHandler{}; + Vec2 position{}; + String label{}; + bool initialized{}; + UniquePtr addInputPin{}; + UniquePtr addOutputPin{}; + + Array inputs{}; + Array outputs{}; }; struct GraphEditorLink { RID rid{}; - u64 index{}; GraphEditorNodePin* inputPin{}; GraphEditorNodePin* outputPin{}; TypeID linkType{}; @@ -77,6 +83,7 @@ namespace Fyrion using GraphNodeMap = HashMap>; using GraphNodePinMap = HashMap>; + using GraphNodeLinkMap = HashMap>; class GraphEditor { @@ -87,12 +94,13 @@ namespace Fyrion FY_NO_COPY_CONSTRUCTOR(GraphEditor) - void OpenGraph(RID rid); - bool IsGraphLoaded() const; - GraphNodeMap& GetNodes() { return m_nodes; } - GraphNodePinMap& GetPins() { return m_pins; } - Span GetLinks() { return m_linksArray; } + void OpenGraph(RID rid); + bool IsGraphLoaded() const; + GraphNodeMap& GetNodes() { return m_nodes; } + GraphNodePinMap& GetPins() { return m_pins; } + GraphNodeLinkMap& GetLinks() { return m_links; } + void AddInputNode(const Vec2& position); void AddOutput(TypeHandler* outputType, const Vec2& position); void AddNode(FunctionHandler* functionHandler, const Vec2& position); bool ValidateLink(GraphEditorNodePin* inputPin, GraphEditorNodePin* outputPin); @@ -113,8 +121,7 @@ namespace Fyrion GraphNodeMap m_nodes; GraphNodePinMap m_pins; - HashMap> m_links; - Array m_linksArray; + GraphNodeLinkMap m_links; void AddNodeCache(RID node); void AddLinkCache(RID link); diff --git a/Editor/Source/Fyrion/Editor/Window/GraphEditorWindow.cpp b/Editor/Source/Fyrion/Editor/Window/GraphEditorWindow.cpp index 7bf2706..3da3d45 100644 --- a/Editor/Source/Fyrion/Editor/Window/GraphEditorWindow.cpp +++ b/Editor/Source/Fyrion/Editor/Window/GraphEditorWindow.cpp @@ -158,7 +158,7 @@ namespace Fyrion for (GraphEditorNodePin* input : node->inputs) { builder.Input(ed::PinId(input)); - DrawPinIcon(input->typeId, false); + DrawPinIcon(input->typeId, !input->links.Empty()); ImGui::Spring(0); ImGui::TextUnformatted(input->label.CStr()); ImGui::Spring(0); @@ -170,9 +170,19 @@ namespace Fyrion builder.Output(ed::PinId(output)); ImGui::TextUnformatted(output->label.CStr()); ImGui::Spring(0); - DrawPinIcon(output->typeId, false); + DrawPinIcon(output->typeId, !output->links.Empty()); builder.EndOutput(); } + + if (node->addOutputPin) + { + builder.Output(ed::PinId(node->addOutputPin.Get())); + ImGui::TextUnformatted("+"); + ImGui::Spring(0); + DrawPinIcon(0, false); + builder.EndOutput(); + } + builder.End(); ImVec2 pos = ed::GetNodePosition(node->rid.id); @@ -182,9 +192,9 @@ namespace Fyrion } } - for (GraphEditorLink* link : m_graphEditor.GetLinks()) + for (const auto& it : m_graphEditor.GetLinks()) { - ed::Link(link->rid.id, ed::PinId(link->inputPin), ed::PinId(link->outputPin), GetTypeColor(link->linkType), 3.f); + ed::Link(it.second->rid.id, ed::PinId(it.second->inputPin), ed::PinId(it.second->outputPin), GetTypeColor(it.second->linkType), 3.f); } if (ed::BeginCreate()) @@ -275,6 +285,16 @@ namespace Fyrion void GraphEditorWindow::OnInitGraphEditor() { + s_menuItemContext.AddMenuItem(MenuItemCreation{ + .itemName = "Graph/Input", + .priority = 10, + .action = [](const MenuItemEventData& eventData) + { + GraphEditorWindow* graphEditorWindow = static_cast(eventData.drawData); + graphEditorWindow->m_graphEditor.AddInputNode(graphEditorWindow->m_clickMousePos); + } + }); + Span outputs = Registry::FindTypesByAttribute(); for (TypeHandler* outputType : outputs) { diff --git a/Engine/Source/Fyrion/Graphics/GraphicsTypeRegister.cpp b/Engine/Source/Fyrion/Graphics/GraphicsTypeRegister.cpp index 193b37f..7736637 100644 --- a/Engine/Source/Fyrion/Graphics/GraphicsTypeRegister.cpp +++ b/Engine/Source/Fyrion/Graphics/GraphicsTypeRegister.cpp @@ -8,5 +8,9 @@ namespace Fyrion Registry::Type(); Registry::Type>(); Registry::Type(); + Registry::Type(); + + + Registry::Type(); } }