From 80c02be90fcf91d722d563227f11637f7f7dc27f Mon Sep 17 00:00:00 2001 From: Pablo Alvarez Lopez Date: Wed, 22 Jan 2025 16:50:12 +0100 Subject: [PATCH] Fixed crash creating TAZ with undo-redo disabled. Refs #16039 --- .../additional/GNEAdditionalHandler.cpp | 10 +++- src/netedit/frames/network/GNETAZFrame.cpp | 50 ++++++++++++++++--- src/netedit/frames/network/GNETAZFrame.h | 3 ++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/netedit/elements/additional/GNEAdditionalHandler.cpp b/src/netedit/elements/additional/GNEAdditionalHandler.cpp index 05152482b15c..7dc95b46b78d 100644 --- a/src/netedit/elements/additional/GNEAdditionalHandler.cpp +++ b/src/netedit/elements/additional/GNEAdditionalHandler.cpp @@ -1369,13 +1369,17 @@ GNEAdditionalHandler::buildTAZ(const CommonXMLStructure::SumoBaseObject* sumoBas TAZ->incRef("buildTAZ"); for (const auto& edge : edges) { // create TAZ Source - GNEAdditional* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1); + GNETAZSourceSink* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1); + myNet->getAttributeCarriers()->insertAdditional(TAZSource); TAZSource->incRef("buildTAZ"); TAZ->addChildElement(TAZSource); + edge->addChildElement(TAZSource); // create TAZ Sink - GNEAdditional* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1); + GNETAZSourceSink* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1); + myNet->getAttributeCarriers()->insertAdditional(TAZSink); TAZSink->incRef("buildTAZ"); TAZ->addChildElement(TAZSink); + edge->addChildElement(TAZSink); } } // enable updating geometry again and update geometry of TAZ @@ -1420,6 +1424,7 @@ GNEAdditionalHandler::buildTAZSource(const CommonXMLStructure::SumoBaseObject* s } else { myNet->getAttributeCarriers()->insertAdditional(TAZSource); TAZ->addChildElement(TAZSource); + edge->addChildElement(TAZSource); TAZSource->incRef("buildTAZSource"); } } else { @@ -1469,6 +1474,7 @@ GNEAdditionalHandler::buildTAZSink(const CommonXMLStructure::SumoBaseObject* sum } else { myNet->getAttributeCarriers()->insertAdditional(TAZSink); TAZ->addChildElement(TAZSink); + edge->addChildElement(TAZSink); TAZSink->incRef("buildTAZSink"); } } else { diff --git a/src/netedit/frames/network/GNETAZFrame.cpp b/src/netedit/frames/network/GNETAZFrame.cpp index fec883c1576a..22eff671f3ae 100644 --- a/src/netedit/frames/network/GNETAZFrame.cpp +++ b/src/netedit/frames/network/GNETAZFrame.cpp @@ -1650,12 +1650,25 @@ GNETAZFrame::shapeDrawed() { // TAZ is created without edges myBaseTAZ->addStringListAttribute(SUMO_ATTR_EDGES, std::vector()); } - // declare additional handler - GNEAdditionalHandler additionalHandler(myViewNet->getNet(), myViewNet->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false); - // build TAZ - additionalHandler.parseSumoBaseObject(myBaseTAZ); - // TAZ created, then return true - return true; + const bool allowUndoRedo = (myBaseTAZ->getStringListAttribute(SUMO_ATTR_EDGES).size() < 2000); + // due lack of memory, we need to ask if we're creating a lot of sourcesinks + if (allowUndoRedo) { + // declare additional handler + GNEAdditionalHandler additionalHandler(myViewNet->getNet(), myViewNet->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false); + // build TAZ + additionalHandler.parseSumoBaseObject(myBaseTAZ); + // TAZ created, then return true + return true; + } else if (askCreateMultipleSourceSinks(myBaseTAZ->getStringListAttribute(SUMO_ATTR_EDGES).size())) { + // declare additional handler + GNEAdditionalHandler additionalHandler(myViewNet->getNet(), false, false); + // build TAZ + additionalHandler.parseSumoBaseObject(myBaseTAZ); + // TAZ created, then return true + return true; + } else { + return false; + } } } @@ -1720,5 +1733,28 @@ GNETAZFrame::dropTAZMembers() { myCurrentTAZ->refreshTAZEdges(); } - +bool +GNETAZFrame::askCreateMultipleSourceSinks(const size_t numSourceSinks) const { + // declare variable to save FXMessageBox outputs. + FXuint answer = 0; + // write warning if netedit is running in testing mode + WRITE_DEBUG("Opening FXMessageBox 'Ask create multiple sourceSinks'"); + // open question dialog box + answer = FXMessageBox::question(myViewNet->getApp(), MBOX_YES_NO, TL("Create multiple sourceSInks"), + TLF("Creation of % cannot be undo. Continue?", toString(numSourceSinks)).c_str()); + if (answer != 1) { //1:yes, 2:no, 4:esc + // write warning if netedit is running in testing mode + if (answer == 2) { + WRITE_DEBUG("Closed FXMessageBox 'Ask create multiple sourceSinks' with 'No'"); + } else if (answer == 4) { + WRITE_DEBUG("Closed FXMessageBox 'Ask create multiple sourceSinks' with 'ESC'"); + } + // abort recompute with volatile options + return false; + } else { + // write warning if netedit is running in testing mode + WRITE_DEBUG("Closed FXMessageBox 'Ask create multiple sourceSinks' with 'Yes'"); + return true; + } +} /****************************************************************************/ diff --git a/src/netedit/frames/network/GNETAZFrame.h b/src/netedit/frames/network/GNETAZFrame.h index 84c06169c9f1..da516777bfdc 100644 --- a/src/netedit/frames/network/GNETAZFrame.h +++ b/src/netedit/frames/network/GNETAZFrame.h @@ -568,6 +568,9 @@ class GNETAZFrame : public GNEFrame { /// @brief drop all TAZSources and TAZ Sinks of current TAZ void dropTAZMembers(); + /// @brief ask for massive TAZ creation + bool askCreateMultipleSourceSinks(const size_t numSourceSinks) const; + private: /// @brief current TAZ CurrentTAZ* myCurrentTAZ;