implement proper port removal

This commit is contained in:
sshumakov3
2020-12-23 22:38:04 +03:00
parent 1e76b29d17
commit 89fd53116a
9 changed files with 96 additions and 48 deletions

View File

@@ -85,6 +85,10 @@ public:
NodeDataModel*
nodeDataModel() const;
Q_SIGNALS:
void
requestConnectionRemove(Connection& connection);
public Q_SLOTS: // data propagation
/// Propagates incoming data to the underlying model.
@@ -100,11 +104,11 @@ public Q_SLOTS: // data propagation
/// update the graphic part if the size of the embeddedwidget changes
/// Port added to the end.
void
onPortAdded();
onPortAdded(PortType port_type, PortIndex port_index);
/// Port removed from the end.
void
onPortRemoved();
onPortRemoved(PortType port_type, PortIndex port_index);
protected:

View File

@@ -167,10 +167,10 @@ Q_SIGNALS:
computingFinished();
void
portAdded();
portAdded(PortType port_type, PortIndex port_index);
void
portRemoved();
portRemoved(PortType port_type, PortIndex port_index);
void
visualsNeedUpdate();

View File

@@ -207,6 +207,9 @@ FlowScene::
createNode(std::unique_ptr<NodeDataModel> && dataModel)
{
auto node = detail::make_unique<Node>(std::move(dataModel));
connect(node.get(), &Node::requestConnectionRemove, this, &FlowScene::deleteConnection);
auto ngo = detail::make_unique<NodeGraphicsObject>(*this, *node);
node->setGraphicsObject(std::move(ngo));
@@ -234,6 +237,9 @@ restoreNode(QJsonObject const& nodeJson)
modelName.toLocal8Bit().data());
auto node = detail::make_unique<Node>(std::move(dataModel));
connect(node.get(), &Node::requestConnectionRemove, this, &FlowScene::deleteConnection);
auto ngo = detail::make_unique<NodeGraphicsObject>(*this, *node);
node->setGraphicsObject(std::move(ngo));

View File

@@ -220,17 +220,21 @@ onDataUpdated(PortIndex index)
void
Node::
onPortAdded()
onPortAdded(PortType port_type, PortIndex port_index)
{
// port In
const unsigned int nNewIn = _nodeDataModel->nPorts(PortType::In);
_nodeGeometry._nSources = nNewIn;
_nodeState._inConnections.resize( nNewIn );
// port Out
const unsigned int nNewOut = _nodeDataModel->nPorts(PortType::Out);
_nodeGeometry._nSinks = nNewOut;
_nodeState._outConnections.resize( nNewOut );
if (port_type == PortType::In)
{
const unsigned int nNewIn = _nodeDataModel->nPorts(PortType::In);
_nodeGeometry._nSources = nNewIn;
_nodeState._inConnections.resize(nNewIn);
}
else if (port_type == PortType::Out)
{
const unsigned int nNewOut = _nodeDataModel->nPorts(PortType::Out);
_nodeGeometry._nSinks = nNewOut;
_nodeState._outConnections.resize( nNewOut );
}
//Recalculate the nodes visuals. A data change can result in the node taking more space than before, so this forces a recalculate+repaint on the affected node
auto widget = _nodeDataModel->embeddedWidget();
@@ -238,29 +242,61 @@ onPortAdded()
if (widget)
widget->adjustSize();
_nodeGraphicsObject->setGeometryChanged();
_nodeGeometry.recalculateSize();
_nodeGraphicsObject->update();
recalculateVisuals();
}
void
Node::
onPortRemoved()
onPortRemoved(PortType port_type, PortIndex port_index)
{
// port In
const unsigned int nNewIn = _nodeDataModel->nPorts(PortType::In);
_nodeGeometry._nSources = nNewIn;
_nodeState._inConnections.resize( nNewIn );
// \todo Remove the lost connections.
// port Out
const unsigned int nNewOut = _nodeDataModel->nPorts(PortType::Out);
_nodeGeometry._nSinks = nNewOut;
_nodeState._outConnections.resize( nNewOut );
// \todo Remove the lost connections.
if (port_type == PortType::In)
{
auto& in_connections = _nodeState._inConnections[port_index];
std::vector<Connection*> connections_to_remove;
connections_to_remove.reserve(in_connections.size());
for (auto& it : in_connections)
{
connections_to_remove.push_back(it.second);
}
for (auto connection : connections_to_remove)
{
Q_EMIT requestConnectionRemove(*connection);
}
_nodeGeometry._nSources = _nodeDataModel->nPorts(PortType::In);
if (in_connections.empty())
_nodeState._inConnections.erase(_nodeState._inConnections.begin() + port_index);
}
else if (port_type == PortType::Out)
{
auto& out_connections = _nodeState._outConnections[port_index];
std::vector<Connection*> connections_to_remove;
connections_to_remove.reserve(out_connections.size());
for (auto& it : out_connections)
{
connections_to_remove.push_back(it.second);
}
for (auto connection : connections_to_remove)
{
Q_EMIT requestConnectionRemove(*connection);
}
const unsigned int nNewOut = _nodeDataModel->nPorts(PortType::Out);
_nodeGeometry._nSinks = nNewOut;
if (out_connections.empty())
_nodeState._outConnections.erase(_nodeState._outConnections.begin() + port_index);
}
auto widget = _nodeDataModel->embeddedWidget();

View File

@@ -210,7 +210,7 @@ void BaseNode::deletePort(PortType port_type, PortIndex port_index)
{
_in_ports.erase(_in_ports.begin() + port_index);
}
emit portRemoved();
emit portRemoved(port_type, port_index);
}
void BaseNode::deleteDefaultWidget(PortType port_type, PortIndex port_index)

View File

@@ -89,9 +89,10 @@ void LogicBeginNode::restore(const QJsonObject& json_obj)
{
addPort<AnyData>(PortType::Out, "Any", true, ConnectionPolicy::One);
addDefaultWidget(new QLabel(&_embedded_widget), PortType::Out, 2 + i);
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
emit portAdded();
}
@@ -121,7 +122,7 @@ void LogicBeginNode::outputConnectionCreated(const Connection& connection)
{
addPort<AnyData>(PortType::Out, "Any", true, ConnectionPolicy::One);
addDefaultWidget(new QLabel(&_embedded_widget), PortType::Out, _out_ports.size() - 1);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
_embedded_widget.adjustSize();
@@ -153,7 +154,7 @@ void LogicBeginNode::outputConnectionDeleted(const Connection& connection)
{
addPort<AnyData>(PortType::Out, "Any", true, ConnectionPolicy::One);
addDefaultWidget(new QLabel(&_embedded_widget), PortType::Out, _out_ports.size() - 1);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
break;
}
}
@@ -162,7 +163,7 @@ void LogicBeginNode::outputConnectionDeleted(const Connection& connection)
{
addPort<AnyData>(PortType::Out, "Any", true, ConnectionPolicy::One);
addDefaultWidget(new QLabel(&_embedded_widget), PortType::Out, _out_ports.size() - 1);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
emit visualsNeedUpdate();
@@ -192,7 +193,7 @@ void LogicBeginNode::restorePostConnection(const QJsonObject& json_obj)
{
addPort<AnyData>(PortType::Out, "Any", true, ConnectionPolicy::One);
addDefaultWidget(new QLabel(&_embedded_widget), PortType::Out, _out_ports.size() - 1);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
break;
}

View File

@@ -57,7 +57,7 @@ void LogicChainNode::outputConnectionCreated(const Connection& connection)
if (_out_ports[_out_ports.size() - 1].connected)
{
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
}
@@ -74,7 +74,7 @@ void LogicChainNode::outputConnectionDeleted(const Connection& connection)
else
{
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
break;
}
}
@@ -82,7 +82,7 @@ void LogicChainNode::outputConnectionDeleted(const Connection& connection)
if (_out_ports.size() == 1 && _out_ports[0].connected)
{
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
}
@@ -103,9 +103,10 @@ void LogicChainNode::restore(const QJsonObject& json_obj)
for (int i = 0; i < json_obj["n_dynamic_ports"].toInt(); ++i)
{
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
emit portAdded();
}
void LogicChainNode::restorePostConnection(const QJsonObject& json_obj)
@@ -120,7 +121,7 @@ void LogicChainNode::restorePostConnection(const QJsonObject& json_obj)
else
{
addPort<LogicData>(PortType::Out, "Logic", true, ConnectionPolicy::One);
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
break;
}
}

View File

@@ -178,14 +178,14 @@ void LogicProcedureNode::restore(const QJsonObject& json_obj)
{
addPort<LogicData>(PortType::In, json_obj[("in_port_" + std::to_string(i + 2) + "_caption").c_str()].toString(), true);
_in_ports[_in_ports.size() - 1].data_type = TypeFactory::create(json_obj[("in_port_" + std::to_string(i + 2)).c_str()].toString().toStdString())->instantiate();
emit portAdded();
emit portAdded(PortType::In, _in_ports.size() - 1);
}
for (int i = 0; i < json_obj["n_dynamic_out_ports"].toInt(); ++i)
{
addPort<LogicData>(PortType::Out, json_obj[("out_port_" + std::to_string(i + 1) + "_caption").c_str()].toString(), true);
_out_ports[_out_ports.size() - 1].data_type = TypeFactory::create(json_obj[("out_port_" + std::to_string(i + 1)).c_str()].toString().toStdString())->instantiate();
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
}
@@ -239,7 +239,7 @@ void LogicProcedureNode::setProcedure(const QString& path)
_scene = gCurrentContext->getScene(QDir("./scripts/").absoluteFilePath(_scene_path), this);
if (_scene)
if (!_scene)
{
setValidationState(NodeValidationState::Error);
setValidationMessage("Error: Scene loading failed.");
@@ -269,7 +269,7 @@ void LogicProcedureNode::setProcedure(const QString& path)
addPort<LogicData>(PortType::In, port.caption, true);
_in_ports[_in_ports.size() - 1].data_type = port.data_type->instantiate();
emit portAdded();
emit portAdded(PortType::In, _in_ports.size() - 1);
}
auto return_node = _scene->getReturnNode();
@@ -286,7 +286,7 @@ void LogicProcedureNode::setProcedure(const QString& path)
addPort<LogicData>(PortType::Out, port.caption, true);
_out_ports[_out_ports.size() - 1].data_type = port.data_type->instantiate();
emit portAdded();
emit portAdded(PortType::Out, _out_ports.size() - 1);
}
}

View File

@@ -48,9 +48,9 @@ void LogicReturnNode::restore(const QJsonObject& json_obj)
for (int i = 0; i < json_obj["n_dynamic_ports"].toInt(); ++i)
{
addPort<AnyData>(PortType::In, "Any", true);
emit portAdded(PortType::In, _in_ports.size() - 1);
}
emit portAdded();
}
NodeValidationState LogicReturnNode::validate()
@@ -108,7 +108,7 @@ void LogicReturnNode::inputConnectionCreated(const Connection& connection)
if (_in_ports[_in_ports.size() - 1].connected)
{
addPort<AnyData>(PortType::In, "Any", true);
emit portAdded();
emit portAdded(PortType::In, _in_ports.size() - 1);
}
}
@@ -132,7 +132,7 @@ void LogicReturnNode::inputConnectionDeleted(const Connection& connection)
else
{
addPort<AnyData>(PortType::In, "Any", true);
emit portAdded();
emit portAdded(PortType::In, _in_ports.size() - 1);
break;
}
}
@@ -140,7 +140,7 @@ void LogicReturnNode::inputConnectionDeleted(const Connection& connection)
if (_in_ports[_in_ports.size() - 1].connected)
{
addPort<AnyData>(PortType::In, "Any", true);
emit portAdded();
emit portAdded(PortType::In, _in_ports.size() - 1);
}
}