fix a few issues with breaking, start work on dynamic nodes

This commit is contained in:
sshumakov3
2020-12-08 22:25:41 +03:00
parent 43949ac071
commit 3ce8e2da32
9 changed files with 169 additions and 45 deletions

View File

@@ -34,11 +34,6 @@ NodeValidationState LogicBreakNode::validate()
setValidationState(NodeValidationState::Error);
setValidationMessage("Error: Failed to evaluate logic input");
_out_ports[0].out_value = std::make_shared<LogicData>(false);
_out_ports[1].out_value = std::make_shared<LogicData>(false);
Q_EMIT dataUpdated(0);
Q_EMIT dataUpdated(1);
setLogicBranchToExecute(-1);
}

View File

@@ -26,7 +26,7 @@ namespace noggit
void compute() override;
NodeValidationState validate() override;
bool doBreak() { return _do_break; };
bool setDoBreak(bool state) { _do_break = state; };
void setDoBreak(bool state) { _do_break = state; };
private:
bool _do_break = false;

View File

@@ -0,0 +1,42 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#include "LogicChainNode.hpp"
#include "BaseNode.inl"
#include "Data/GenericData.hpp"
#include <vector>
using namespace noggit::Red::PresetEditor::Nodes;
LogicChainNode::LogicChainNode()
: LogicNodeBase()
{
setName("LogicChainNode");
setCaption("Chain");
_validation_state = NodeValidationState::Valid;
addPort<LogicData>(PortType::In, "Logic", true);
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
}
void LogicChainNode::compute()
{
int count = 0;
for (auto& port : _out_ports)
{
_out_ports[count].out_value = std::make_shared<LogicData>(true);
count++;
}
}
NodeValidationState LogicChainNode::validate()
{
return BaseNode::validate();
}
void LogicChainNode::outputConnectionCreated(const Connection& connection)
{
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
}

View File

@@ -0,0 +1,40 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#ifndef NOGGIT_LOGICCHAINNODE_HPP
#define NOGGIT_LOGICCHAINNODE_HPP
#include "LogicNodeBase.hpp"
using QtNodes::PortType;
using QtNodes::PortIndex;
using QtNodes::NodeData;
using QtNodes::NodeDataType;
using QtNodes::NodeDataModel;
using QtNodes::NodeValidationState;
namespace noggit
{
namespace Red::PresetEditor::Nodes
{
class LogicChainNode : public LogicNodeBase
{
Q_OBJECT
public:
LogicChainNode();
void compute() override;
NodeValidationState validate() override;
public Q_SLOTS:
void outputConnectionCreated(Connection const& connection) override;
private:
};
}
}
#endif //NOGGIT_LOGICCHAINNODE_HPP

View File

@@ -10,12 +10,11 @@ LogicIfNode::LogicIfNode()
{
setName("LogicIfNode");
setCaption("Branch");
_validation_state = NodeValidationState::Valid;
addPort<LogicData>(PortType::In, "Logic", true);
addPort<BooleanData>(PortType::In, "Boolean", true);
addPort<LogicData>(PortType::Out, "Then", true, ConnectionPolicy::One);
addPort<LogicData>(PortType::Out, "Else", true, ConnectionPolicy::One);
addPort<LogicData>(PortType::Out, "True", true, ConnectionPolicy::One);
addPort<LogicData>(PortType::Out, "False", true, ConnectionPolicy::One);
setNLogicBranches(2);
}

View File

@@ -2,6 +2,7 @@
#include "../BaseNode.hpp"
#include "../LogicNodeBase.hpp"
#include "../LogicBreakNode.hpp"
#include "../Data/GenericData.hpp"
#include <stdexcept>
@@ -29,16 +30,38 @@ void LogicBranch::executeNode(Node* node, Node* source_node)
model->compute();
model->setComputed(true);
// Handle loop breaking
if(model->isLogicNode()
&& static_cast<LogicNodeBase*>(model)->name() == "LogicBreakNode"
&& static_cast<LogicBreakNode*>(model)->doBreak())
{
static_cast<LogicNodeBase*>(getCurrentLoop()->nodeDataModel())->setIterationIndex(-1);
static_cast<LogicBreakNode*>(model)->setDoBreak(false);
auto break_node = static_cast<LogicBreakNode*>(model);
if (_loop_stack.empty())
{
break_node->setValidationState(NodeValidationState::Error);
break_node->setValidationMessage("Error: break is outside any loop.");
}
else
{
Node* current_loop_node = getCurrentLoop();
static_cast<LogicNodeBase*>(getCurrentLoop()->nodeDataModel())->setIterationIndex(-1);
break_node->setDoBreak(false);
markNodesComputed(current_loop_node, true);
}
}
// Handle dependant nodes
for (int i = 0; i < model->nPorts(PortType::Out); ++i)
{
// we do not process dependant data nodes here, discard them
if (model->dataType(PortType::Out, i).id != "logic")
continue;
// discard logic branches not suitable for evaluation
if (!static_cast<LogicData*>(model->outData(i).get())->value())
continue;
auto const& connections = nodeState.connections(PortType::Out, i);
for (auto const& pair : connections)
@@ -49,32 +72,31 @@ void LogicBranch::executeNode(Node* node, Node* source_node)
continue;
auto connected_model = static_cast<BaseNode*>(connected_node->nodeDataModel());
if (connected_model->isLogicNode())
executeNodeLeaves(connected_node, node); // Execute data node leaves
if (connected_model->validate() != NodeValidationState::Error)
{
executeNodeLeaves(connected_node, node);
if (connected_model->validate() != NodeValidationState::Error)
auto logic_model = static_cast<LogicNodeBase*>(connected_node->nodeDataModel());
if (logic_model->isIterable()) // handle iteration nodes
{
auto logic_model = static_cast<LogicNodeBase*>(connected_node->nodeDataModel());
if (logic_model->isIterable())
{
setCurrentLoop(connected_node);
int it_index = logic_model->getIterationindex();
while (it_index >= 0 && it_index < logic_model->getNIteraitons())
{
markNodesComputed(connected_node, false);
executeNode(connected_node, node);
logic_model->setComputed(true);
it_index = logic_model->getIterationindex();
}
unsetCurrentLoop();
}
else
setCurrentLoop(connected_node);
int it_index = logic_model->getIterationindex();
while (it_index >= 0 && it_index < logic_model->getNIteraitons())
{
markNodesComputed(connected_node, false);
executeNode(connected_node, node);
logic_model->setComputed(true);
it_index = logic_model->getIterationindex();
}
unsetCurrentLoop();
}
else // haandle regular nodes
{
executeNode(connected_node, node);
}
}
}
}

View File

@@ -29,7 +29,7 @@ namespace noggit
void markNodeLeavesComputed(Node* start_node, Node* source_node, bool state);
void setCurrentLoop(Node* node) { _loop_stack.push(node); };
void unsetCurrentLoop() { _loop_stack.pop(); };
Node* getCurrentLoop() { return _loop_stack.top(); };
Node* getCurrentLoop() { return _loop_stack.empty() ? nullptr : _loop_stack.top(); };
void execute();
private:

View File

@@ -15,6 +15,7 @@
#include <noggit/Red/PresetEditor/Nodes/LogicBreakNode.hpp>
#include <noggit/Red/PresetEditor/Nodes/PrintNode.hpp>
#include <noggit/Red/PresetEditor/Nodes/ForLoopNode.hpp>
#include <noggit/Red/PresetEditor/Nodes/LogicChainNode.hpp>
#include <noggit/Red/PresetEditor/Nodes/BaseNode.hpp>
#include <noggit/Red/PresetEditor/Nodes/Data/GenericTypeConverter.hpp>
#include <noggit/Red/PresetEditor/Nodes/Scene/NodeScene.hpp>
@@ -37,6 +38,7 @@ using noggit::Red::PresetEditor::Nodes::LogicBeginNode;
using noggit::Red::PresetEditor::Nodes::PrintNode;
using noggit::Red::PresetEditor::Nodes::ForLoopNode;
using noggit::Red::PresetEditor::Nodes::LogicBreakNode;
using noggit::Red::PresetEditor::Nodes::LogicChainNode;
using noggit::Red::PresetEditor::Nodes::BaseNode;
using noggit::Red::PresetEditor::Nodes::NodeScene;
@@ -59,6 +61,7 @@ registerDataModels()
ret->registerModel<LogicIfNode>("Logic//Flow");
ret->registerModel<ForLoopNode>("Logic//Flow");
ret->registerModel<LogicBreakNode>("Logic//Flow");
ret->registerModel<LogicChainNode>("Logic//Flow");
ret->registerModel<PrintNode>("Functions//Generic");
ret->REGISTER_TYPE_CONVERTER(Decimal, Integer);
@@ -232,18 +235,21 @@ PresetEditorWidget::PresetEditorWidget(QWidget *parent)
connect(ui->executeButton, &QPushButton::clicked
, [this, scene]()
{
/*
scene->iterateOverNodeDataDependentOrder(
[](NodeDataModel* model)
{
reinterpret_cast<BaseNode*>(model)->compute();
}
);
*/
scene->execute();
scene->execute();
});
connect(ui->loadButton, &QPushButton::clicked
, [this, scene]()
{
scene->load();
});
connect(ui->saveButton, &QPushButton::clicked
, [this, scene]()
{
scene->save();
});
}
void PresetEditorWidget::setupConnectsCommon()

View File

@@ -265,6 +265,12 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignTop">
<widget class="QToolBox" name="toolBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>1</number>
</property>
@@ -371,9 +377,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>76</height>
<y>-36</y>
<width>361</width>
<height>112</height>
</rect>
</property>
<attribute name="label">
@@ -387,6 +393,20 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loadButton">
<property name="text">
<string>Load</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>