Skip to content

Commit

Permalink
Make outputtype define input and output types and change its name. Ad…
Browse files Browse the repository at this point in the history
…d type info for node operations into nodegraphbase. Add getters for input and output nodes to be able to interact with the node graph externally.
  • Loading branch information
linuscu committed Oct 1, 2024
1 parent dea04fb commit b3ae348
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 67 deletions.
2 changes: 2 additions & 0 deletions packages/nodegraph/include/nodegraph/NodeGraphSchema.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<void(NodeGraphBase*)> cb);
void ForEachOutputNode(std::function<void(NodeGraphBase*)> cb);

bool HasNodeType(const std::string& typeGroup, int32_t typeId);
void ForEachNodeType(std::function<void(std::string_view, const std::vector<UINodeDesc>&)> cb) const;
Expand Down
26 changes: 20 additions & 6 deletions packages/nodegraph/include/nodegraph/core/NodeGraphBase.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "logging/LoggingAll.h"
#include "meta/Reflection.h"

#include <string>
#include <vector>
Expand All @@ -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<NodeGraphBase>())
{}

virtual ~NodeGraphBase() {
LOG(LogInfo) << "Node graph base destroyed";
}
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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<class T>
bool IsOfOperation() {
return l::meta::template class_hash<T> == mOperationTypeId;
}

protected:
virtual void SetNumInputs(int8_t numInputs);
Expand All @@ -114,9 +126,10 @@ namespace l::nodegraph {
std::vector<NodeGraphOutput> mOutputs;

int32_t mId = -1;
OutputType mOutputType;
NodeType mOutputType;

std::string mName;
size_t mOperationTypeHash;
};

/**********************************************************************************/
Expand Down Expand Up @@ -168,9 +181,10 @@ namespace l::nodegraph {
template<class T, class... Params>
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>(params)...)
mOperation(this, std::forward<Params>(params)...),
mOperationTypeId = typeid(T)
{
SetNumInputs(mOperation.GetNumInputs());
SetNumOutputs(mOperation.GetNumOutputs());
Expand Down
3 changes: 2 additions & 1 deletion packages/nodegraph/include/nodegraph/core/NodeGraphData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<float, float> GetInputBounds(InputBound bound);
Expand Down
12 changes: 10 additions & 2 deletions packages/nodegraph/include/nodegraph/core/NodeGraphGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,22 @@ namespace l::nodegraph {
bool RemoveNode(int32_t id);

template<class T, class... Params, std::enable_if_t<std::is_base_of_v<NodeGraphOp, T>, int> = 0>
l::nodegraph::NodeGraphBase* NewNode(OutputType nodeType, Params&&... params) {
l::nodegraph::NodeGraphBase* NewNode(NodeType nodeType, Params&&... params) {
mNodes.emplace_back(std::make_unique<l::nodegraph::NodeGraph<T, Params...>>(nodeType, std::forward<Params>(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<void(NodeGraphBase*)> cb);
void ForEachOutputNode(std::function<void(NodeGraphBase*)> cb);

void ClearProcessFlags();
void ProcessSubGraph(int32_t numSamples);
void Tick(int32_t tickCount, float elapsed);
Expand All @@ -92,6 +99,7 @@ namespace l::nodegraph {

std::vector<std::unique_ptr<NodeGraphBase>> mNodes;
std::vector<NodeGraphBase*> mOutputNodes;
std::vector<NodeGraphBase*> mInputNodes;

int32_t mLastTickCount = 0;
};
Expand Down
106 changes: 57 additions & 49 deletions packages/nodegraph/source/common/NodeGraphSchema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,160 +26,160 @@ namespace l::nodegraph {
l::nodegraph::NodeGraphBase* node = nullptr;
switch (typeId) {
case 0:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(OutputType::Default, 0);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(NodeType::Default, 0);
break;
case 1:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(OutputType::Default, 1);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(NodeType::Default, 1);
break;
case 2:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(OutputType::Default, 2);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(NodeType::Default, 2);
break;
case 3:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(OutputType::Default, 3);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceConstants>(NodeType::Default, 3);
break;
case 4:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceTime>(OutputType::ExternalOutput, mAudioOutput != nullptr ? mAudioOutput->GetSampleRate() : 44100, 60);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSourceTime>(NodeType::ExternalOutput, mAudioOutput != nullptr ? mAudioOutput->GetSampleRate() : 44100, 60);
break;

case 50:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericAdd>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericAdd>(NodeType::Default);
break;
case 51:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericSubtract>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericSubtract>(NodeType::Default);
break;
case 52:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericNegate>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericNegate>(NodeType::Default);
break;
case 53:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericMultiply>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericMultiply>(NodeType::Default);
break;
case 54:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericIntegral>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericIntegral>(NodeType::Default);
break;
case 55:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericMultiply3>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericMultiply3>(NodeType::Default);
break;
case 56:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericMultiplyAndAdd>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericMultiplyAndAdd>(NodeType::Default);
break;
case 57:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericRound>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphNumericRound>(NodeType::Default);
break;

case 100:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphLogicalAnd>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphLogicalAnd>(NodeType::Default);
break;
case 101:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphLogicalOr>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphLogicalOr>(NodeType::Default);
break;
case 102:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphLogicalXor>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphLogicalXor>(NodeType::Default);
break;

case 150:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphFilterLowpass>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphFilterLowpass>(NodeType::Default);
break;
case 151:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphFilterHighpass>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphFilterHighpass>(NodeType::Default);
break;
case 152:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphFilterChamberlain2pole>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphFilterChamberlain2pole>(NodeType::Default);
break;

case 200:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputDebug>(OutputType::ExternalOutput);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputDebug>(NodeType::ExternalOutput);
break;
case 201:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputSpeaker>(OutputType::ExternalOutput, mAudioOutput);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputSpeaker>(NodeType::ExternalOutput, mAudioOutput);
break;
case 202:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputPlot>(OutputType::ExternalVisualOutput, 100);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputPlot>(NodeType::ExternalVisualOutput, 100);
break;
case 203:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputImGuiPlotLine>(OutputType::ExternalOutput);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputImGuiPlotLine>(NodeType::ExternalOutput);
break;
case 204:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputImGuiPlotCandles>(OutputType::ExternalOutput);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphOutputImGuiPlotCandles>(NodeType::ExternalOutput);
break;

case 251:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectReverb1>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectReverb1>(NodeType::Default);
break;
case 252:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectReverb2>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectReverb2>(NodeType::Default);
break;
case 254:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectLimiter>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectLimiter>(NodeType::Default);
break;
case 255:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectEnvelopeFollower>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectEnvelopeFollower>(NodeType::Default);
break;
case 256:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectSaturator>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectSaturator>(NodeType::Default);
break;
case 257:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectTranceGate>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphEffectTranceGate>(NodeType::Default);
break;

case 300:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputKeyboardPiano>(OutputType::Default, mKeyState);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputKeyboardPiano>(NodeType::Default, mKeyState);
break;
case 301:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiKeyboard>(OutputType::Default, mMidiManager);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiKeyboard>(NodeType::Default, mMidiManager);
break;
case 302:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiKnobs>(OutputType::Default, mMidiManager);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiKnobs>(NodeType::Default, mMidiManager);
break;
case 303:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(OutputType::Default, mMidiManager, 0);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(NodeType::Default, mMidiManager, 0);
break;
case 304:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(OutputType::Default, mMidiManager, 1);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(NodeType::Default, mMidiManager, 1);
break;
case 305:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(OutputType::Default, mMidiManager, 2);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(NodeType::Default, mMidiManager, 2);
break;
case 306:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(OutputType::Default, mMidiManager, 3);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(NodeType::Default, mMidiManager, 3);
break;
case 307:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(OutputType::Default, mMidiManager, 4);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphInputMidiButtons>(NodeType::Default, mMidiManager, 4);
break;

case 350:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSine>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSine>(NodeType::Default);
break;
case 351:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSineFM>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSineFM>(NodeType::Default);
break;
case 352:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSineFM2>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSineFM2>(NodeType::Default);
break;
case 353:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSineFM3>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSineFM3>(NodeType::Default);
break;
case 354:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSaw>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSaw>(NodeType::Default);
break;
case 355:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSine2>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSine2>(NodeType::Default);
break;
case 356:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSaw2>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphSignalSaw2>(NodeType::Default);
break;

case 400:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphControlEnvelope>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphControlEnvelope>(NodeType::Default);
break;
case 401:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphControlArpeggio>(OutputType::Default);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphControlArpeggio>(NodeType::Default);
break;

case 450:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphDataBusDataIn>(OutputType::Default, 6);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphDataBusDataIn>(NodeType::Default, 6);
break;
case 451:
node = mMainNodeGraph.NewNode<l::nodegraph::GraphDataBusDataOut>(OutputType::ExternalOutput, 6);
node = mMainNodeGraph.NewNode<l::nodegraph::GraphDataBusDataOut>(NodeType::ExternalOutput, 6);
break;

default:
Expand Down Expand Up @@ -214,6 +214,14 @@ namespace l::nodegraph {
return false;
}

void NodeGraphSchema::ForEachInputNode(std::function<void(NodeGraphBase*)> cb) {
mMainNodeGraph.ForEachInputNode(cb);
}

void NodeGraphSchema::ForEachOutputNode(std::function<void(NodeGraphBase*)> cb) {
mMainNodeGraph.ForEachOutputNode(cb);
}

void NodeGraphSchema::ForEachNodeType(std::function<void(std::string_view, const std::vector<UINodeDesc>&)> cb) const {
for (auto& it : mRegisteredNodeTypes) {
cb(it.first, it.second);
Expand Down
2 changes: 1 addition & 1 deletion packages/nodegraph/source/common/core/NodeGraphBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ namespace l::nodegraph {
return mOutputs.at(outputChannel).IsPolled();
}

OutputType NodeGraphBase::GetOutputType() {
NodeType NodeGraphBase::GetOutputType() {
return mOutputType;
}

Expand Down
Loading

0 comments on commit b3ae348

Please sign in to comment.