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

          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        7278 : GUILoadThread::GUILoadThread(FXApp* app, GUIApplicationWindow* mw,
      67        7278 :                              MFXSynchQue<GUIEvent*>& eq, FXEX::MFXThreadEvent& ev, const bool isLibsumo)
      68        7278 :     : MFXSingleEventThread(app, mw), myParent(mw), myEventQue(eq),
      69        7278 :       myEventThrow(ev), myAmLibsumo(isLibsumo) {
      70        7278 :     myErrorRetriever = new MsgRetrievingFunction<GUILoadThread>(this, &GUILoadThread::retrieveMessage, MsgHandler::MsgType::MT_ERROR);
      71        7278 :     myMessageRetriever = new MsgRetrievingFunction<GUILoadThread>(this, &GUILoadThread::retrieveMessage, MsgHandler::MsgType::MT_MESSAGE);
      72        7278 :     myWarningRetriever = new MsgRetrievingFunction<GUILoadThread>(this, &GUILoadThread::retrieveMessage, MsgHandler::MsgType::MT_WARNING);
      73        7278 :     MsgHandler::getErrorInstance()->addRetriever(myErrorRetriever);
      74        7278 : }
      75             : 
      76             : 
      77       14520 : GUILoadThread::~GUILoadThread() {
      78        7260 :     delete myErrorRetriever;
      79        7260 :     delete myMessageRetriever;
      80        7260 :     delete myWarningRetriever;
      81       14520 : }
      82             : 
      83             : 
      84             : FXint
      85        7278 : GUILoadThread::run() {
      86             :     // register message callbacks
      87        7278 :     MsgHandler::getMessageInstance()->addRetriever(myMessageRetriever);
      88        7278 :     MsgHandler::getErrorInstance()->addRetriever(myErrorRetriever);
      89       14556 :     if (!OptionsCont::getOptions().getBool("no-warnings")) {
      90        7278 :         MsgHandler::getWarningInstance()->addRetriever(myWarningRetriever);
      91             :     }
      92             : 
      93             :     // try to load the given configuration
      94        7278 :     OptionsCont& oc = OptionsCont::getOptions();
      95             :     try {
      96        7278 :         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        7278 :             OptionsIO::loadConfiguration();
     106       14552 :             if (oc.isSet("configuration-file")) {
     107         688 :                 myFile = oc.getString("configuration-file");
     108         344 :                 myParent->addRecentConfig(FXPath::absolute(myFile.c_str()));
     109             : 
     110       13864 :             } else if (oc.isSet("net-file")) {
     111       13864 :                 myFile = oc.getString("net-file");
     112        6932 :                 myParent->addRecentNetwork(FXPath::absolute(myFile.c_str()));
     113             :             }
     114       21828 :             myEventQue.push_back(new GUIEvent_Message("Loading '" + myFile + "'."));
     115        7276 :             myEventThrow.signal();
     116             :         }
     117        7276 :         myTitle = myFile;
     118        7276 :         if (!myAmLibsumo) {
     119             :             // within gui-based applications, nothing is reported to the console
     120        6797 :             MsgHandler::getMessageInstance()->removeRetriever(&OutputDevice::getDevice("stdout"));
     121        6797 :             MsgHandler::getWarningInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));
     122       13594 :             MsgHandler::getErrorInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));
     123             :         }
     124             :         // do this once again to get parsed options
     125       15217 :         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        1190 :             oc.setDefault("verbose", "true");
     129             :         }
     130        7276 :         MsgHandler::initOutputOptions();
     131        7276 :         if (!MSFrame::checkOptions()) {
     132          17 :             throw ProcessError();
     133             :         }
     134       21765 :         XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"), oc.getString("xml-validation.routes"));
     135        7718 :         GUIGlobals::gRunAfterLoad = oc.getBool("start") || (myAmLibsumo && std::getenv("LIBSUMO_GUI") != nullptr);
     136        7255 :         GUIGlobals::gQuitOnEnd = oc.getBool("quit-on-end");
     137        7255 :         GUIGlobals::gDemoAutoReload = oc.getBool("demo");
     138        7255 :         GUIGlobals::gTrackerInterval = STEPS2TIME(string2time(oc.getString("tracker-interval")));
     139          23 :     } catch (ProcessError& e) {
     140          41 :         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          23 :         GUIGlobals::gQuitOnEnd = oc.getBool("quit-on-end");
     145          46 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     146          23 :         submitEndAndCleanup(nullptr, 0, 0);
     147             :         return 0;
     148          23 :     }
     149             : 
     150             :     // initialise global settings
     151        7255 :     NLBuilder::initRandomness();
     152        7255 :     MSFrame::setMSGlobals(oc);
     153        7255 :     GUITexturesHelper::allowTextures(!oc.getBool("disable-textures"));
     154             : 
     155             :     MSVehicleControl* vehControl = nullptr;
     156        7255 :     GUIVisualizationSettings::UseMesoSim = MSGlobals::gUseMesoSim;
     157        7255 :     if (MSGlobals::gUseMesoSim) {
     158        2365 :         vehControl = new GUIMEVehicleControl();
     159             :     } else {
     160        4890 :         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        7255 :             new GUIEventControl(),
     173        7255 :             new GUIEventControl(),
     174       14510 :             new GUIEventControl());
     175             :         // need to init TraCI-Server before loading routes to catch VehicleState::BUILT
     176             :         std::map<int, TraCIServer::CmdExecutor> execs;
     177        7255 :         execs[libsumo::CMD_GET_GUI_VARIABLE] = &TraCIServerAPI_GUI::processGet;
     178        7255 :         execs[libsumo::CMD_SET_GUI_VARIABLE] = &TraCIServerAPI_GUI::processSet;
     179        7255 :         TraCIServer::openSocket(execs);
     180        7252 :         if (myAmLibsumo) {
     181         479 :             libsumo::Helper::registerStateListener();
     182             :         }
     183             : 
     184        7252 :         eb = new GUIEdgeControlBuilder();
     185        7252 :         GUIDetectorBuilder db(*net);
     186        7252 :         NLJunctionControlBuilder jb(*net, db);
     187        7252 :         GUITriggerBuilder tb;
     188        7252 :         NLHandler handler("", *net, db, tb, *eb, jb);
     189        7252 :         tb.setHandler(&handler);
     190        7252 :         NLBuilder builder(oc, *net, *eb, jb, db, handler);
     191        7252 :         MsgHandler::getErrorInstance()->clear();
     192        7252 :         MsgHandler::getWarningInstance()->clear();
     193        7252 :         MsgHandler::getMessageInstance()->clear();
     194        7252 :         if (!builder.build()) {
     195         222 :             throw ProcessError();
     196             :         } else {
     197        7009 :             net->initGUIStructures();
     198       14018 :             simStartTime = string2time(oc.getString("begin"));
     199       14018 :             simEndTime = string2time(oc.getString("end"));
     200        7009 :             guiSettingsFiles = oc.getStringVector("gui-settings-file");
     201             : #ifdef HAVE_OSG
     202        7009 :             osgView = oc.getBool("osg-view");
     203             : #endif
     204       14018 :             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        8470 :     } catch (ProcessError& e) {
     215         318 :         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
     216          48 :             WRITE_ERROR(e.what());
     217             :         }
     218         246 :         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
     219         246 :         delete net;
     220             :         net = nullptr;
     221             : #ifndef _DEBUG
     222         246 :     } catch (std::exception& e) {
     223           0 :         WRITE_ERROR(e.what());
     224           0 :         delete net;
     225             :         net = nullptr;
     226             : #endif
     227           0 :     }
     228        7255 :     if (net == nullptr) {
     229         246 :         MSNet::clearAll();
     230             :     }
     231        7255 :     delete eb;
     232        7255 :     submitEndAndCleanup(net, simStartTime, simEndTime, guiSettingsFiles, osgView,
     233        7255 :                         oc.getBool("registry-viewport"));
     234             :     return 0;
     235        7255 : }
     236             : 
     237             : 
     238             : void
     239        7278 : 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        7278 :     MsgHandler::getErrorInstance()->removeRetriever(myErrorRetriever);
     247        7278 :     MsgHandler::getWarningInstance()->removeRetriever(myWarningRetriever);
     248        7278 :     MsgHandler::getMessageInstance()->removeRetriever(myMessageRetriever);
     249             :     // inform parent about the process
     250        7278 :     GUIEvent* e = new GUIEvent_SimulationLoaded(net, simStartTime, simEndTime, myTitle, guiSettingsFiles, osgView, viewportFromRegistry);
     251        7278 :     myEventQue.push_back(e);
     252        7278 :     myEventThrow.signal();
     253        7278 : }
     254             : 
     255             : 
     256             : void
     257        7278 : GUILoadThread::loadConfigOrNet(const std::string& file) {
     258        7278 :     myFile = file;
     259        7278 :     if (myFile != "") {
     260           0 :         OptionsIO::setArgs(0, nullptr);
     261             :     }
     262        7278 :     start();
     263        7278 : }
     264             : 
     265             : 
     266             : void
     267       36221 : GUILoadThread::retrieveMessage(const MsgHandler::MsgType type, const std::string& msg) {
     268       36221 :     GUIEvent* e = new GUIEvent_Message(type, msg);
     269       36221 :     myEventQue.push_back(e);
     270       36221 :     myEventThrow.signal();
     271       36221 : }
     272             : 
     273             : 
     274             : const std::string&
     275     2005206 : GUILoadThread::getFileName() const {
     276     2005206 :     return myFile;
     277             : }
     278             : 
     279             : 
     280             : /****************************************************************************/

Generated by: LCOV version 1.14