From e72e6bce96495373a6e01ec964e7cba8d280cdba Mon Sep 17 00:00:00 2001 From: parker Date: Wed, 30 Jul 2025 17:12:13 +0100 Subject: [PATCH] fix: dirty system now dirties and cooks descendents of change --- src/Engine/Network/NetworkManager.cpp | 54 +++++++++++++++++++++--- src/Engine/Network/NetworkManager.h | 1 + src/Engine/Operator/GeometryOperator.cpp | 12 +++--- src/Engine/Operator/GeometryOperator.h | 6 +-- src/Gui/Network/Network.cpp | 2 - src/Gui/Network/NodeGraphic.cpp | 2 +- 6 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/Engine/Network/NetworkManager.cpp b/src/Engine/Network/NetworkManager.cpp index 7aff4d7..faab2d1 100644 --- a/src/Engine/Network/NetworkManager.cpp +++ b/src/Engine/Network/NetworkManager.cpp @@ -19,15 +19,31 @@ enzo::nt::OpId enzo::nt::NetworkManager::addOperator(op::OpInfo opInfo) maxOpId_++; std::unique_ptr newOp = std::make_unique(maxOpId_, opInfo); newOp->nodeDirtied.connect( - [this](nt::OpId opId) + [this](nt::OpId opId, bool dirtyDescendents) { - cookOp(opId); - - if(getDisplayOp()==opId) + IC(); + if(dirtyDescendents) { - enzo::nt::GeometryOperator& displayOp = getGeoOperator(opId); - updateDisplay(displayOp.getOutputGeo(0)); + IC(); + std::vector dependentIds = getDependentsGraph(opId); + for(OpId dependentId : dependentIds) + { + IC(); + // dirty node + enzo::nt::GeometryOperator& dependentOp = getGeoOperator(opId); + std::cout << "dirtying id: " << dependentId << "\n"; + dependentOp.dirtyNode(false); + + // cook display op + if(getDisplayOp().has_value() && getDisplayOp().value()==dependentId) + { + IC(); + cookOp(dependentId); + updateDisplay(dependentOp.getOutputGeo(0)); + } + } } + }); gopStore_.emplace(maxOpId_, std::move(newOp)); std::cout << "adding operator " << maxOpId_ << "\n"; @@ -96,7 +112,6 @@ std::vector enzo::nt::NetworkManager::getDependencyGraph(enzo::n while(traversalBuffer.size()!=0) { enzo::nt::OpId currentOp = traversalBuffer.top(); - std::cout << "cooking node: " << currentOp << "\n"; traversalBuffer.pop(); auto inputConnections = getGeoOperator(currentOp).getInputConnections(); for(auto connection : inputConnections) @@ -114,6 +129,31 @@ std::vector enzo::nt::NetworkManager::getDependencyGraph(enzo::n return dependencyGraph; } +std::vector enzo::nt::NetworkManager::getDependentsGraph(enzo::nt::OpId opId) +{ + std::stack traversalBuffer; + std::vector dependencyGraph; + traversalBuffer.push(opId); + dependencyGraph.push_back(opId); + + while(traversalBuffer.size()!=0) + { + enzo::nt::OpId currentOp = traversalBuffer.top(); + traversalBuffer.pop(); + auto outputConnections = getGeoOperator(currentOp).getOutputConnections(); + for(auto connection : outputConnections) + { + if(auto connectionPtr = connection.lock()) + { + traversalBuffer.push(connectionPtr->getOutputOpId()); + dependencyGraph.push_back(connectionPtr->getOutputOpId()); + } + else { throw std::runtime_error("Connection weak ptr invalid"); } + } + } + + return dependencyGraph; +} std::optional enzo::nt::NetworkManager::getDisplayOp() { diff --git a/src/Engine/Network/NetworkManager.h b/src/Engine/Network/NetworkManager.h index 87a6043..52e52e4 100644 --- a/src/Engine/Network/NetworkManager.h +++ b/src/Engine/Network/NetworkManager.h @@ -36,6 +36,7 @@ private: // functions void cookOp(enzo::nt::OpId opId); std::vector getDependencyGraph(enzo::nt::OpId opId); + std::vector getDependentsGraph(enzo::nt::OpId opId); // variables // store for geometry operators diff --git a/src/Engine/Operator/GeometryOperator.cpp b/src/Engine/Operator/GeometryOperator.cpp index 6240f3a..dc3bbd1 100644 --- a/src/Engine/Operator/GeometryOperator.cpp +++ b/src/Engine/Operator/GeometryOperator.cpp @@ -40,17 +40,17 @@ void nt::GeometryOperator::initParameters() std::cout << "name: " << t->getName() << "\n"; // create parameter auto parameter = std::make_shared(*t); - parameter->valueChanged.connect(boost::bind(&GeometryOperator::dirtyNode, this)); + parameter->valueChanged.connect([this](){dirtyNode();}); parameters_.push_back(parameter); } } -void enzo::nt::GeometryOperator::dirtyNode() +void enzo::nt::GeometryOperator::dirtyNode(bool dirtyDescendents) { dirty_=true; - nodeDirtied(opId_); + nodeDirtied(opId_, dirtyDescendents); } void enzo::nt::GeometryOperator::cookOp(op::Context context) @@ -79,11 +79,11 @@ void nt::GeometryOperator::addInputConnection(std::shared_ptrgetInputOpId() << " -> " << newConnection->getOutputOpId() << "\n"; - std::cout << "Connecting index " << newConnection->getInputIndex() << " -> " << newConnection->getOutputIndex() << "\n"; // add new newConnection inputConnections_.push_back(newConnection); - std::cout << "size: " << inputConnections_.size() << "\n"; + + IC(); + dirtyNode(); } void nt::GeometryOperator::addOutputConnection(std::shared_ptr connection) diff --git a/src/Engine/Operator/GeometryOperator.h b/src/Engine/Operator/GeometryOperator.h index 34aa500..35be946 100644 --- a/src/Engine/Operator/GeometryOperator.h +++ b/src/Engine/Operator/GeometryOperator.h @@ -32,15 +32,15 @@ public: std::string getTypeName(); - void dirtyNode(); + void dirtyNode(bool dirtyDescendents=true); - unsigned int getMaxInputs() const; unsigned int getMinInputs() const; + unsigned int getMaxInputs() const; unsigned int getMaxOutputs() const; // signals - boost::signals2::signal nodeDirtied; + boost::signals2::signal nodeDirtied; diff --git a/src/Gui/Network/Network.cpp b/src/Gui/Network/Network.cpp index 9c218ad..d693f96 100644 --- a/src/Gui/Network/Network.cpp +++ b/src/Gui/Network/Network.cpp @@ -165,8 +165,6 @@ void Network::socketClicked(SocketGraphic* socket, QMouseEvent *event) newEdge->setPos(outputNodeSocket->scenePos(), inputNodeSocket->scenePos()); scene_->addItem(newEdge); destroyFloatingEdge(); - - geoOp.dirtyNode(); } } diff --git a/src/Gui/Network/NodeGraphic.cpp b/src/Gui/Network/NodeGraphic.cpp index 7e25790..41ee3ea 100644 --- a/src/Gui/Network/NodeGraphic.cpp +++ b/src/Gui/Network/NodeGraphic.cpp @@ -24,7 +24,7 @@ NodeGraphic::NodeGraphic(enzo::nt::OpId id, QGraphicsItem *parent) enzo::nt::GeometryOperator& geoOp = enzo::nt::nm().getGeoOperator(id); titleText_ = geoOp.getTypeName(); // TODO: unique node names - subTitleText_ = geoOp.getTypeName(); + subTitleText_ = "OpID: " + std::to_string(opId_); constexpr int height = 27; constexpr int width = 100; bodyRect_ = QRect(-width*0.5f, -height*0.5f, width, height);