diff --git a/packages/nodegraph/include/nodegraph/NodeGraphSchema.h b/packages/nodegraph/include/nodegraph/NodeGraphSchema.h index 2d85074..6cdb3fd 100644 --- a/packages/nodegraph/include/nodegraph/NodeGraphSchema.h +++ b/packages/nodegraph/include/nodegraph/NodeGraphSchema.h @@ -101,6 +101,8 @@ namespace l::nodegraph { int32_t NewNode(int32_t typeId); bool RemoveNode(int32_t nodeId); NodeGraphBase* GetNode(int32_t nodeId); + void ForEachInputNode(std::function cb); + void ForEachOutputNode(std::function cb); bool HasNodeType(const std::string& typeGroup, int32_t typeId); void ForEachNodeType(std::function&)> cb) const; diff --git a/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h b/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h index a781517..da7a2cf 100644 --- a/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h +++ b/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h @@ -1,6 +1,7 @@ #pragma once #include "logging/LoggingAll.h" +#include "meta/Reflection.h" #include #include @@ -26,8 +27,12 @@ namespace l::nodegraph { /**********************************************************************************/ class NodeGraphBase { public: - NodeGraphBase(OutputType outputType) : mId(CreateUniqueId()), mOutputType(outputType) { - } + NodeGraphBase(NodeType outputType) : + mId(CreateUniqueId()), + mOutputType(outputType), + mOperationTypeHash(l::meta::class_hash()) + {} + virtual ~NodeGraphBase() { LOG(LogInfo) << "Node graph base destroyed"; } @@ -40,6 +45,7 @@ namespace l::nodegraph { this->mLastTickCount = other.mLastTickCount; this->mOutputType = other.mOutputType; this->mProcessUpdateHasRun = other.mProcessUpdateHasRun; + this->mOperationTypeHash = other.mOperationTypeHash; return *this; } NodeGraphBase& operator=(const NodeGraphBase& other) noexcept { @@ -50,6 +56,7 @@ namespace l::nodegraph { this->mLastTickCount = other.mLastTickCount; this->mOutputType = other.mOutputType; this->mProcessUpdateHasRun = other.mProcessUpdateHasRun; + this->mOperationTypeHash = other.mOperationTypeHash; return *this; } NodeGraphBase(NodeGraphBase&& other) noexcept { @@ -100,7 +107,12 @@ namespace l::nodegraph { virtual bool IsDataEditable(int8_t num); virtual bool IsOutputPolled(int8_t outputChannel); - virtual OutputType GetOutputType(); + virtual NodeType GetOutputType(); + + template + bool IsOfOperation() { + return l::meta::template class_hash == mOperationTypeId; + } protected: virtual void SetNumInputs(int8_t numInputs); @@ -114,9 +126,10 @@ namespace l::nodegraph { std::vector mOutputs; int32_t mId = -1; - OutputType mOutputType; + NodeType mOutputType; std::string mName; + size_t mOperationTypeHash; }; /**********************************************************************************/ @@ -168,9 +181,10 @@ namespace l::nodegraph { template class NodeGraph : public NodeGraphBase { public: - NodeGraph(OutputType outputType = OutputType::Default, Params&&... params) : + NodeGraph(NodeType outputType = NodeType::Default, Params&&... params) : NodeGraphBase(outputType), - mOperation(this, std::forward(params)...) + mOperation(this, std::forward(params)...), + mOperationTypeId = typeid(T) { SetNumInputs(mOperation.GetNumInputs()); SetNumOutputs(mOperation.GetNumOutputs()); diff --git a/packages/nodegraph/include/nodegraph/core/NodeGraphData.h b/packages/nodegraph/include/nodegraph/core/NodeGraphData.h index b78c470..1ad83ec 100644 --- a/packages/nodegraph/include/nodegraph/core/NodeGraphData.h +++ b/packages/nodegraph/include/nodegraph/core/NodeGraphData.h @@ -30,10 +30,11 @@ namespace l::nodegraph { INPUT_CUSTOM, }; - enum class OutputType { + enum class NodeType { Default, // node will be processed if it is connected to the groups output by some route ExternalOutput, // node does not have meaningful output for other nodes but should still be processed (ex speaker output only has input) ExternalVisualOutput, // node has visual output that requires special handling, for example the graph plot node + ExternalInput }; std::pair GetInputBounds(InputBound bound); diff --git a/packages/nodegraph/include/nodegraph/core/NodeGraphGroup.h b/packages/nodegraph/include/nodegraph/core/NodeGraphGroup.h index 38fdd53..2ab9ea8 100644 --- a/packages/nodegraph/include/nodegraph/core/NodeGraphGroup.h +++ b/packages/nodegraph/include/nodegraph/core/NodeGraphGroup.h @@ -74,15 +74,22 @@ namespace l::nodegraph { bool RemoveNode(int32_t id); template, int> = 0> - l::nodegraph::NodeGraphBase* NewNode(OutputType nodeType, Params&&... params) { + l::nodegraph::NodeGraphBase* NewNode(NodeType nodeType, Params&&... params) { mNodes.emplace_back(std::make_unique>(nodeType, std::forward(params)...)); auto nodePtr = mNodes.back().get(); - if (nodeType == OutputType::ExternalOutput || nodeType == OutputType::ExternalVisualOutput) { + if (nodeType == NodeType::ExternalOutput || nodeType == NodeType::ExternalVisualOutput) { mOutputNodes.push_back(nodePtr); + } + else if (nodeType == NodeType::ExternalInput) { + mInputNodes.push_back(nodePtr); } + return nodePtr; } + void ForEachInputNode(std::function cb); + void ForEachOutputNode(std::function cb); + void ClearProcessFlags(); void ProcessSubGraph(int32_t numSamples); void Tick(int32_t tickCount, float elapsed); @@ -92,6 +99,7 @@ namespace l::nodegraph { std::vector> mNodes; std::vector mOutputNodes; + std::vector mInputNodes; int32_t mLastTickCount = 0; }; diff --git a/packages/nodegraph/source/common/NodeGraphSchema.cpp b/packages/nodegraph/source/common/NodeGraphSchema.cpp index 409cdc1..40ae9fc 100644 --- a/packages/nodegraph/source/common/NodeGraphSchema.cpp +++ b/packages/nodegraph/source/common/NodeGraphSchema.cpp @@ -26,160 +26,160 @@ namespace l::nodegraph { l::nodegraph::NodeGraphBase* node = nullptr; switch (typeId) { case 0: - node = mMainNodeGraph.NewNode(OutputType::Default, 0); + node = mMainNodeGraph.NewNode(NodeType::Default, 0); break; case 1: - node = mMainNodeGraph.NewNode(OutputType::Default, 1); + node = mMainNodeGraph.NewNode(NodeType::Default, 1); break; case 2: - node = mMainNodeGraph.NewNode(OutputType::Default, 2); + node = mMainNodeGraph.NewNode(NodeType::Default, 2); break; case 3: - node = mMainNodeGraph.NewNode(OutputType::Default, 3); + node = mMainNodeGraph.NewNode(NodeType::Default, 3); break; case 4: - node = mMainNodeGraph.NewNode(OutputType::ExternalOutput, mAudioOutput != nullptr ? mAudioOutput->GetSampleRate() : 44100, 60); + node = mMainNodeGraph.NewNode(NodeType::ExternalOutput, mAudioOutput != nullptr ? mAudioOutput->GetSampleRate() : 44100, 60); break; case 50: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 51: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 52: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 53: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 54: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 55: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 56: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 57: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 100: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 101: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 102: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 150: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 151: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 152: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 200: - node = mMainNodeGraph.NewNode(OutputType::ExternalOutput); + node = mMainNodeGraph.NewNode(NodeType::ExternalOutput); break; case 201: - node = mMainNodeGraph.NewNode(OutputType::ExternalOutput, mAudioOutput); + node = mMainNodeGraph.NewNode(NodeType::ExternalOutput, mAudioOutput); break; case 202: - node = mMainNodeGraph.NewNode(OutputType::ExternalVisualOutput, 100); + node = mMainNodeGraph.NewNode(NodeType::ExternalVisualOutput, 100); break; case 203: - node = mMainNodeGraph.NewNode(OutputType::ExternalOutput); + node = mMainNodeGraph.NewNode(NodeType::ExternalOutput); break; case 204: - node = mMainNodeGraph.NewNode(OutputType::ExternalOutput); + node = mMainNodeGraph.NewNode(NodeType::ExternalOutput); break; case 251: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 252: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 254: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 255: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 256: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 257: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 300: - node = mMainNodeGraph.NewNode(OutputType::Default, mKeyState); + node = mMainNodeGraph.NewNode(NodeType::Default, mKeyState); break; case 301: - node = mMainNodeGraph.NewNode(OutputType::Default, mMidiManager); + node = mMainNodeGraph.NewNode(NodeType::Default, mMidiManager); break; case 302: - node = mMainNodeGraph.NewNode(OutputType::Default, mMidiManager); + node = mMainNodeGraph.NewNode(NodeType::Default, mMidiManager); break; case 303: - node = mMainNodeGraph.NewNode(OutputType::Default, mMidiManager, 0); + node = mMainNodeGraph.NewNode(NodeType::Default, mMidiManager, 0); break; case 304: - node = mMainNodeGraph.NewNode(OutputType::Default, mMidiManager, 1); + node = mMainNodeGraph.NewNode(NodeType::Default, mMidiManager, 1); break; case 305: - node = mMainNodeGraph.NewNode(OutputType::Default, mMidiManager, 2); + node = mMainNodeGraph.NewNode(NodeType::Default, mMidiManager, 2); break; case 306: - node = mMainNodeGraph.NewNode(OutputType::Default, mMidiManager, 3); + node = mMainNodeGraph.NewNode(NodeType::Default, mMidiManager, 3); break; case 307: - node = mMainNodeGraph.NewNode(OutputType::Default, mMidiManager, 4); + node = mMainNodeGraph.NewNode(NodeType::Default, mMidiManager, 4); break; case 350: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 351: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 352: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 353: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 354: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 355: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 356: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 400: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 401: - node = mMainNodeGraph.NewNode(OutputType::Default); + node = mMainNodeGraph.NewNode(NodeType::Default); break; case 450: - node = mMainNodeGraph.NewNode(OutputType::Default, 6); + node = mMainNodeGraph.NewNode(NodeType::Default, 6); break; case 451: - node = mMainNodeGraph.NewNode(OutputType::ExternalOutput, 6); + node = mMainNodeGraph.NewNode(NodeType::ExternalOutput, 6); break; default: @@ -214,6 +214,14 @@ namespace l::nodegraph { return false; } + void NodeGraphSchema::ForEachInputNode(std::function cb) { + mMainNodeGraph.ForEachInputNode(cb); + } + + void NodeGraphSchema::ForEachOutputNode(std::function cb) { + mMainNodeGraph.ForEachOutputNode(cb); + } + void NodeGraphSchema::ForEachNodeType(std::function&)> cb) const { for (auto& it : mRegisteredNodeTypes) { cb(it.first, it.second); diff --git a/packages/nodegraph/source/common/core/NodeGraphBase.cpp b/packages/nodegraph/source/common/core/NodeGraphBase.cpp index b6ba48d..c00a7f1 100644 --- a/packages/nodegraph/source/common/core/NodeGraphBase.cpp +++ b/packages/nodegraph/source/common/core/NodeGraphBase.cpp @@ -264,7 +264,7 @@ namespace l::nodegraph { return mOutputs.at(outputChannel).IsPolled(); } - OutputType NodeGraphBase::GetOutputType() { + NodeType NodeGraphBase::GetOutputType() { return mOutputType; } diff --git a/packages/nodegraph/source/common/core/NodeGraphGroup.cpp b/packages/nodegraph/source/common/core/NodeGraphGroup.cpp index 190be5c..959b868 100644 --- a/packages/nodegraph/source/common/core/NodeGraphGroup.cpp +++ b/packages/nodegraph/source/common/core/NodeGraphGroup.cpp @@ -24,13 +24,13 @@ namespace l::nodegraph { void NodeGraphGroup::SetNumInputs(int8_t numInputs) { if (!mInputNode) { - mInputNode = NewNode(OutputType::Default, numInputs); + mInputNode = NewNode(NodeType::Default, numInputs); } } void NodeGraphGroup::SetNumOutputs(int8_t numOutput) { if (!mOutputNode) { - mOutputNode = NewNode(OutputType::ExternalOutput, numOutput); + mOutputNode = NewNode(NodeType::ExternalOutput, numOutput); } } @@ -121,6 +121,18 @@ namespace l::nodegraph { return count > 0 ? true : false; } + void NodeGraphGroup::ForEachInputNode(std::function cb) { + for (auto& it : mInputNodes) { + cb(it); + } + } + + void NodeGraphGroup::ForEachOutputNode(std::function cb) { + for (auto& it : mOutputNodes) { + cb(it); + } + } + void NodeGraphGroup::ClearProcessFlags() { mOutputNode->ClearProcessFlags(); } diff --git a/packages/nodegraph/tests/common/NodeGraphBatchingTest.cpp b/packages/nodegraph/tests/common/NodeGraphBatchingTest.cpp index f29c9e9..958b501 100644 --- a/packages/nodegraph/tests/common/NodeGraphBatchingTest.cpp +++ b/packages/nodegraph/tests/common/NodeGraphBatchingTest.cpp @@ -12,12 +12,12 @@ TEST(NodeGraphBatching, Simple) { NodeGraphGroup group; group.SetNumOutputs(1); - auto nodeSine = group.NewNode(OutputType::Default); + auto nodeSine = group.NewNode(NodeType::Default); nodeSine->SetInput(1, 4.0f); // sine update rate nodeSine->SetInput(2, 1400.0f); // sine freq nodeSine->SetInput(3, 0.5f); // sine freq - auto nodeLowpass = group.NewNode(OutputType::Default); + auto nodeLowpass = group.NewNode(NodeType::Default); nodeLowpass->SetInput(1, *nodeSine, 0); group.SetOutput(0, *nodeLowpass, 0); diff --git a/packages/nodegraph/tests/common/NodeGraphSchemaTest.cpp b/packages/nodegraph/tests/common/NodeGraphSchemaTest.cpp index 085315e..8fae536 100644 --- a/packages/nodegraph/tests/common/NodeGraphSchemaTest.cpp +++ b/packages/nodegraph/tests/common/NodeGraphSchemaTest.cpp @@ -129,8 +129,8 @@ TEST(NodeGraph, GraphGroups) { group.SetInput(2, &input1); group.SetInput(3, &input2); - auto nodeLowpass1 = group.NewNode(OutputType::Default); - auto nodeLowpass2 = group.NewNode(OutputType::Default); + auto nodeLowpass1 = group.NewNode(NodeType::Default); + auto nodeLowpass2 = group.NewNode(NodeType::Default); // left, right nodeLowpass1->SetInput(1, group, 2); @@ -156,7 +156,7 @@ TEST(NodeGraph, GraphGroups) { group2.SetInput(0, group, 0); group2.SetInput(1, group, 1); - auto copyNode = group2.NewNode(OutputType::Default, 2); + auto copyNode = group2.NewNode(NodeType::Default, 2); copyNode->SetInput(0, group2, 0); copyNode->SetInput(1, group2, 1); diff --git a/packages/rendering/source/common/ui/UICreator.cpp b/packages/rendering/source/common/ui/UICreator.cpp index dc10d7e..63f90b1 100644 --- a/packages/rendering/source/common/ui/UICreator.cpp +++ b/packages/rendering/source/common/ui/UICreator.cpp @@ -88,7 +88,7 @@ namespace l::ui { } } - if (node.GetOutputType() == l::nodegraph::OutputType::ExternalVisualOutput) { + if (node.GetOutputType() == l::nodegraph::NodeType::ExternalVisualOutput) { auto row = CreateContainer(uiManager, l::ui::UIContainer_DrawFlag, l::ui::UIRenderType::Rect, l::ui::UIAlignH::Left, l::ui::UIAlignV::Bottom, l::ui::UILayoutH::Parent, l::ui::UILayoutV::Parent); row->SetPosition(ImVec2(0.0f, 0.0f)); row->GetContainerArea().mMargin = ioSize;