aboutsummaryrefslogtreecommitdiff
path: root/core/src/Model/Workflow
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-05-14 20:52:00 -0700
committerrtk0c <[email protected]>2021-05-14 20:52:00 -0700
commitfa13cad2bf12d8f7f63f7ff6aab07dd2eaf6ec6d (patch)
tree994198f3636030b3974f73170fc59b04a794681d /core/src/Model/Workflow
parent765df313e065f8401319c68ba70cd41b0bc34c9d (diff)
Node graph editor basic functionality
Diffstat (limited to 'core/src/Model/Workflow')
-rw-r--r--core/src/Model/Workflow/Nodes/DocumentNodes.cpp2
-rw-r--r--core/src/Model/Workflow/Nodes/NumericNodes.cpp4
-rw-r--r--core/src/Model/Workflow/Nodes/TextNodes.cpp2
-rw-r--r--core/src/Model/Workflow/Nodes/UserInputNodes.cpp4
-rw-r--r--core/src/Model/Workflow/Workflow.hpp29
-rw-r--r--core/src/Model/Workflow/Workflow_Main.cpp57
6 files changed, 68 insertions, 30 deletions
diff --git a/core/src/Model/Workflow/Nodes/DocumentNodes.cpp b/core/src/Model/Workflow/Nodes/DocumentNodes.cpp
index b858b49..3925dec 100644
--- a/core/src/Model/Workflow/Nodes/DocumentNodes.cpp
+++ b/core/src/Model/Workflow/Nodes/DocumentNodes.cpp
@@ -9,7 +9,7 @@ bool DocumentTemplateExpansionNode::IsInstance(const WorkflowNode* node)
}
DocumentTemplateExpansionNode::DocumentTemplateExpansionNode()
- : WorkflowNode(KD_DocumentTemplateExpansion)
+ : WorkflowNode(KD_DocumentTemplateExpansion, false)
{
}
diff --git a/core/src/Model/Workflow/Nodes/NumericNodes.cpp b/core/src/Model/Workflow/Nodes/NumericNodes.cpp
index 083172e..ad51fb4 100644
--- a/core/src/Model/Workflow/Nodes/NumericNodes.cpp
+++ b/core/src/Model/Workflow/Nodes/NumericNodes.cpp
@@ -36,7 +36,7 @@ bool NumericOperationNode::IsInstance(const WorkflowNode* node)
}
NumericOperationNode::NumericOperationNode(OperationType type)
- : WorkflowNode(OperationTypeToNodeKind(type))
+ : WorkflowNode(OperationTypeToNodeKind(type), false)
, mType{ type }
{
mInputs.resize(2);
@@ -85,7 +85,7 @@ bool NumericExpressionNode::IsInstance(const WorkflowNode* node)
}
NumericExpressionNode::NumericExpressionNode()
- : WorkflowNode(KD_NumericExpression)
+ : WorkflowNode(KD_NumericExpression, false)
{
}
diff --git a/core/src/Model/Workflow/Nodes/TextNodes.cpp b/core/src/Model/Workflow/Nodes/TextNodes.cpp
index b70290d..6c71309 100644
--- a/core/src/Model/Workflow/Nodes/TextNodes.cpp
+++ b/core/src/Model/Workflow/Nodes/TextNodes.cpp
@@ -53,7 +53,7 @@ bool TextFormatterNode::IsInstance(const WorkflowNode* node)
}
TextFormatterNode::TextFormatterNode()
- : WorkflowNode(KD_TextFormatting)
+ : WorkflowNode(KD_TextFormatting, false)
{
}
diff --git a/core/src/Model/Workflow/Nodes/UserInputNodes.cpp b/core/src/Model/Workflow/Nodes/UserInputNodes.cpp
index 3a30631..f8d3e01 100644
--- a/core/src/Model/Workflow/Nodes/UserInputNodes.cpp
+++ b/core/src/Model/Workflow/Nodes/UserInputNodes.cpp
@@ -9,7 +9,7 @@ bool FormInputNode::IsInstance(const WorkflowNode* node)
}
FormInputNode::FormInputNode()
- : WorkflowNode(KD_FormInput)
+ : WorkflowNode(KD_FormInput, false)
{
}
@@ -23,7 +23,7 @@ bool DatabaseRowsInputNode::IsInstance(const WorkflowNode* node)
}
DatabaseRowsInputNode::DatabaseRowsInputNode()
- : WorkflowNode(KD_DatabaseRowsInput)
+ : WorkflowNode(KD_DatabaseRowsInput, false)
{
}
diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp
index 79c2b2f..847aa72 100644
--- a/core/src/Model/Workflow/Workflow.hpp
+++ b/core/src/Model/Workflow/Workflow.hpp
@@ -4,6 +4,7 @@
#include "Utils/Vector.hpp"
#include "cplt_fwd.hpp"
+#include <imgui_node_editor.h>
#include <cstddef>
#include <cstdint>
#include <iosfwd>
@@ -14,6 +15,8 @@
#include <variant>
#include <vector>
+namespace ImNodes = ax::NodeEditor;
+
class WorkflowConnection
{
public:
@@ -31,7 +34,7 @@ public:
bool IsValid() const;
/// Used for `LinkId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading).
- size_t GetLinkId() const;
+ ImNodes::LinkId GetLinkId() const;
void DrawDebugInfo() const;
void ReadFrom(std::istream& stream);
@@ -99,13 +102,14 @@ protected:
uint32_t mId;
Kind mKind;
int mDepth;
+ bool mLocked;
public:
static const char* FormatKind(Kind kind);
static const char* FormatType(Type type);
static std::unique_ptr<WorkflowNode> CreateByKind(Kind kind);
- WorkflowNode(Kind kind);
+ WorkflowNode(Kind kind, bool locked);
virtual ~WorkflowNode() = default;
WorkflowNode(const WorkflowNode&) = delete;
@@ -118,23 +122,28 @@ public:
uint32_t GetId() const;
/// Used for `NodeId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading).
- size_t GetNodeId() const;
+ ImNodes::NodeId GetNodeId() const;
Kind GetKind() const;
int GetDepth() const;
+ bool IsLocked() const;
Type GetType() const;
bool IsInputNode() const;
bool IsOutputNode() const;
- void ConnectInput(uint32_t pinId, WorkflowNode& output, uint32_t outputNodeId);
+ void ConnectInput(uint32_t pinId, WorkflowNode& srcNode, uint32_t srcPinId);
void DisconnectInput(uint32_t pinId);
+
+ void DrawInputPinDebugInfo(uint32_t pinId) const;
const InputPin& GetInputPin(uint32_t pinId)const ;
- size_t GetInputPinUniqueId(uint32_t pinId) const;
+ ImNodes::PinId GetInputPinUniqueId(uint32_t pinId) const;
- void ConnectOutput(uint32_t pinId, WorkflowNode& input, uint32_t inputNodeId);
+ void ConnectOutput(uint32_t pinId, WorkflowNode& dstNode, uint32_t dstPinId);
void DisconnectOutput(uint32_t pinId);
+
+ void DrawOutputPinDebugInfo(uint32_t pinId)const;
const OutputPin& GetOutputPin(uint32_t pinId)const ;
- size_t GetOutputPinUniqueId(uint32_t pinId) const;
+ ImNodes::PinId GetOutputPinUniqueId(uint32_t pinId) const;
virtual void Evaluate(WorkflowEvaluationContext& ctx) = 0;
@@ -187,7 +196,9 @@ public:
std::vector<std::unique_ptr<BaseValue>>& GetConstants();
WorkflowConnection* GetConnectionById(uint32_t id);
+ WorkflowConnection* GetConnectionByLinkId(ImNodes::LinkId linkId);
WorkflowNode* GetNodeById(uint32_t id);
+ WorkflowNode* GetNodeByNodeId(ImNodes::NodeId nodeId);
BaseValue* GetConstantById(uint32_t id);
struct GlobalPinId
@@ -200,8 +211,8 @@ public:
};
/// `pinId` should be the `UniqueId` of a pin from a node that's within this workflow.
- GlobalPinId DisassembleGlobalPinId(size_t id);
- size_t FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const;
+ GlobalPinId DisassembleGlobalPinId(ImNodes::PinId id);
+ ImNodes::PinId FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const;
const std::vector<std::vector<uint32_t>>& GetDepthGroups() const;
bool DoesDepthNeedsUpdate() const;
diff --git a/core/src/Model/Workflow/Workflow_Main.cpp b/core/src/Model/Workflow/Workflow_Main.cpp
index 678b4b8..1b50064 100644
--- a/core/src/Model/Workflow/Workflow_Main.cpp
+++ b/core/src/Model/Workflow/Workflow_Main.cpp
@@ -24,7 +24,7 @@ bool WorkflowConnection::IsValid() const
return Id != 0;
}
-size_t WorkflowConnection::GetLinkId() const
+ImNodes::LinkId WorkflowConnection::GetLinkId() const
{
// Our id is 0-based (represents an index directly)
// but imgui-node-editor uses the value 0 to represent a null id, so we need to offset by 1
@@ -33,12 +33,10 @@ size_t WorkflowConnection::GetLinkId() const
void WorkflowConnection::DrawDebugInfo() const
{
- ImGui::BeginTooltip();
ImGui::Text("Source (node with output pin):");
ImGui::Text("{ Node = %u, Pin = %u }", SourceNode, SourcePin);
ImGui::Text("Destination (node with input pin):");
ImGui::Text("{ Node = %u, Pin = %u }", DestinationNode, DestinationPin);
- ImGui::EndTooltip();
}
void WorkflowConnection::ReadFrom(std::istream& stream)
@@ -78,9 +76,10 @@ BaseValue::Kind WorkflowNode::OutputPin::GetMatchingType() const
return MatchingType;
}
-WorkflowNode::WorkflowNode(Kind kind)
+WorkflowNode::WorkflowNode(Kind kind, bool locked)
: mKind{ kind }
, mDepth{ -1 }
+ , mLocked(locked)
{
}
@@ -99,7 +98,7 @@ uint32_t WorkflowNode::GetId() const
return mId;
}
-size_t WorkflowNode::GetNodeId() const
+ImNodes::NodeId WorkflowNode::GetNodeId() const
{
// See WorkflowConnection::GetLinkId for the rationale
return mId + 1;
@@ -115,6 +114,11 @@ int WorkflowNode::GetDepth() const
return mDepth;
}
+bool WorkflowNode::IsLocked() const
+{
+ return mLocked;
+}
+
WorkflowNode::Type WorkflowNode::GetType() const
{
if (IsInputNode()) {
@@ -136,9 +140,9 @@ bool WorkflowNode::IsOutputNode() const
return mOutputs.size() == 0;
}
-void WorkflowNode::ConnectInput(uint32_t pinId, WorkflowNode& output, uint32_t outputNodeId)
+void WorkflowNode::ConnectInput(uint32_t pinId, WorkflowNode& srcNode, uint32_t srcPinId)
{
- mWorkflow->Connect(*this, pinId, output, outputNodeId);
+ mWorkflow->Connect(*this, pinId, srcNode, srcPinId);
}
void WorkflowNode::DisconnectInput(uint32_t pinId)
@@ -146,19 +150,25 @@ void WorkflowNode::DisconnectInput(uint32_t pinId)
mWorkflow->DisconnectByDestination(*this, pinId);
}
+void WorkflowNode::DrawInputPinDebugInfo(uint32_t pinId) const
+{
+ ImGui::Text("Node ID: %d", mId);
+ ImGui::Text("Pin ID: (input) %d", pinId);
+}
+
const WorkflowNode::InputPin& WorkflowNode::GetInputPin(uint32_t pinId) const
{
return mInputs[pinId];
}
-size_t WorkflowNode::GetInputPinUniqueId(uint32_t pinId) const
+ImNodes::PinId WorkflowNode::GetInputPinUniqueId(uint32_t pinId) const
{
return mWorkflow->FabricateGlobalPinId(*this, pinId, false);
}
-void WorkflowNode::ConnectOutput(uint32_t pinId, WorkflowNode& input, uint32_t inputNodeId)
+void WorkflowNode::ConnectOutput(uint32_t pinId, WorkflowNode& dstNode, uint32_t dstPinId)
{
- mWorkflow->Connect(input, inputNodeId, *this, pinId);
+ mWorkflow->Connect(dstNode, dstPinId, *this, pinId);
}
void WorkflowNode::DisconnectOutput(uint32_t pinId)
@@ -166,12 +176,18 @@ void WorkflowNode::DisconnectOutput(uint32_t pinId)
mWorkflow->DisconnectBySource(*this, pinId);
}
+void WorkflowNode::DrawOutputPinDebugInfo(uint32_t pinId) const
+{
+ ImGui::Text("Node ID: %d", mId);
+ ImGui::Text("Pin ID: (output) %d", pinId);
+}
+
const WorkflowNode::OutputPin& WorkflowNode::GetOutputPin(uint32_t pinId) const
{
return mOutputs[pinId];
}
-size_t WorkflowNode::GetOutputPinUniqueId(uint32_t pinId) const
+ImNodes::PinId WorkflowNode::GetOutputPinUniqueId(uint32_t pinId) const
{
return mWorkflow->FabricateGlobalPinId(*this, pinId, true);
}
@@ -180,12 +196,14 @@ void WorkflowNode::Draw()
{
for (uint32_t i = 0; i < mInputs.size(); ++i) {
auto& pin = mInputs[i];
+ auto& typeInfo = BaseValue::QueryInfo(pin.MatchingType);
ImNodes::BeginPin(GetInputPinUniqueId(i), ImNodes::PinKind::Input);
// TODO
ImNodes::EndPin();
}
for (uint32_t i = 0; i < mOutputs.size(); ++i) {
auto& pin = mOutputs[i];
+ auto& typeInfo = BaseValue::QueryInfo(pin.MatchingType);
ImNodes::BeginPin(GetOutputPinUniqueId(i), ImNodes::PinKind::Output);
// TODO
ImNodes::EndPin();
@@ -194,13 +212,11 @@ void WorkflowNode::Draw()
void WorkflowNode::DrawDebugInfo() const
{
- ImGui::BeginTooltip();
ImGui::Text("Node kind: %s", FormatKind(mKind));
ImGui::Text("Node type: %s", FormatType(GetType()));
ImGui::Text("Node ID: %u", mId);
ImGui::Text("Depth: %d", mDepth);
DrawExtraDebugInfo();
- ImGui::EndTooltip();
}
void WorkflowNode::ReadFrom(std::istream& stream)
@@ -338,17 +354,27 @@ WorkflowConnection* Workflow::GetConnectionById(uint32_t id)
return &mConnections[id];
}
+WorkflowConnection* Workflow::GetConnectionByLinkId(ImNodes::LinkId id)
+{
+ return &mConnections[(uint32_t)(size_t)id - 1];
+}
+
WorkflowNode* Workflow::GetNodeById(uint32_t id)
{
return mNodes[id].get();
}
+WorkflowNode* Workflow::GetNodeByNodeId(ImNodes::NodeId id)
+{
+ return mNodes[(uint32_t)(size_t)id - 1].get();
+}
+
BaseValue* Workflow::GetConstantById(uint32_t id)
{
return mConstants[id].get();
}
-Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(size_t id)
+Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(ImNodes::PinId pinId)
{
// imgui-node-editor requires all pins to have a global, unique id
// but in our model the pin are typed (input vs output) and associated with a node: there is no built-in global id
@@ -362,6 +388,7 @@ Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(size_t id)
// 1 is added to pin id to prevent the 0th node's 0th input pin resulting in a 0 global pin id
// (this is problematic because imgui-node-editor use 0 to represent null)
+ auto id = static_cast<uint64_t>(pinId);
GlobalPinId result;
result.Node = mNodes[id >> 32].get();
@@ -371,7 +398,7 @@ Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(size_t id)
return result;
}
-size_t Workflow::FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const
+ImNodes::PinId Workflow::FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const
{
// See this->DisassembleGlobalPinId for format details and rationale