Newer
Older
if ((oldOIn.size() == 1) && (inputParents[0].first)) {
for (std::size_t i = 0; i < newOIn.size(); ++i) {
inputParents[0].first -> addChild(newOIn[i].first, inputParents[0].second, newOIn[i].second);
for (std::size_t i = 0; i < oldOIn.size(); ++i) {

Maxence Naud
committed
if (inputParents[i].first) {
inputParents[i].first -> addChild(newOIn[0].first, inputParents[i].second, newOIn[0].second);

Maxence Naud
committed
}
for (std::size_t o = 0; o < oldOOut.size(); ++o) {
for (const auto& child : outputChildren[o]) {
newOOut[o].first -> addChild(child.first, newOOut[o].second, child.second);
else {
for (const auto& nodePtr : oldNodes) {
}
for (const auto& nodePtr : newNodes) {
}
return false;
}

Maxence Naud
committed
auto oldGOutputs = oldGraph->outputNodes();

Maxence Naud
committed
for (const auto& nodePtr : oldNodes) {
bool removeFromGraphs = true;
if (std::find(oldGOutputs.cbegin(), oldGOutputs.cend(), nodePtr) == oldGOutputs.cend()) {
for (const auto& chPtr : nodePtr->getChildren()) {
if (oldNodes.find(chPtr) == oldNodes.cend()) {
removeFromGraphs = false;
}
}
}
if (removeFromGraphs) {
for (const auto& g : commonGraphViews) {
g -> remove(nodePtr, false);
g -> updateInputsOutputsDelete(nodePtr);
}
nodePtr -> resetConnections(true);
}
}
for (const auto& nodePtr : newNodes) {
for (const auto& g : commonGraphViews) {
g -> add(nodePtr);
for (const auto& nodePtr : oldNodes) {
for (const auto& nodePtr : newNodes) {
return true;
}
void Aidge::GraphView::updateInputsOutputs() {
for (auto node : mNodes) {
updateInputsOutputsNew(node);
}
}
void Aidge::GraphView::updateInputsOutputsNew(std::shared_ptr<Node> newNode) {
// Can be called several times with the same node, e.g. when addChild() is
// called on a node already part of the GraphView. In this case, inputs/outputs
// need to be updated!
std::vector<std::pair<NodePtr, IOIndex_t>>::const_iterator newInputsInsertionPoint = mInputNodes.cend();
// Remove inputs that are not input anymore because connected to newNode
for (auto orderedChilds : newNode->getOrderedChildren()) {
for (auto ch_ptr : orderedChilds) {
// Check that newNode child is in current GraphView
if (mNodes.find(ch_ptr) != mNodes.cend()) {
for (const std::shared_ptr<Node>& pa_ptr : ch_ptr->getParents()) {
// If newNode is connected to it
if (pa_ptr == newNode) {
const auto val = std::make_pair(ch_ptr, inputIdx);
const auto iter = std::find(mInputNodes.cbegin(), mInputNodes.cend(), val);
// Check that it was not already the case (if node UPDATE)
if (iter != mInputNodes.cend()) { // newNode is linked to an actual inputNode to an input connection
// The first old (removed) input becomes the insertion point for newNode GraphView inputs
if (std::distance(newInputsInsertionPoint, iter) <= 0) {
newInputsInsertionPoint = mInputNodes.erase(iter);
}
else {
mInputNodes.erase(iter);
}
}
}
++inputIdx;
}
}
}
}
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
// Manage newNode parents
// Check if any input connection is an input for the GraphView
IOIndex_t inputIdx = 0U;
for (const std::shared_ptr<Node>& pa_ptr : newNode->getParents()) {
const auto val = std::make_pair(newNode, inputIdx);
const auto it = std::find(mInputNodes.cbegin(), mInputNodes.cend(), val);
if ((pa_ptr == nullptr) ||
(mNodes.find(pa_ptr) == mNodes.cend())) {
// Parent doesn't exist || Parent not in the graph
if (it == mInputNodes.cend()) {
// If node's inputs are inputs for the GraphView: add them to the input list
// Addition rule:
// - Inputs addition order follows node inputs order
// - Inputs are inserted at the position of the first input removed
newInputsInsertionPoint = mInputNodes.insert(newInputsInsertionPoint, val);
newInputsInsertionPoint = std::next(newInputsInsertionPoint);
}
} else if (it != mInputNodes.cend()) {
// Parent already in the graph SO edge is not an input anymore for the graph
mInputNodes.erase(it);
}
++inputIdx;
std::vector<std::pair<NodePtr, IOIndex_t>>::const_iterator newOutputsInsertionPoint = mOutputNodes.cend();
// Remove outputs that are not output anymore because connected to newNode
for (const std::shared_ptr<Node>& parent : newNode->getParents()) {
// Check that newNode parent is in current GraphView
if (mNodes.find(parent) != mNodes.cend()) {
for (auto orderedChilds : parent->getOrderedChildren()) {
for (auto ch_ptr : orderedChilds) {
// If newNode is connected to it
if (ch_ptr == newNode) {
const auto val = std::make_pair(parent, outputIdx);
const auto iter = std::find(mOutputNodes.cbegin(), mOutputNodes.cend(), val);
if (iter != mOutputNodes.cend()) {
// The first old (removed) output becomes the insertion point for newNode GraphView outputs
if (std::distance(newOutputsInsertionPoint, iter) <= 0) {
newOutputsInsertionPoint = mOutputNodes.erase(iter);
}
else {
mOutputNodes.erase(iter);
}
}
}
}
// Check if node outputs are outputs for the GraphView and add them to the output list if so

Maxence Naud
committed
for (const auto& orderedChilds : newNode->getOrderedChildren()) {

Maxence Naud
committed
for (const auto& ch_ptr : orderedChilds) {
if (mNodes.find(ch_ptr) != mNodes.cend()) {
if (noInsideConnection) {
const auto val = std::make_pair(newNode, outputIdx);
// Output may be already be present (see addChild() with a node already in GraphView)

Maxence Naud
committed
if (std::find(mOutputNodes.cbegin(), mOutputNodes.cend(), val) == mOutputNodes.cend()) {
newOutputsInsertionPoint = mOutputNodes.insert(newOutputsInsertionPoint, val);
newOutputsInsertionPoint = std::next(newOutputsInsertionPoint);
}
}
++outputIdx;
}
}
void Aidge::GraphView::updateInputsOutputsDelete(std::shared_ptr<Node> deletedNode) {
std::vector<std::pair<NodePtr, IOIndex_t>>::const_iterator newInputsInsertionPoint = mInputNodes.cend();
// Check if node inputs were inputs for the GraphView and remove them from the list if so
for (IOIndex_t inputIdx = 0; inputIdx < deletedNode->getParents().size(); ++inputIdx) {
const auto iter = std::find(mInputNodes.cbegin(), mInputNodes.cend(), val);
if (iter != mInputNodes.cend()) {
// The first old (removed) input becomes the insertion point for new GraphView inputs
if (std::distance(newInputsInsertionPoint, iter) <= 0) {
newInputsInsertionPoint = mInputNodes.erase(iter);
}
else {
mInputNodes.erase(iter);
}
}
}
// Add child node inputs that become GraphView input following the removal of the node
// Inputs addition order follows deletedNode outputs order
for (auto orderedChilds : deletedNode->getOrderedChildren()) {
for (auto ch_ptr : orderedChilds) {
// Check that deletedNode child is in current GraphView
if (mNodes.find(ch_ptr) != mNodes.cend()) {
for (const std::shared_ptr<Node>& pa_ptr : ch_ptr->getParents()) {
// If newNode was connected to it
if (pa_ptr == deletedNode) {
const auto val = std::make_pair(ch_ptr, inputIdx);
if (std::find(mInputNodes.cbegin(), mInputNodes.cend(), val) == mInputNodes.cend()) {
newInputsInsertionPoint = mInputNodes.insert(newInputsInsertionPoint, val);
newInputsInsertionPoint = std::next(newInputsInsertionPoint);
}
std::vector<std::pair<NodePtr, IOIndex_t>>::const_iterator newOutputsInsertionPoint = mOutputNodes.cend();
// Check if node outputs were outputs for the GraphView and remove them from the list if so
for (IOIndex_t outputIdx = 0; outputIdx < deletedNode->getOrderedChildren().size(); ++outputIdx) {
const auto val = std::make_pair(deletedNode, outputIdx);
const auto iter = std::find(mOutputNodes.cbegin(), mOutputNodes.cend(), val);
if (iter != mOutputNodes.cend()) {
// The first old (removed) output becomes the insertion point for newNode GraphView outputs
if (std::distance(newOutputsInsertionPoint, iter) <= 0) {
newOutputsInsertionPoint = mOutputNodes.erase(iter);
}
else {
mOutputNodes.erase(iter);
}
}
}
// Add parent node outputs that become GraphView output following the removal of the node
// Outputs addition order follows deletedNode inputs order
for (const std::shared_ptr<Node>& parent : deletedNode->getParents()) {
if (mNodes.find(parent) != mNodes.end()) {
IOIndex_t outputIdx = 0;
for (auto orderedChilds : parent->getOrderedChildren()) {
bool noInsideConnection = true;
for (auto ch_ptr : orderedChilds) {
if (mNodes.find(ch_ptr) != mNodes.end()) {
noInsideConnection = false;
break;
}
if (noInsideConnection) {
const auto val = std::make_pair(parent, outputIdx);
if (std::find(mOutputNodes.cbegin(), mOutputNodes.cend(), val) == mOutputNodes.cend()) {
newOutputsInsertionPoint = mOutputNodes.insert(newOutputsInsertionPoint, val);
newOutputsInsertionPoint = std::next(newOutputsInsertionPoint);
}
}
++outputIdx;

Grégoire Kubler
committed
const std::pair<std::vector<NodePtr>, size_t> ranked_nodes = getRankedNodes();
if(ranked_nodes.second== 0 || ranked_nodes.first.size() <= 1)

Grégoire Kubler
committed
mRootNode = nullptr;
} else {
// The new root node will be the second node in the order of ranked nodes
setRootNode(*std::next(ranked_nodes.first.cbegin(),1));
}
std::shared_ptr<Aidge::GraphView> Aidge::GraphView::cloneCallback(NodePtr(*cloneNode)(NodePtr)) const {
std::shared_ptr<GraphView> newGraph = std::make_shared<GraphView>(mName);
// Map for old node -> new node correspondance
std::map<NodePtr, NodePtr> oldToNewNodes;
for (const std::shared_ptr<Node> &node_ptr : mNodes) {
auto clonedNode = cloneNode(node_ptr);
if (clonedNode == nullptr) {
AIDGE_ASSERT(node_ptr->getChildren().size() <= 1, "deleted nodes in GraphView::clone() cannot have multiple children");
AIDGE_ASSERT(node_ptr->nbData() <= 1, "deleted nodes in GraphView::clone() cannot have multiple data input parents");
}
oldToNewNodes[node_ptr] = clonedNode;
// For each node, convert old node -> new node connections
for (auto &oldToNewNode : oldToNewNodes) {
if (oldToNewNode.second == nullptr) {
// Connect parent nodes. Nodes that were removed with cloneNode() are set to nullptr
size_t parentId = 0;
for (auto parent : oldToNewNode.first->inputs()) {
if (parent.first != nullptr) {
while (oldToNewNodes[parent.first] == nullptr) {
// Find next valid parent in line, going backward in the graph
AIDGE_INTERNAL_ASSERT(parent.first->getChildren().size() == 1);
const auto& parents = parent.first->dataInputs();
if (!parents.empty() && parents[0].first != nullptr // a valid parent exists
&& oldToNewNodes.find(parents[0].first) != oldToNewNodes.end()) // parent is in the GraphView
{
parent = parents[0];
}
else {
break;
}
if (oldToNewNodes[parent.first]) {
AIDGE_INTERNAL_ASSERT(oldToNewNodes[parent.first]->nbOutputs() == parent.first->nbOutputs());
oldToNewNodes[parent.first]->addChild(oldToNewNode.second, parent.second, parentId);
}
}
}
// Once connected, add each new nodes to new GraphView
// This has to be done in a second step to ensure that new GraphView inputs/outputs
// are properly set (otherwise, some node's inputs/outputs may be wrongly registered as
// GraphView inputs/outputs because not yet connected to other nodes)
if (oldToNewNodes[mRootNode] != nullptr) {
// Add root node first if is still exists!
newGraph->add(oldToNewNodes[mRootNode], false);
}
for (auto &oldToNewNode : oldToNewNodes) {
if (oldToNewNode.second == nullptr)
continue; // deleted node
newGraph->add(oldToNewNode.second, false);
}
// Update cloned graph inputs/outputs order to match initial graph order
auto newInputNodes = mInputNodes;
for (auto it = newInputNodes.begin(); it != newInputNodes.end(); ) {
// If input node was removed, find next valid input
while (oldToNewNodes[it->first] == nullptr) {
// Removed node should have only one connected output, otherwise cloning is invalid
AIDGE_INTERNAL_ASSERT(it->first->getChildren().size() <= 1);
if (it->first->getChildren().size() == 1) {
auto child = *it->first->getChildren().begin();
std::size_t inputIdx = 0;
for (auto parent : child->getParents()) {
if (parent == it->first) {
it->first = child;
it->second = inputIdx;
found = true;
break;
}
++inputIdx;
}
}
if (!found) {
break;
}
}
if (oldToNewNodes[it->first] == nullptr) {
it = newInputNodes.erase(it);
}
else {
it->first = oldToNewNodes[it->first];
}
newGraph->setOrderedInputs(newInputNodes);
auto newOutputNodes = mOutputNodes;
for (auto it = newOutputNodes.begin(); it != newOutputNodes.end(); ) {
// If output node was removed, find previous valid output
while (oldToNewNodes[it->first] == nullptr) {
// Removed node should have only one connected data input, otherwise cloning is invalid
if (!parents.empty() && parents[0].first != nullptr // a valid parent exists
&& oldToNewNodes.find(parents[0].first) != oldToNewNodes.end()) // parent is in the GraphView
{
*it = parents[0];
}
else {
break;
}
}
if (oldToNewNodes[it->first] == nullptr) {
it = newOutputNodes.erase(it);
}
else {
it->first = oldToNewNodes[it->first];
return newGraph;
}
std::shared_ptr<Aidge::GraphView> Aidge::getConnectedGraphView(std::shared_ptr<Node> node) {
for (std::size_t curNodeIdx = 0; curNodeIdx < foundNodes.size(); ++curNodeIdx) {
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
NodePtr curNode = foundNodes[curNodeIdx];
for (auto childs : curNode->getOrderedChildren()) {
for (auto child : childs) {
if (child != nullptr && std::find(foundNodes.begin(), foundNodes.end(), child) == foundNodes.end()) {
foundNodes.push_back(child);
}
}
}
for (auto parent : curNode->getParents()) {
if (parent != nullptr && std::find(foundNodes.begin(), foundNodes.end(), parent) == foundNodes.end()) {
foundNodes.push_back(parent);
}
}
}
auto graph = std::make_shared<GraphView>();
graph->add(node);
graph->add({foundNodes.cbegin(), foundNodes.cend()});
return graph;
}