Skip to content

Commit

Permalink
Added FibonacciModel in calculator example showing dynamic output ports
Browse files Browse the repository at this point in the history
  • Loading branch information
Daguerreo committed Apr 26, 2021
1 parent 19813ec commit 69149b3
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 2 deletions.
150 changes: 150 additions & 0 deletions examples/calculator/FibonacciModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#include "FibonacciModel.hpp"

#include <nodes/Connection>

int fibo(int n)
{
if(n<=1) return 1;

int fibo = 0;
int fibo1 = 1;
int fibo2 = 1;
int i = 1;

while (i<n) {
fibo = fibo1 + fibo2;
++i;
fibo2 = fibo1;
fibo1 = fibo;
}

return fibo;
}

FibonacciModel::FibonacciModel()
: NodeDataModel(),
_indexCounter(1)
{
}

unsigned int
FibonacciModel::
nPorts(QtNodes::PortType portType) const
{
if (portType == PortType::In)
return 0;
else
return std::max(1, _indexCounter);
}

bool
FibonacciModel::
hasDynamicPorts(QtNodes::PortType portType) const
{
if(portType == PortType::Out)
return true;

return false;
}

QtNodes::NodeDataType
FibonacciModel::
dataType(QtNodes::PortType, QtNodes::PortIndex) const
{
return DecimalData().type();
}

std::shared_ptr<QtNodes::NodeData>
FibonacciModel::
outData(QtNodes::PortIndex port)
{
return std::make_shared<DecimalData>(fibo(port));
}

void
FibonacciModel::
setInData(std::shared_ptr<QtNodes::NodeData>, QtNodes::PortIndex)
{
}

QString
FibonacciModel::
caption() const
{
return QStringLiteral("Fibonacci");
}

bool
FibonacciModel::
portCaptionVisible(QtNodes::PortType, QtNodes::PortIndex) const
{
return true;
}

QString
FibonacciModel::
portCaption(QtNodes::PortType, QtNodes::PortIndex portIndex) const
{
return QString("Fibo %1").arg(portIndex);
}

QString
FibonacciModel::
name() const
{
return QStringLiteral("Fibonacci");
}

QtNodes::NodeValidationState
FibonacciModel::
validationState() const
{
return _modelValidationState;
}

QString
FibonacciModel::
validationMessage() const
{
return _modelValidationError;
}

void FibonacciModel::restore(const QJsonObject& obj)
{
int out = obj["dynamic_outputs"].toInt();
if(out > 1){
_indexCounter = out;
}
}

void FibonacciModel::outputConnectionCreated(const QtNodes::Connection& c)
{
auto outIndex = static_cast<int>(c.getPortIndex(QtNodes::PortType::Out));

// Create a new port only if the last port is connected and the connection is completed
if (outIndex == _indexCounter-1 && c.complete()){
++_indexCounter;
Q_EMIT portAdded(PortType::Out, _indexCounter-1);
}
}

void FibonacciModel::outputConnectionDeleted(const QtNodes::Connection& c)
{
auto outIndex = static_cast<int>(c.getPortIndex(QtNodes::PortType::Out));

// outIndex >= 0 ---> dynamic remove only for ports exceding 0
// !c.complete() ---> port is removed only if connection is removed e and mouse released
// outIndex != _indexCounter-1 --> if you start a connection from the last port but do not connect it
// the connection is destroyed as incomplete, but the port must not be removed because that
// port is already the last one

if ((outIndex >= 0) && (!c.complete()) && (outIndex != _indexCounter-1)){
Q_EMIT portRemoved(PortType::Out, outIndex);
--_indexCounter;

// Recalculate ports
for(int i = outIndex; i<_indexCounter; ++i){
Q_EMIT dataUpdated(i);
}
}
}
78 changes: 78 additions & 0 deletions examples/calculator/FibonacciModel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#pragma once

#include <nodes/NodeDataModel>
#include <nodes/Connection>

#include "DecimalData.hpp"

using QtNodes::PortType;
using QtNodes::PortIndex;
using QtNodes::NodeData;
using QtNodes::NodeDataType;
using QtNodes::NodeDataModel;
using QtNodes::NodeValidationState;

class FibonacciModel : public NodeDataModel
{
Q_OBJECT

public:
FibonacciModel();

unsigned int
nPorts(PortType portType) const override;

bool
hasDynamicPorts(PortType portType) const override;

NodeDataType
dataType(PortType portType, PortIndex portIndex) const override;

std::shared_ptr<NodeData>
outData(PortIndex port) override;

void
setInData(std::shared_ptr<NodeData> data, PortIndex portIndex) override;

public:

QString
caption() const override;

bool
portCaptionVisible(PortType portType, PortIndex portIndex) const override;

QString
portCaption(PortType portType, PortIndex portIndex) const override;

QString
name() const override;

public:

QWidget *
embeddedWidget() override { return nullptr; }

NodeValidationState
validationState() const override;

QString
validationMessage() const override;

private:

void
restore(const QJsonObject& obj) override;

void
outputConnectionCreated(const QtNodes::Connection& c) override;

void
outputConnectionDeleted(const QtNodes::Connection& c) override;

private:
int _indexCounter;

NodeValidationState _modelValidationState = NodeValidationState::Warning;
QString _modelValidationError = QString("Missing or incorrect inputs");
};
7 changes: 5 additions & 2 deletions examples/calculator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "AccumulatorModel.hpp"
#include "MinModel.hpp"
#include "MaxModel.hpp"
#include "FibonacciModel.hpp"
#include "Converters.hpp"

using QtNodes::DataModelRegistry;
Expand Down Expand Up @@ -49,9 +50,11 @@ registerDataModels()

ret->registerModel<ModuloModel>("Operators");

ret->registerModel<MinModel>("Operators");
ret->registerModel<MinModel>("Special");

ret->registerModel<MaxModel>("Operators");
ret->registerModel<MaxModel>("Special");

ret->registerModel<FibonacciModel>("Special");

ret->registerTypeConverter(std::make_pair(DecimalData().type(),
IntegerData().type()),
Expand Down

0 comments on commit 69149b3

Please sign in to comment.