#include "Evaluation.hpp" #include const char* WorkflowEvaluationError::FormatMessageType(enum MessageType messageType) { switch (messageType) { case Error: return "Error"; case Warning: return "Warning"; } } const char* WorkflowEvaluationError::FormatPinType(enum PinType pinType) { switch (pinType) { case NoPin: return nullptr; case InputPin: return "Input pin"; case OutputPin: return "Output pin"; } } std::string WorkflowEvaluationError::Format() const { // TODO convert to std::format std::string result; result += FormatMessageType(this->Type); result += " at "; result += NodeId; if (auto pinText = FormatPinType(this->PinType)) { result += "/"; result += pinText; result += " "; result += PinId; } result += ": "; result += this->Message; return result; } struct WorkflowEvaluationContext::RuntimeNode { enum EvaluationStatus { ST_Unevaluated, ST_Success, ST_Failed, }; EvaluationStatus Status = ST_Unevaluated; }; struct WorkflowEvaluationContext::RuntimeConnection { std::unique_ptr Value; bool IsAvailableValue() const { return Value != nullptr; } }; WorkflowEvaluationContext::WorkflowEvaluationContext(Workflow& workflow) : mWorkflow{ &workflow } { mRuntimeNodes.resize(workflow.mNodes.size()); mRuntimeConnections.resize(workflow.mConnections.size()); } BaseValue* WorkflowEvaluationContext::GetConnectionValue(size_t id, bool constant) { if (constant) { return mWorkflow->GetConstantById(id); } else { return mRuntimeConnections[id].Value.get(); } } BaseValue* WorkflowEvaluationContext::GetConnectionValue(const WorkflowNode::InputPin& inputPin) { if (inputPin.IsConnected()) { return GetConnectionValue(inputPin.Connection, inputPin.IsConstantConnection()); } else { return nullptr; } } void WorkflowEvaluationContext::SetConnectionValue(size_t id, std::unique_ptr value) { mRuntimeConnections[id].Value = std::move(value); } void WorkflowEvaluationContext::SetConnectionValue(const WorkflowNode::OutputPin& outputPin, std::unique_ptr value) { if (outputPin.IsConnected()) { SetConnectionValue(outputPin.Connection, std::move(value)); } } void WorkflowEvaluationContext::Run() { int evaluatedCount = 0; int erroredCount = 0; for (auto& depthGroup : mWorkflow->GetDepthGroups()) { for (size_t idx : depthGroup) { auto& rn = mRuntimeNodes[idx]; auto& n = *mWorkflow->mNodes[idx]; // TODO int preEvalErrors = mErrors.size(); n.Evaluate(*this); if (preEvalErrors != mErrors.size()) { erroredCount++; } else { evaluatedCount++; } } } for (size_t i = 0; i < mRuntimeNodes.size(); ++i) { auto& rn = mRuntimeNodes[i]; auto& n = *mWorkflow->mNodes[i]; if (n.GetType() == WorkflowNode::OutputType) { // TODO record outputs } } } void WorkflowEvaluationContext::ReportError(std::string message, const WorkflowNode& node, int pinId, bool inputPin) { mErrors.push_back(WorkflowEvaluationError{ .Message = std::move(message), .NodeId = node.GetId(), .PinId = pinId, .PinType = inputPin ? WorkflowEvaluationError::InputPin : WorkflowEvaluationError::OutputPin, .Type = WorkflowEvaluationError::Error, }); } void WorkflowEvaluationContext::ReportError(std::string message, const WorkflowNode& node) { mErrors.push_back(WorkflowEvaluationError{ .Message = std::move(message), .NodeId = node.GetId(), .PinId = -1, .PinType = WorkflowEvaluationError::NoPin, .Type = WorkflowEvaluationError::Error, }); } void WorkflowEvaluationContext::ReportWarning(std::string message, const WorkflowNode& node, int pinId, bool inputPin) { mErrors.push_back(WorkflowEvaluationError{ .Message = std::move(message), .NodeId = node.GetId(), .PinId = pinId, .PinType = inputPin ? WorkflowEvaluationError::InputPin : WorkflowEvaluationError::OutputPin, .Type = WorkflowEvaluationError::Warning, }); } void WorkflowEvaluationContext::ReportWarning(std::string message, const WorkflowNode& node) { mErrors.push_back(WorkflowEvaluationError{ .Message = std::move(message), .NodeId = node.GetId(), .PinId = -1, .PinType = WorkflowEvaluationError::NoPin, .Type = WorkflowEvaluationError::Warning, }); }