summaryrefslogtreecommitdiff
path: root/core/src/Model
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-05-12 13:23:56 -0700
committerrtk0c <[email protected]>2021-05-12 13:34:43 -0700
commit765df313e065f8401319c68ba70cd41b0bc34c9d (patch)
tree44e0c781ed9f5ea0f98ac906e96c677d04befa27 /core/src/Model
parent6ec8cc216282396ece535941ea6ca4a63d924e8f (diff)
Start to work on actually rendering the node graph
Diffstat (limited to 'core/src/Model')
-rw-r--r--core/src/Model/Workflow/Value.hpp12
-rw-r--r--core/src/Model/Workflow/Value_RTTI.cpp29
-rw-r--r--core/src/Model/Workflow/Workflow.hpp100
-rw-r--r--core/src/Model/Workflow/Workflow_Main.cpp193
4 files changed, 220 insertions, 114 deletions
diff --git a/core/src/Model/Workflow/Value.hpp b/core/src/Model/Workflow/Value.hpp
index 6cd42f3..8b3e63a 100644
--- a/core/src/Model/Workflow/Value.hpp
+++ b/core/src/Model/Workflow/Value.hpp
@@ -1,5 +1,8 @@
#pragma once
+#include "cplt_fwd.hpp"
+#include "Utils/Color.hpp"
+
#include <iosfwd>
#include <memory>
@@ -17,11 +20,18 @@ public:
KindCount = InvalidKind,
};
+ struct KindInfo
+ {
+ ImGui::IconType PinIcon;
+ RgbaColor PinColor;
+ };
+
private:
Kind mKind;
public:
- static const char* FormatKind(Kind kind);
+ static const KindInfo& QueryInfo(Kind kind);
+ static const char* Format(Kind kind);
static std::unique_ptr<BaseValue> CreateByKind(Kind kind);
BaseValue(Kind kind);
diff --git a/core/src/Model/Workflow/Value_RTTI.cpp b/core/src/Model/Workflow/Value_RTTI.cpp
index a0c3213..5e24ed7 100644
--- a/core/src/Model/Workflow/Value_RTTI.cpp
+++ b/core/src/Model/Workflow/Value_RTTI.cpp
@@ -1,9 +1,34 @@
#include "Value.hpp"
#include "Model/Workflow/Values/BasicValues.hpp"
-#include "Utils/Macros.hpp"
+#include "UI/UI.hpp"
-const char* BaseValue::FormatKind(Kind kind)
+constexpr BaseValue::KindInfo kNumericInfo{
+ .PinIcon = ImGui::IconType::Circle,
+ .PinColor = RgbaColor(147, 226, 74),
+};
+
+constexpr BaseValue::KindInfo kTextInfo{
+ .PinIcon = ImGui::IconType::Circle,
+ .PinColor = RgbaColor(124, 21, 153),
+};
+
+constexpr BaseValue::KindInfo kDateTimeInfo{
+ .PinIcon = ImGui::IconType::Diamond,
+ .PinColor = RgbaColor(147, 226, 74),
+};
+
+const BaseValue::KindInfo& BaseValue::QueryInfo(BaseValue::Kind kind)
+{
+ switch (kind) {
+ case KD_Numeric: return kNumericInfo;
+ case KD_Text: break;
+ case KD_DateTime: break;
+ case InvalidKind: break;
+ }
+}
+
+const char* BaseValue::Format(Kind kind)
{
switch (kind) {
case KD_Numeric: return "Numeric";
diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp
index 7bcd349..79c2b2f 100644
--- a/core/src/Model/Workflow/Workflow.hpp
+++ b/core/src/Model/Workflow/Workflow.hpp
@@ -17,20 +17,22 @@
class WorkflowConnection
{
public:
- static constexpr auto kInvalidId = std::numeric_limits<size_t>::max();
+ static constexpr auto kInvalidId = std::numeric_limits<uint32_t>::max();
- /// Used for `LinkId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading).
- size_t UniqueId;
- size_t SourceNode;
- size_t DestinationNode;
- int SourcePin;
- int DestinationPin;
+ uint32_t Id;
+ uint32_t SourceNode;
+ uint32_t SourcePin;
+ uint32_t DestinationNode;
+ uint32_t DestinationPin;
public:
WorkflowConnection();
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;
+
void DrawDebugInfo() const;
void ReadFrom(std::istream& stream);
void WriteTo(std::ostream& stream);
@@ -39,7 +41,8 @@ public:
class WorkflowNode
{
public:
- static constexpr auto kInvalidId = std::numeric_limits<size_t>::max();
+ static constexpr auto kInvalidId = std::numeric_limits<uint32_t>::max();
+ static constexpr auto kInvalidPinId = std::numeric_limits<uint32_t>::max();
enum Type
{
@@ -64,16 +67,13 @@ public:
KindCount = InvalidKind,
};
-protected:
struct InputPin
{
- /// Equivalent of `PinId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading).
- size_t UniqueId;
- size_t Connection = WorkflowConnection::kInvalidId;
+ uint32_t Connection = WorkflowConnection::kInvalidId;
BaseValue::Kind MatchingType = BaseValue::InvalidKind;
bool ConnectionToConst = false;
- /// A constant connection connects from a user-specified constant value, feeding to a valid \c Destination and \c DestinationPin (i.e. input pins).
+ /// A constant connection connects from a user-specified constant value, feeding to a valid \c DestinationNode and \c DestinationPin (i.e. input pins).
bool IsConstantConnection() const;
bool IsConnected() const;
BaseValue::Kind GetMatchingType() const;
@@ -81,26 +81,22 @@ protected:
struct OutputPin
{
- /// Equivalent of `PinId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading).
- size_t UniqueId;
- size_t Connection = WorkflowConnection::kInvalidId;
+ uint32_t Connection = WorkflowConnection::kInvalidId;
BaseValue::Kind MatchingType = BaseValue::InvalidKind;
- bool AllowsMultipleConnections = false;
bool IsConnected() const;
BaseValue::Kind GetMatchingType() const;
};
+protected:
friend class Workflow;
friend class WorkflowEvaluationContext;
Workflow* mWorkflow;
- /// Equivalent of `NodeId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading).
- size_t mUniqueId;
- size_t mId;
std::vector<InputPin> mInputs;
std::vector<OutputPin> mOutputs;
Vec2i mPosition;
+ uint32_t mId;
Kind mKind;
int mDepth;
@@ -120,7 +116,9 @@ public:
void SetPosition(const Vec2i& position);
Vec2i GetPosition() const;
- size_t GetId() const;
+ 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;
Kind GetKind() const;
int GetDepth() const;
@@ -128,13 +126,15 @@ public:
bool IsInputNode() const;
bool IsOutputNode() const;
- void ConnectInput(int nodeId, WorkflowNode& output, int outputNodeId);
- void DisconnectInput(int nodeId);
- bool IsInputConnected(int nodeId) const;
+ void ConnectInput(uint32_t pinId, WorkflowNode& output, uint32_t outputNodeId);
+ void DisconnectInput(uint32_t pinId);
+ const InputPin& GetInputPin(uint32_t pinId)const ;
+ size_t GetInputPinUniqueId(uint32_t pinId) const;
- void ConnectOutput(int nodeId, WorkflowNode& input, int inputNodeId);
- void DisconnectOutput(int nodeId);
- bool IsOutputConnected(int nodeId) const;
+ void ConnectOutput(uint32_t pinId, WorkflowNode& input, uint32_t inputNodeId);
+ void DisconnectOutput(uint32_t pinId);
+ const OutputPin& GetOutputPin(uint32_t pinId)const ;
+ size_t GetOutputPinUniqueId(uint32_t pinId) const;
virtual void Evaluate(WorkflowEvaluationContext& ctx) = 0;
@@ -157,20 +157,20 @@ protected:
/* For \c Workflow to invoke, override by implementations */
- void OnAttach(Workflow& workflow, size_t newId) {}
- void OnDetach() {}
+ void OnAttach(Workflow& workflow, uint32_t newId);
+ void OnDetach();
};
class Workflow
{
private:
+ friend class WorkflowNode;
friend class WorkflowEvaluationContext;
- size_t mUniqueId = 0;
std::vector<WorkflowConnection> mConnections;
std::vector<std::unique_ptr<WorkflowNode>> mNodes;
std::vector<std::unique_ptr<BaseValue>> mConstants;
- std::vector<std::vector<size_t>> mDepthGroups;
+ std::vector<std::vector<uint32_t>> mDepthGroups;
int mConnectionCount;
int mNodeCount;
int mConstantCount;
@@ -186,23 +186,36 @@ public:
const std::vector<std::unique_ptr<BaseValue>>& GetConstants() const;
std::vector<std::unique_ptr<BaseValue>>& GetConstants();
- WorkflowConnection* GetConnectionById(size_t id);
- WorkflowNode* GetStepById(size_t id);
- BaseValue* GetConstantById(size_t id);
+ WorkflowConnection* GetConnectionById(uint32_t id);
+ WorkflowNode* GetNodeById(uint32_t id);
+ BaseValue* GetConstantById(uint32_t id);
+
+ struct GlobalPinId
+ {
+ WorkflowNode* Node;
+ uint32_t PinId;
+ /// true => input pin
+ /// false => output pin
+ bool IsOutput;
+ };
+
+ /// `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;
- const std::vector<std::vector<size_t>>& GetDepthGroups() const;
+ const std::vector<std::vector<uint32_t>>& GetDepthGroups() const;
bool DoesDepthNeedsUpdate() const;
/* Graph mutation */
- void AddStep(std::unique_ptr<WorkflowNode> step);
- void RemoveStep(size_t id);
+ void AddNode(std::unique_ptr<WorkflowNode> step);
+ void RemoveNode(uint32_t id);
- void RemoveConnection(size_t id);
+ void RemoveConnection(uint32_t id);
- bool Connect(WorkflowNode& sourceNode, int sourcePin, WorkflowNode& destinationNode, int destinationPin);
- bool DisconnectBySource(WorkflowNode& sourceNode, int sourcePin);
- bool DisconnectByDestination(WorkflowNode& destinationNode, int destinationPin);
+ bool Connect(WorkflowNode& sourceNode, uint32_t sourcePin, WorkflowNode& destinationNode, uint32_t destinationPin);
+ bool DisconnectBySource(WorkflowNode& sourceNode, uint32_t sourcePin);
+ bool DisconnectByDestination(WorkflowNode& destinationNode, uint32_t destinationPin);
/* Graph rebuild */
@@ -218,12 +231,12 @@ public:
struct UnsatisfiedDependencies
{
- std::vector<size_t> UnsatisfiedNodes;
+ std::vector<uint32_t> UnsatisfiedNodes;
};
struct UnreachableNodes
{
- std::vector<size_t> UnreachableNodes;
+ std::vector<uint32_t> UnreachableNodes;
};
using T = std::variant<
@@ -246,7 +259,6 @@ public:
void WriteTo(std::ostream& stream);
private:
- size_t AllocUniqueId();
std::pair<WorkflowConnection&, size_t> AllocWorkflowConnection();
std::pair<std::unique_ptr<WorkflowNode>&, size_t> AllocWorkflowStep();
};
diff --git a/core/src/Model/Workflow/Workflow_Main.cpp b/core/src/Model/Workflow/Workflow_Main.cpp
index cfa7cea..678b4b8 100644
--- a/core/src/Model/Workflow/Workflow_Main.cpp
+++ b/core/src/Model/Workflow/Workflow_Main.cpp
@@ -3,7 +3,6 @@
#include <imgui.h>
#include <imgui_node_editor.h>
#include <tsl/robin_set.h>
-#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
@@ -12,38 +11,46 @@
namespace ImNodes = ax::NodeEditor;
WorkflowConnection::WorkflowConnection()
- : SourceNode{ WorkflowNode::kInvalidId }
+ : Id{ 0 }
+ , SourceNode{ WorkflowNode::kInvalidId }
, DestinationNode{ WorkflowNode::kInvalidId }
- , SourcePin{ -1 }
- , DestinationPin{ -1 }
+ , SourcePin{ WorkflowNode::kInvalidPinId }
+ , DestinationPin{ WorkflowNode::kInvalidPinId }
{
}
bool WorkflowConnection::IsValid() const
{
- return SourceNode != WorkflowNode::kInvalidId;
+ return Id != 0;
+}
+
+size_t 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
+ return Id + 1;
}
void WorkflowConnection::DrawDebugInfo() const
{
ImGui::BeginTooltip();
ImGui::Text("Source (node with output pin):");
- ImGui::Text("{ Node = %llu, Pin = %d }", SourceNode, SourcePin);
+ ImGui::Text("{ Node = %u, Pin = %u }", SourceNode, SourcePin);
ImGui::Text("Destination (node with input pin):");
- ImGui::Text("{ Node = %llu, Pin = %d }", DestinationNode, DestinationPin);
+ ImGui::Text("{ Node = %u, Pin = %u }", DestinationNode, DestinationPin);
ImGui::EndTooltip();
}
void WorkflowConnection::ReadFrom(std::istream& stream)
{
- stream >> SourceNode >> DestinationNode;
- stream >> SourcePin >> DestinationPin;
+ stream >> SourceNode >> SourcePin;
+ stream >> DestinationNode >> DestinationPin;
}
void WorkflowConnection::WriteTo(std::ostream& stream)
{
- stream << SourceNode << DestinationNode;
- stream << SourcePin << DestinationPin;
+ stream << SourceNode << SourcePin;
+ stream << DestinationNode << DestinationPin;
}
bool WorkflowNode::InputPin::IsConstantConnection() const
@@ -87,11 +94,17 @@ void WorkflowNode::SetPosition(const Vec2i& position)
mPosition = position;
}
-size_t WorkflowNode::GetId() const
+uint32_t WorkflowNode::GetId() const
{
return mId;
}
+size_t WorkflowNode::GetNodeId() const
+{
+ // See WorkflowConnection::GetLinkId for the rationale
+ return mId + 1;
+}
+
WorkflowNode::Kind WorkflowNode::GetKind() const
{
return mKind;
@@ -123,47 +136,57 @@ bool WorkflowNode::IsOutputNode() const
return mOutputs.size() == 0;
}
-void WorkflowNode::ConnectInput(int nodeId, WorkflowNode& output, int outputNodeId)
+void WorkflowNode::ConnectInput(uint32_t pinId, WorkflowNode& output, uint32_t outputNodeId)
+{
+ mWorkflow->Connect(*this, pinId, output, outputNodeId);
+}
+
+void WorkflowNode::DisconnectInput(uint32_t pinId)
+{
+ mWorkflow->DisconnectByDestination(*this, pinId);
+}
+
+const WorkflowNode::InputPin& WorkflowNode::GetInputPin(uint32_t pinId) const
{
- mWorkflow->Connect(*this, nodeId, output, outputNodeId);
+ return mInputs[pinId];
}
-void WorkflowNode::DisconnectInput(int nodeId)
+size_t WorkflowNode::GetInputPinUniqueId(uint32_t pinId) const
{
- mWorkflow->DisconnectByDestination(*this, nodeId);
+ return mWorkflow->FabricateGlobalPinId(*this, pinId, false);
}
-bool WorkflowNode::IsInputConnected(int nodeId) const
+void WorkflowNode::ConnectOutput(uint32_t pinId, WorkflowNode& input, uint32_t inputNodeId)
{
- return mInputs[nodeId].IsConnected();
+ mWorkflow->Connect(input, inputNodeId, *this, pinId);
}
-void WorkflowNode::ConnectOutput(int nodeId, WorkflowNode& input, int inputNodeId)
+void WorkflowNode::DisconnectOutput(uint32_t pinId)
{
- mWorkflow->Connect(input, inputNodeId, *this, nodeId);
+ mWorkflow->DisconnectBySource(*this, pinId);
}
-void WorkflowNode::DisconnectOutput(int nodeId)
+const WorkflowNode::OutputPin& WorkflowNode::GetOutputPin(uint32_t pinId) const
{
- mWorkflow->DisconnectBySource(*this, nodeId);
+ return mOutputs[pinId];
}
-bool WorkflowNode::IsOutputConnected(int nodeId) const
+size_t WorkflowNode::GetOutputPinUniqueId(uint32_t pinId) const
{
- return mOutputs[nodeId].IsConnected();
+ return mWorkflow->FabricateGlobalPinId(*this, pinId, true);
}
void WorkflowNode::Draw()
{
- for (size_t i = 0; i < mInputs.size(); ++i) {
+ for (uint32_t i = 0; i < mInputs.size(); ++i) {
auto& pin = mInputs[i];
- ImNodes::BeginPin(i, ImNodes::PinKind::Input);
+ ImNodes::BeginPin(GetInputPinUniqueId(i), ImNodes::PinKind::Input);
// TODO
ImNodes::EndPin();
}
- for (size_t i = 0; i < mOutputs.size(); ++i) {
+ for (uint32_t i = 0; i < mOutputs.size(); ++i) {
auto& pin = mOutputs[i];
- ImNodes::BeginPin(i + mInputs.size(), ImNodes::PinKind::Output);
+ ImNodes::BeginPin(GetOutputPinUniqueId(i), ImNodes::PinKind::Output);
// TODO
ImNodes::EndPin();
}
@@ -174,7 +197,7 @@ void WorkflowNode::DrawDebugInfo() const
ImGui::BeginTooltip();
ImGui::Text("Node kind: %s", FormatKind(mKind));
ImGui::Text("Node type: %s", FormatType(GetType()));
- ImGui::Text("Node ID: %llu", mId);
+ ImGui::Text("Node ID: %u", mId);
ImGui::Text("Depth: %d", mDepth);
DrawExtraDebugInfo();
ImGui::EndTooltip();
@@ -272,6 +295,14 @@ void WorkflowNode::SwapOutputPin(int a, int b)
std::swap(pinA, pinB);
}
+void WorkflowNode::OnAttach(Workflow& workflow, uint32_t newId)
+{
+}
+
+void WorkflowNode::OnDetach()
+{
+}
+
const std::vector<WorkflowConnection>& Workflow::GetConnections() const
{
return mConnections;
@@ -302,22 +333,57 @@ std::vector<std::unique_ptr<BaseValue>>& Workflow::GetConstants()
return mConstants;
}
-WorkflowConnection* Workflow::GetConnectionById(size_t id)
+WorkflowConnection* Workflow::GetConnectionById(uint32_t id)
{
return &mConnections[id];
}
-WorkflowNode* Workflow::GetStepById(size_t id)
+WorkflowNode* Workflow::GetNodeById(uint32_t id)
{
return mNodes[id].get();
}
-BaseValue* Workflow::GetConstantById(size_t id)
+BaseValue* Workflow::GetConstantById(uint32_t id)
{
return mConstants[id].get();
}
-const std::vector<std::vector<size_t>>& Workflow::GetDepthGroups() const
+Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(size_t id)
+{
+ // 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
+ // Therefore we encode one ourselves
+
+ // Global pin id format
+ // nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn Tppppppp pppppppp pppppppp pppppppp
+ // <------- (32 bits) node id -------> ^<------ (31 bits) pin id -------->
+ // | (1 bit) input (false) vs output (true)
+
+ // 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)
+
+ GlobalPinId result;
+
+ result.Node = mNodes[id >> 32].get();
+ result.PinId = (uint32_t)(id & 0x000000001FFFFFFF) - 1;
+ result.IsOutput = id >> 31;
+
+ return result;
+}
+
+size_t Workflow::FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const
+{
+ // See this->DisassembleGlobalPinId for format details and rationale
+
+ uint64_t id = 0;
+ id |= ((uint64_t)node.GetId() << 32);
+ id |= (isOutput << 31);
+ id |= ((pinId + 1) & 0x1FFFFFFF);
+
+ return id;
+}
+
+const std::vector<std::vector<uint32_t>>& Workflow::GetDepthGroups() const
{
return mDepthGroups;
}
@@ -327,7 +393,7 @@ bool Workflow::DoesDepthNeedsUpdate() const
return mDepthsDirty;
}
-void Workflow::AddStep(std::unique_ptr<WorkflowNode> step)
+void Workflow::AddNode(std::unique_ptr<WorkflowNode> step)
{
auto [storage, id] = AllocWorkflowStep();
storage = std::move(step);
@@ -336,7 +402,7 @@ void Workflow::AddStep(std::unique_ptr<WorkflowNode> step)
storage->mId = id;
}
-void Workflow::RemoveStep(size_t id)
+void Workflow::RemoveNode(uint32_t id)
{
auto& step = mNodes[id];
if (step == nullptr) return;
@@ -346,7 +412,7 @@ void Workflow::RemoveStep(size_t id)
step->mId = WorkflowNode::kInvalidId;
}
-void Workflow::RemoveConnection(size_t id)
+void Workflow::RemoveConnection(uint32_t id)
{
auto& conn = mConnections[id];
if (!conn.IsValid()) return;
@@ -358,7 +424,7 @@ void Workflow::RemoveConnection(size_t id)
mDepthsDirty = true;
}
-bool Workflow::Connect(WorkflowNode& sourceNode, int sourcePin, WorkflowNode& destinationNode, int destinationPin)
+bool Workflow::Connect(WorkflowNode& sourceNode, uint32_t sourcePin, WorkflowNode& destinationNode, uint32_t destinationPin)
{
auto& src = sourceNode.mOutputs[sourcePin];
auto& dst = destinationNode.mInputs[destinationPin];
@@ -385,7 +451,7 @@ bool Workflow::Connect(WorkflowNode& sourceNode, int sourcePin, WorkflowNode& de
return true;
}
-bool Workflow::DisconnectBySource(WorkflowNode& sourceNode, int sourcePin)
+bool Workflow::DisconnectBySource(WorkflowNode& sourceNode, uint32_t sourcePin)
{
auto& sn = sourceNode.mOutputs[sourcePin];
if (!sn.IsConnected()) return false;
@@ -401,7 +467,7 @@ bool Workflow::DisconnectBySource(WorkflowNode& sourceNode, int sourcePin)
return true;
}
-bool Workflow::DisconnectByDestination(WorkflowNode& destinationNode, int destinationPin)
+bool Workflow::DisconnectByDestination(WorkflowNode& destinationNode, uint32_t destinationPin)
{
auto& dn = destinationNode.mOutputs[destinationPin];
if (!dn.IsConnected()) return false;
@@ -436,7 +502,7 @@ Workflow::GraphUpdateResult::T Workflow::UpdateGraph()
};
std::vector<WorkingNode> workingNodes;
- std::queue<size_t> q;
+ std::queue<uint32_t> q;
// Check if all dependencies of this node is satisfied
auto CheckNodeDependencies = [&](WorkflowNode& node) -> bool {
@@ -450,8 +516,8 @@ Workflow::GraphUpdateResult::T Workflow::UpdateGraph()
workingNodes.reserve(mNodes.size());
{
- std::vector<size_t> unsatisfiedNodes;
- for (size_t i = 0; i < mNodes.size(); ++i) {
+ std::vector<uint32_t> unsatisfiedNodes;
+ for (uint32_t i = 0; i < mNodes.size(); ++i) {
auto& node = mNodes[i];
workingNodes.push_back(WorkingNode{});
@@ -506,8 +572,8 @@ Workflow::GraphUpdateResult::T Workflow::UpdateGraph()
if (processedNodes < mNodes.size()) {
// There is unreachable nodes, collect them and report to the caller
- std::vector<size_t> unreachableNodes;
- for (size_t i = 0; i < mNodes.size(); ++i) {
+ std::vector<uint32_t> unreachableNodes;
+ for (uint32_t i = 0; i < mNodes.size(); ++i) {
auto& wn = workingNodes[i];
auto& n = *mNodes[i];
@@ -526,41 +592,32 @@ Workflow::GraphUpdateResult::T Workflow::UpdateGraph()
Workflow::ReadResult Workflow::ReadFrom(std::istream& stream)
{
auto DeserializeV0 = [&]() {
- size_t connectionsStorage, nodesStorage, constantsStorage;
- stream >> connectionsStorage >> nodesStorage >> constantsStorage;
-
uint32_t connectionCount, nodeCount, constantCount;
stream >> connectionCount >> nodeCount >> constantCount;
+ mConnections.reserve(connectionCount);
for (uint32_t i = 0; i < connectionCount; ++i) {
- size_t idx;
- stream >> idx;
-
- mConnections[idx].ReadFrom(stream);
+ mConnections.emplace_back().ReadFrom(stream);
}
+ mNodes.reserve(connectionCount);
for (uint32_t i = 0; i < nodeCount; ++i) {
- size_t idx;
- stream >> idx;
-
uint32_t nKind;
stream >> nKind;
auto kind = (WorkflowNode::Kind)nKind;
- mNodes[idx] = WorkflowNode::CreateByKind(kind);
- mNodes[idx]->ReadFrom(stream);
+ mNodes.push_back(WorkflowNode::CreateByKind(kind));
+ mNodes.back()->ReadFrom(stream);
}
+ mConstants.reserve(connectionCount);
for (uint32_t i = 0; i < constantCount; ++i) {
- size_t idx;
- stream >> idx;
-
uint32_t nKind;
stream >> nKind;
auto kind = (BaseValue::Kind)nKind;
- mConstants[idx] = BaseValue::CreateByKind(kind);
- mConstants[idx]->ReadFrom(stream);
+ mConstants.push_back(BaseValue::CreateByKind(kind));
+ mConstants.back()->ReadFrom(stream);
}
};
@@ -579,6 +636,8 @@ void Workflow::WriteTo(std::ostream& stream)
// Version
stream << (uint64_t)0;
+ // TODO id compacting
+
stream << (size_t)mConnections.size();
stream << (size_t)mNodes.size();
stream << (size_t)mConstants.size();
@@ -621,7 +680,10 @@ std::pair<WorkflowConnection&, size_t> Workflow::AllocWorkflowConnection()
}
auto id = mConnections.size();
- return { mConnections.emplace_back(WorkflowConnection{}), id };
+ auto& conn = mConnections.emplace_back(WorkflowConnection{});
+ conn.Id = id;
+
+ return { conn, id };
}
std::pair<std::unique_ptr<WorkflowNode>&, size_t> Workflow::AllocWorkflowStep()
@@ -634,10 +696,7 @@ std::pair<std::unique_ptr<WorkflowNode>&, size_t> Workflow::AllocWorkflowStep()
}
auto id = mNodes.size();
- return { mNodes.emplace_back(std::unique_ptr<WorkflowNode>()), id };
-}
+ auto& node = mNodes.emplace_back(std::unique_ptr<WorkflowNode>());
-size_t Workflow::AllocUniqueId()
-{
- return mUniqueId++;
+ return { node, id };
}