LCOV - code coverage report
Current view: top level - src/gui - GUILoadThread.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 90.0 % 130 117
Test Date: 2024-12-21 15:45:41 Functions: 100.0 % 8 8

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    GUILoadThread.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // Class describing the thread that performs the loading of a simulation
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <iostream>
      25              : #include <ctime>
      26              : #include <utils/common/RandHelper.h>
      27              : #include <utils/common/UtilExceptions.h>
      28              : #include <utils/common/MsgHandler.h>
      29              : #include <utils/common/MsgRetrievingFunction.h>
      30              : #include <utils/options/OptionsCont.h>
      31              : #include <utils/options/Option.h>
      32              : #include <utils/options/OptionsIO.h>
      33              : #include <utils/foxtools/MFXSynchQue.h>
      34              : #include <utils/gui/events/GUIEvent_Message.h>
      35              : #include <utils/gui/windows/GUIAppEnum.h>
      36              : #include <utils/gui/globjects/GUIGlObjectStorage.h>
      37              : #include <utils/gui/images/GUITexturesHelper.h>
      38              : #include <utils/xml/XMLSubSys.h>
      39              : #include <guisim/GUINet.h>
      40              : #include <guisim/GUIEventControl.h>
      41              : #include <guisim/GUIVehicleControl.h>
      42              : #include <netload/NLBuilder.h>
      43              : #include <netload/NLHandler.h>
      44              : #include <netload/NLJunctionControlBuilder.h>
      45              : #include <guinetload/GUIEdgeControlBuilder.h>
      46              : #include <guinetload/GUIDetectorBuilder.h>
      47              : #include <guinetload/GUITriggerBuilder.h>
      48              : #include <microsim/output/MSDetectorControl.h>
      49              : #include <microsim/devices/MSDevice.h>
      50              : #include <microsim/MSGlobals.h>
      51              : #include <microsim/MSFrame.h>
      52              : #include <microsim/MSRouteHandler.h>
      53              : #include <mesogui/GUIMEVehicleControl.h>
      54              : #include <libsumo/Helper.h>
      55              : #include <traci-server/TraCIServer.h>
      56              : #include "TraCIServerAPI_GUI.h"
      57              : #include "GUIApplicationWindow.h"
      58              : #include "GUILoadThread.h"
      59              : #include "GUIGlobals.h"
      60              : #include "GUIEvent_SimulationLoaded.h"
      61              : 
      62              : 
      63              : // ===========================================================================
      64              : // member method definitions
      65              : // ===========================================================================
      66         7597 : GUILoadThread::GUILoadThread(FXApp* app, GUIApplicationWindow* mw,
      67         7597 :                              MFXSynchQue<GUIEvent*>& eq, FXEX::MFXThreadEvent& ev, const bool isLibsumo)
      68         7597 :     : MFXSingleEventThread(app, mw), myParent(mw), myEventQue(eq),
      69         7597 :       myEventThrow(ev), myAmLibsumo(isLibsumo) {
      70         7597 :     myErrorRetriever = new MsgRetrievingFunction<GUILoadThread>(this, &GUILoadThread::retrieveMessage, MsgHandler::MsgType::MT_ERROR);
      71         7597 :     myMessageRetriever = new MsgRetrievingFunction<GUILoadThread>(this, &GUILoadThread::retrieveMessage, MsgHandler::MsgType::MT_MESSAGE);
      72         7597 :     myWarningRetriever = new MsgRetrievingFunction<GUILoadThread>(this, &GUILoadThread::retrieveMessage, MsgHandler::MsgType::MT_WARNING);
      73         7597 :     MsgHandler::getErrorInstance()->addRetriever(myErrorRetriever);
      74         7597 : }
      75              : 
      76              : 
      77        15160 : GUILoadThread::~GUILoadThread() {
      78         7580 :     delete myErrorRetriever;
      79         7580 :     delete myMessageRetriever;
      80         7580 :     delete myWarningRetriever;
      81        15160 : }
      82              : 
      83              : 
      84              : FXint
      85         7597 : GUILoadThread::run() {
      86              :     // register message callbacks
      87         7597 :     MsgHandler::getMessageInstance()->addRetriever(myMessageRetriever);
      88         7597 :     MsgHandler::getErrorInstance()->addRetriever(myErrorRetriever);
      89        15194 :     if (!OptionsCont::getOptions().getBool("no-warnings")) {
      90         7597 :         MsgHandler::getWarningInstance()->addRetriever(myWarningRetriever);
      91              :     }
      92              : 
      93              :     // try to load the given configuration
      94         7597 :     OptionsCont& oc = OptionsCont::getOptions();
      95              :     try {
      96         7597 :         if (myFile != "") {
      97              :             // triggered by menu option or reload
      98            0 :             oc.clear();
      99            0 :             MSFrame::fillOptions();
     100            0 :             oc.setByRootElement(OptionsIO::getRoot(myFile), myFile);
     101            0 :             oc.resetWritable(); // there may be command line options
     102            0 :             OptionsIO::getOptions();
     103              :         } else {
     104              :             // triggered at application start
     105         7597 :             OptionsIO::loadConfiguration();
     106        15190 :             if (oc.isSet("configuration-file")) {
     107          293 :                 myFile = oc.getString("configuration-file");
     108          293 :                 myParent->addRecentConfig(FXPath::absolute(myFile.c_str()));
     109              : 
     110        14604 :             } else if (oc.isSet("net-file")) {
     111         7302 :                 myFile = oc.getString("net-file");
     112         7302 :                 myParent->addRecentNetwork(FXPath::absolute(myFile.c_str()));
     113              :             }
     114        15190 :             myEventQue.push_back(new GUIEvent_Message("Loading '" + myFile + "'."));
     115         7595 :             myEventThrow.signal();
     116              :         }
     117         7595 :         myTitle = myFile;
     118         7595 :         if (!myAmLibsumo) {
     119              :             // within gui-based applications, nothing is reported to the console
     120         7100 :             MsgHandler::getMessageInstance()->removeRetriever(&OutputDevice::getDevice("stdout"));
     121         7100 :             MsgHandler::getWarningInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));
     122        14200 :             MsgHandler::getErrorInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));
     123              :         }
     124              :         // do this once again to get parsed options
     125         8262 :         if (oc.getBool("duration-log.statistics") && oc.isDefault("verbose")) {
     126              :             // must be done before calling initOutputOptions (which checks option "verbose")
     127              :             // but initOutputOptions must come before checkOptions (so that warnings are printed)
     128         1264 :             oc.setDefault("verbose", "true");
     129              :         }
     130         7595 :         MsgHandler::initOutputOptions();
     131         7595 :         if (!MSFrame::checkOptions()) {
     132           20 :             throw ProcessError();
     133              :         }
     134        22713 :         XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), oc.getString("xml-validation.routes"));
     135        15142 :         GUIGlobals::gRunAfterLoad = oc.getBool("start") || (myAmLibsumo && std::getenv("LIBSUMO_GUI") != nullptr);
     136         7571 :         GUIGlobals::gQuitOnEnd = oc.getBool("quit-on-end");
     137         7571 :         GUIGlobals::gDemoAutoReload = oc.getBool("demo");
     138         7571 :         GUIGlobals::gTrackerInterval = STEPS2TIME(string2time(oc.getString("tracker-interval")));
     139           26 :     } catch (ProcessError& e) {
     140           38 :         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
     141           12 :             WRITE_ERROR(e.what());
     142              :         }
     143              :         // the options are not valid but maybe we want to quit
     144           26 :         GUIGlobals::gQuitOnEnd = oc.getBool("quit-on-end");
     145           52 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     146           26 :         submitEndAndCleanup(nullptr, 0, 0);
     147              :         return 0;
     148           26 :     }
     149              : 
     150              :     // initialise global settings
     151         7571 :     NLBuilder::initRandomness();
     152         7571 :     MSFrame::setMSGlobals(oc);
     153         7571 :     GUITexturesHelper::allowTextures(!oc.getBool("disable-textures"));
     154              : 
     155              :     MSVehicleControl* vehControl = nullptr;
     156         7571 :     GUIVisualizationSettings::UseMesoSim = MSGlobals::gUseMesoSim;
     157         7571 :     if (MSGlobals::gUseMesoSim) {
     158         2505 :         vehControl = new GUIMEVehicleControl();
     159              :     } else {
     160         5066 :         vehControl = new GUIVehicleControl();
     161              :     }
     162              : 
     163              :     GUINet* net = nullptr;
     164              :     SUMOTime simStartTime = 0;
     165              :     SUMOTime simEndTime = 0;
     166              :     std::vector<std::string> guiSettingsFiles;
     167              :     bool osgView = false;
     168              :     GUIEdgeControlBuilder* eb = nullptr;
     169              :     try {
     170              :         net = new GUINet(
     171              :             vehControl,
     172         7571 :             new GUIEventControl(),
     173         7571 :             new GUIEventControl(),
     174        15142 :             new GUIEventControl());
     175              :         // need to init TraCI-Server before loading routes to catch VehicleState::BUILT
     176              :         std::map<int, TraCIServer::CmdExecutor> execs;
     177         7571 :         execs[libsumo::CMD_GET_GUI_VARIABLE] = &TraCIServerAPI_GUI::processGet;
     178         7571 :         execs[libsumo::CMD_SET_GUI_VARIABLE] = &TraCIServerAPI_GUI::processSet;
     179         7571 :         TraCIServer::openSocket(execs);
     180         7569 :         if (myAmLibsumo) {
     181          495 :             libsumo::Helper::registerStateListener();
     182              :         }
     183              : 
     184         7569 :         eb = new GUIEdgeControlBuilder();
     185         7569 :         GUIDetectorBuilder db(*net);
     186         7569 :         NLJunctionControlBuilder jb(*net, db);
     187         7569 :         GUITriggerBuilder tb;
     188         7569 :         NLHandler handler("", *net, db, tb, *eb, jb);
     189         7569 :         tb.setHandler(&handler);
     190         7569 :         NLBuilder builder(oc, *net, *eb, jb, db, handler);
     191         7569 :         MsgHandler::getErrorInstance()->clear();
     192         7569 :         MsgHandler::getWarningInstance()->clear();
     193         7569 :         MsgHandler::getMessageInstance()->clear();
     194         7569 :         if (!builder.build()) {
     195          228 :             throw ProcessError();
     196              :         } else {
     197         7320 :             net->initGUIStructures();
     198         7320 :             simStartTime = string2time(oc.getString("begin"));
     199         7320 :             simEndTime = string2time(oc.getString("end"));
     200         7320 :             guiSettingsFiles = oc.getStringVector("gui-settings-file");
     201              : #ifdef HAVE_OSG
     202         7320 :             osgView = oc.getBool("osg-view");
     203              : #endif
     204        14640 :             if (oc.isSet("edgedata-files")) {
     205            0 :                 if (!oc.isUsableFileList("edgedata-files")) {
     206            0 :                     WRITE_ERRORF(TL("Could not load edgedata-files '%'"), oc.getString("edgedata-files"));
     207              :                 } else {
     208            0 :                     for (const std::string& file : oc.getStringVector("edgedata-files")) {
     209            0 :                         net->loadEdgeData(file);
     210              :                     }
     211              :                 }
     212              :             }
     213              :         }
     214         8816 :     } catch (ProcessError& e) {
     215          297 :         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
     216           46 :             WRITE_ERROR(e.what());
     217              :         }
     218          251 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     219          251 :         delete net;
     220              :         net = nullptr;
     221              : #ifndef _DEBUG
     222          251 :     } catch (std::exception& e) {
     223            0 :         WRITE_ERROR(e.what());
     224            0 :         delete net;
     225              :         net = nullptr;
     226              : #endif
     227            0 :     }
     228         7571 :     if (net == nullptr) {
     229          251 :         MSNet::clearAll();
     230              :     }
     231         7571 :     delete eb;
     232         7571 :     submitEndAndCleanup(net, simStartTime, simEndTime, guiSettingsFiles, osgView,
     233         7571 :                         oc.getBool("registry-viewport"));
     234              :     return 0;
     235         7571 : }
     236              : 
     237              : 
     238              : void
     239         7597 : GUILoadThread::submitEndAndCleanup(GUINet* net,
     240              :                                    const SUMOTime simStartTime,
     241              :                                    const SUMOTime simEndTime,
     242              :                                    const std::vector<std::string>& guiSettingsFiles,
     243              :                                    const bool osgView,
     244              :                                    const bool viewportFromRegistry) {
     245              :     // remove message callbacks
     246         7597 :     MsgHandler::getErrorInstance()->removeRetriever(myErrorRetriever);
     247         7597 :     MsgHandler::getWarningInstance()->removeRetriever(myWarningRetriever);
     248         7597 :     MsgHandler::getMessageInstance()->removeRetriever(myMessageRetriever);
     249              :     // inform parent about the process
     250         7597 :     GUIEvent* e = new GUIEvent_SimulationLoaded(net, simStartTime, simEndTime, myTitle, guiSettingsFiles, osgView, viewportFromRegistry);
     251         7597 :     myEventQue.push_back(e);
     252         7597 :     myEventThrow.signal();
     253         7597 : }
     254              : 
     255              : 
     256              : void
     257         7597 : GUILoadThread::loadConfigOrNet(const std::string& file) {
     258         7597 :     myFile = file;
     259         7597 :     if (myFile != "") {
     260            0 :         OptionsIO::setArgs(0, nullptr);
     261              :     }
     262         7597 :     start();
     263         7597 : }
     264              : 
     265              : 
     266              : void
     267        43176 : GUILoadThread::retrieveMessage(const MsgHandler::MsgType type, const std::string& msg) {
     268        43176 :     GUIEvent* e = new GUIEvent_Message(type, msg);
     269        43176 :     myEventQue.push_back(e);
     270        43176 :     myEventThrow.signal();
     271        43176 : }
     272              : 
     273              : 
     274              : const std::string&
     275      1507842 : GUILoadThread::getFileName() const {
     276      1507842 :     return myFile;
     277              : }
     278              : 
     279              : 
     280              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1