LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSTransportableControl.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 97.4 % 265 258
Test Date: 2026-09-20 15:45:03 Functions: 100.0 % 30 30

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2026 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    MSTransportableControl.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Sascha Krieg
      18              : /// @author  Michael Behrisch
      19              : /// @date    Mon, 9 Jul 2001
      20              : ///
      21              : // Stores all persons in the net and handles their waiting for cars.
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <vector>
      26              : #include <algorithm>
      27              : #include <utils/iodevices/OutputDevice.h>
      28              : #include <utils/iodevices/OutputDevice_String.h>
      29              : #include <utils/options/OptionsCont.h>
      30              : #include <microsim/transportables/MSPerson.h>
      31              : #include <microsim/transportables/MSStageDriving.h>
      32              : #include <microsim/transportables/MSPModel_NonInteracting.h>
      33              : #ifdef HAVE_JUPEDSIM
      34              : #include <microsim/transportables/MSPModel_JuPedSim.h>
      35              : #endif
      36              : #include <microsim/transportables/MSPModel_Striping.h>
      37              : #include <microsim/transportables/MSTransportableControl.h>
      38              : #include <microsim/devices/MSDevice_Vehroutes.h>
      39              : #include <microsim/devices/MSDevice_Taxi.h>
      40              : #include <microsim/MSNet.h>
      41              : #include <microsim/MSEdge.h>
      42              : #include <microsim/MSVehicle.h>
      43              : #include <microsim/MSStoppingPlace.h>
      44              : 
      45              : 
      46              : // ===========================================================================
      47              : // method definitions
      48              : // ===========================================================================
      49        10232 : MSTransportableControl::MSTransportableControl(const bool isPerson):
      50        10232 :     myLoadedNumber(0),
      51        10232 :     myDiscardedNumber(0),
      52        10232 :     myRunningNumber(0),
      53        10232 :     myJammedNumber(0),
      54        10232 :     myWaitingForDepartureNumber(0),
      55        10232 :     myWaitingForVehicleNumber(0),
      56        10232 :     myWaitingUntilNumber(0),
      57        10232 :     myAccessNumber(0),
      58        10232 :     myEndedNumber(0),
      59        10232 :     myArrivedNumber(0),
      60        10232 :     myTeleportsAbortWait(0),
      61        10232 :     myTeleportsWrongDest(0),
      62        10232 :     myHaveNewWaiting(false) {
      63        10232 :     const OptionsCont& oc = OptionsCont::getOptions();
      64        10232 :     MSNet* const net = MSNet::getInstance();
      65        10232 :     myMovementModel = myNonInteractingModel = new MSPModel_NonInteracting(oc, net);
      66        10232 :     if (isPerson) {
      67         8277 :         const std::string& model = oc.getString("pedestrian.model");
      68         8277 :         if (model == "striping") {
      69         6128 :             myMovementModel = new MSPModel_Striping(oc, net);
      70              : #ifdef HAVE_JUPEDSIM
      71              :         } else if (model == "jupedsim") {
      72              :             myMovementModel = new MSPModel_JuPedSim(oc, net);
      73              : #endif
      74         2149 :         } else if (model != "nonInteracting") {
      75           24 :             delete myNonInteractingModel;
      76           72 :             throw ProcessError(TLF("Unknown pedestrian model '%'", model));
      77              :         }
      78              :     }
      79        20416 :     if (oc.isSet("vehroute-output")) {
      80         1672 :         myRouteInfos.routeOut = &OutputDevice::getDeviceByOption("vehroute-output");
      81              :     }
      82        20416 :     if (oc.isSet("personroute-output")) {
      83           24 :         OutputDevice::createDeviceByOption("personroute-output", "routes", "routes_file.xsd");
      84           12 :         myRouteInfos.routeOut = &OutputDevice::getDeviceByOption("personroute-output");
      85              :     }
      86        20416 :     if (oc.isSet("personinfo-output")) {
      87           36 :         OutputDevice::createDeviceByOption("personinfo-output", "tripinfos", "tripinfo_file.xsd");
      88              :     }
      89        10208 :     myAbortWaitingTimeout = string2time(oc.getString("time-to-teleport.ride"));
      90        10208 :     myMaxTransportableNumber = isPerson ? oc.getInt("max-num-persons") : -1;
      91        10256 : }
      92              : 
      93              : 
      94        18613 : MSTransportableControl::~MSTransportableControl() {
      95        10185 :     clearState();
      96        10185 :     if (myMovementModel != myNonInteractingModel) {
      97         6116 :         delete myMovementModel;
      98              :     }
      99        10185 :     delete myNonInteractingModel;
     100        18613 : }
     101              : 
     102              : 
     103              : bool
     104       530483 : MSTransportableControl::add(MSTransportable* transportable) {
     105       530483 :     const SUMOVehicleParameter& param = transportable->getParameter();
     106       530483 :     if (myTransportables.find(param.id) == myTransportables.end()) {
     107       530467 :         myTransportables[param.id] = transportable;
     108       530467 :         const SUMOTime step = param.depart % DELTA_T == 0 ? param.depart : (param.depart / DELTA_T + 1) * DELTA_T;
     109       530467 :         myWaiting4Departure[step].push_back(transportable);
     110       530467 :         myLoadedNumber++;
     111       530467 :         myWaitingForDepartureNumber++;
     112              :         return true;
     113              :     }
     114              :     return false;
     115              : }
     116              : 
     117              : 
     118              : void
     119          219 : MSTransportableControl::fixLoadCount(const MSTransportable* transportable) {
     120          219 :     myLoadedNumber--;
     121          219 :     if (transportable->hasDeparted()) {
     122          134 :         const SUMOVehicleParameter& param = transportable->getParameter();
     123          134 :         const SUMOTime step = param.depart % DELTA_T == 0 ? param.depart : (param.depart / DELTA_T + 1) * DELTA_T;
     124          134 :         TransportableVector& waiting = myWaiting4Departure[step];
     125          134 :         auto it = std::find(waiting.begin(), waiting.end(), transportable);
     126          134 :         if (it != waiting.end()) {
     127              :             waiting.erase(it);
     128          134 :             if (waiting.size() == 0) {
     129              :                 myWaiting4Departure.erase(step);
     130              :             }
     131              :         }
     132              :     }
     133          219 : }
     134              : 
     135              : 
     136              : MSTransportable*
     137     13800610 : MSTransportableControl::get(const std::string& id) const {
     138              :     std::map<std::string, MSTransportable*>::const_iterator i = myTransportables.find(id);
     139     13800610 :     if (i == myTransportables.end()) {
     140              :         return nullptr;
     141              :     }
     142     13793157 :     return (*i).second;
     143              : }
     144              : 
     145              : 
     146              : void
     147       500416 : MSTransportableControl::erase(MSTransportable* transportable) {
     148       500416 :     const OptionsCont& oc = OptionsCont::getOptions();
     149      1000832 :     if (oc.isSet("personinfo-output")) {
     150          360 :         transportable->tripInfoOutput(OutputDevice::getDeviceByOption("personinfo-output"));
     151      1000472 :     } else if (oc.isSet("tripinfo-output")) {
     152        71344 :         transportable->tripInfoOutput(OutputDevice::getDeviceByOption("tripinfo-output"));
     153       929128 :     } else if (oc.getBool("duration-log.statistics")) {
     154              :         // collecting statistics is a sideffect
     155        21785 :         OutputDevice_String dev;
     156        21785 :         transportable->tripInfoOutput(dev);
     157        21785 :     }
     158       996965 :     if (oc.isSet("vehroute-output") || oc.isSet("personroute-output")) {
     159         4109 :         if (transportable->hasArrived() || oc.getBool("vehroute-output.write-unfinished")) {
     160              :             // @todo: adapt this if we ever introduce person-device.vehroute
     161         7634 :             if (transportable->getBoolParam("has.vehroute.person-device", false, true)) {
     162         7394 :                 if (oc.getBool("vehroute-output.sorted")) {
     163          122 :                     const SUMOTime departure = oc.getBool("vehroute-output.intended-depart") ? transportable->getParameter().depart : transportable->getDeparture();
     164          122 :                     OutputDevice_String od(1);
     165          122 :                     transportable->routeOutput(od, oc.getBool("vehroute-output.route-length"));
     166          122 :                     MSDevice_Vehroutes::writeSortedOutput(&myRouteInfos,
     167          122 :                                                           departure, transportable->getNumericalID(), od.getString());
     168          122 :                 } else {
     169         7150 :                     transportable->routeOutput(*myRouteInfos.routeOut, oc.getBool("vehroute-output.route-length"));
     170              :                 }
     171              :             }
     172              :         }
     173              :     }
     174              :     const std::map<std::string, MSTransportable*>::iterator i = myTransportables.find(transportable->getID());
     175       500416 :     if (i != myTransportables.end()) {
     176       500416 :         if (i->second->hasDeparted()) {
     177       500130 :             myRunningNumber--;
     178              :         }
     179       500416 :         myEndedNumber++;
     180      1198183 :         MSNet::getInstance()->informTransportableStateListener(transportable,
     181       500416 :                 transportable->isPerson() ? MSNet::TransportableState::PERSON_ARRIVED : MSNet::TransportableState::CONTAINER_ARRIVED);
     182       500416 :         delete i->second;
     183              :         myTransportables.erase(i);
     184              :     }
     185       500416 : }
     186              : 
     187              : 
     188              : void
     189          647 : MSTransportableControl::eraseAll() {
     190              :     // avoid taxi device having dangling references to erased customers
     191          647 :     MSDevice_Taxi::allCustomersErased();
     192          879 :     while (loadedBegin() != loadedEnd()) {
     193          232 :         erase(loadedBegin()->second);
     194              :     }
     195          647 : }
     196              : 
     197              : 
     198              : void
     199       125097 : MSTransportableControl::setWaitEnd(const SUMOTime time, MSTransportable* transportable) {
     200       125097 :     const SUMOTime step = time % DELTA_T == 0 ? time : (time / DELTA_T + 1) * DELTA_T;
     201              :     // avoid double registration
     202       125097 :     const TransportableVector& transportables = myWaitingUntil[step];
     203       125097 :     if (std::find(transportables.begin(), transportables.end(), transportable) == transportables.end()) {
     204       125097 :         myWaitingUntil[step].push_back(transportable);
     205       125097 :         myWaitingUntilNumber++;
     206              :     }
     207       125097 : }
     208              : 
     209              : 
     210              : void
     211     81277797 : MSTransportableControl::checkWaiting(MSNet* net, const SUMOTime time) {
     212     81277797 :     myHaveNewWaiting = false;
     213    162864892 :     while (myWaiting4Departure.find(time) != myWaiting4Departure.end()) {
     214       309340 :         TransportableVector& transportables = myWaiting4Departure[time];
     215              :         // we cannot use an iterator here because there might be additions to the vector while proceeding
     216       818771 :         for (auto it = transportables.begin(); it != transportables.end();) {
     217       509577 :             MSTransportable* t = *it;
     218       509577 :             if (myMaxTransportableNumber > 0 && myRunningNumber >= myMaxTransportableNumber) {
     219          104 :                 TransportableVector& nextStep = myWaiting4Departure[time + DELTA_T];
     220          104 :                 nextStep.insert(nextStep.begin(), transportables.begin(), transportables.end());
     221              :                 transportables.clear();
     222              :                 break;
     223       509473 :             } else if (myMaxTransportableNumber == 0) {
     224          160 :                 erase(t);
     225              :                 it = transportables.erase(it);
     226          160 :                 continue;
     227              :             }
     228              :             it = transportables.erase(it);
     229       509313 :             myWaitingForDepartureNumber--;
     230       509313 :             const bool isPerson = t->isPerson();
     231       509313 :             t->setDeparted(time);
     232       509313 :             if (t->proceed(net, time)) {
     233       509271 :                 myRunningNumber++;
     234       706654 :                 MSNet::getInstance()->informTransportableStateListener(t,
     235              :                         isPerson ? MSNet::TransportableState::PERSON_DEPARTED : MSNet::TransportableState::CONTAINER_DEPARTED);
     236       509271 :                 const OptionsCont& oc = OptionsCont::getOptions();
     237      1018542 :                 if (oc.getBool("vehroute-output.sorted")) {
     238          132 :                     const SUMOTime departure = oc.getBool("vehroute-output.intended-depart") ? t->getParameter().depart : time;
     239          264 :                     if (oc.isSet("personroute-output")) {
     240           24 :                         myRouteInfos.departureCounts[departure]++;
     241              :                     } else {
     242          108 :                         MSDevice_Vehroutes::registerTransportableDepart(departure);
     243              :                     }
     244              :                 }
     245              :             } else {
     246            0 :                 erase(t);
     247              :             }
     248              :         }
     249              :         myWaiting4Departure.erase(time);
     250              :     }
     251     81355578 :     while (myWaitingUntil.find(time) != myWaitingUntil.end()) {
     252              :         // make a copy because 0-duration stops might modify the vector
     253        77829 :         const TransportableVector transportables = myWaitingUntil[time];
     254              :         myWaitingUntil.erase(time);
     255       202643 :         for (MSTransportable* t : transportables) {
     256       124820 :             myWaitingUntilNumber--;
     257       124820 :             if (!t->proceed(net, time)) {
     258        18635 :                 erase(t);
     259              :             }
     260              :         }
     261        77829 :     }
     262     81277749 : }
     263              : 
     264              : 
     265              : #ifndef THREAD_POOL
     266              : #ifdef HAVE_FOX
     267              : void
     268         4512 : MSTransportableControl::addPendingRouting(MSTransportable* transportable) {
     269         4512 :     myPendingRouting.push_back(transportable);
     270         4512 : }
     271              : 
     272              : 
     273              : void
     274     83067811 : MSTransportableControl::processPendingRouting(MSNet* net, const SUMOTime time) {
     275     83072314 :     for (MSTransportable* t : myPendingRouting) {
     276         4511 :         if (!t->proceed(net, time)) {
     277            0 :             erase(t);
     278              :         }
     279              :     }
     280              :     myPendingRouting.clear();
     281     83067803 : }
     282              : #endif
     283              : #endif
     284              : 
     285              : 
     286              : void
     287           42 : MSTransportableControl::forceDeparture() {
     288           42 :     myRunningNumber++;
     289           42 : }
     290              : 
     291              : 
     292              : void
     293       134628 : MSTransportableControl::addWaiting(const MSEdge* const edge, MSTransportable* transportable) {
     294       134628 :     myWaiting4Vehicle[edge].push_back(transportable);
     295       134628 :     myWaitingForVehicleNumber++;
     296       134628 :     myHaveNewWaiting = true;
     297       134628 :     if (myAbortWaitingTimeout >= 0) {
     298           16 :         transportable->setAbortWaiting(myAbortWaitingTimeout);
     299              :     }
     300       134628 : }
     301              : 
     302              : 
     303              : bool
     304           83 : MSTransportableControl::hasAnyWaiting(const MSEdge* edge, SUMOVehicle* vehicle) const {
     305              :     const auto wait = myWaiting4Vehicle.find(edge);
     306           83 :     if (wait != myWaiting4Vehicle.end()) {
     307           44 :         for (const MSTransportable* t : wait->second) {
     308              :             if (t->isWaitingFor(vehicle)
     309           39 :                     && vehicle->allowsBoarding(t)
     310           78 :                     && vehicle->isStoppedInRange(t->getEdgePos(), MSGlobals::gStopTolerance, true)) {
     311              :                 return true;
     312              :             }
     313              :         }
     314              :     }
     315              :     return false;
     316              : }
     317              : 
     318              : 
     319              : bool
     320      5923783 : MSTransportableControl::loadAnyWaiting(const MSEdge* edge, SUMOVehicle* vehicle, SUMOTime& timeToLoadNext, SUMOTime& stopDuration, MSTransportable* const force) {
     321              :     bool ret = false;
     322              :     const auto wait = myWaiting4Vehicle.find(edge);
     323      5923783 :     if (wait != myWaiting4Vehicle.end()) {
     324      4152950 :         const SUMOTime currentTime = SIMSTEP;
     325      4152950 :         TransportableVector& transportables = wait->second;
     326      4688675 :         for (TransportableVector::iterator i = transportables.begin(); i != transportables.end();) {
     327      4629530 :             MSTransportable* const t = *i;
     328      9205707 :             if (t->isWaitingFor(vehicle) && (t == force ||
     329      4576177 :                                              (vehicle->allowsBoarding(t)
     330      4330545 :                                               && timeToLoadNext - DELTA_T <= currentTime
     331      4166614 :                                               && vehicle->isStoppedInRange(t->getEdgePos(), MSGlobals::gStopTolerance)))) {
     332      4163393 :                 edge->removeTransportable(t);
     333      4163393 :                 vehicle->addTransportable(t);
     334        69588 :                 if (myAbortWaitingTimeout >= 0) {
     335            0 :                     t->setAbortWaiting(-1);
     336              :                 }
     337        69588 :                 if (timeToLoadNext >= 0) { // meso does not have loading times
     338        75588 :                     const SUMOTime loadingDuration = (SUMOTime)((double)vehicle->getVehicleType().getLoadingDuration(t->isPerson()) * t->getVehicleType().getBoardingFactor());
     339              :                     //update the time point at which the next transportable can be loaded on the vehicle
     340        37794 :                     if (timeToLoadNext > currentTime - DELTA_T) {
     341        34503 :                         timeToLoadNext += loadingDuration;
     342              :                     } else {
     343         3291 :                         timeToLoadNext = currentTime + loadingDuration;
     344              :                     }
     345              :                 }
     346              : 
     347        69588 :                 static_cast<MSStageDriving*>(t->getCurrentStage())->setVehicle(vehicle);
     348        69588 :                 if (t->getCurrentStage()->getOriginStop() != nullptr) {
     349        64119 :                     t->getCurrentStage()->getOriginStop()->removeTransportable(*i);
     350              :                 }
     351              :                 i = transportables.erase(i);
     352        69588 :                 myWaitingForVehicleNumber--;
     353              :                 ret = true;
     354              :             } else {
     355              :                 ++i;
     356              :             }
     357              :         }
     358        59145 :         if (transportables.empty()) {
     359              :             myWaiting4Vehicle.erase(wait);
     360              :         }
     361        59145 :         if (ret && timeToLoadNext >= 0) {
     362              :             //if the time a transportable needs to get loaded on the vehicle extends the duration of the stop of the vehicle extend
     363              :             //the duration by setting it to the loading duration of the transportable
     364         8253 :             stopDuration = MAX2(stopDuration, timeToLoadNext - currentTime);
     365              :         }
     366              :     }
     367      1829978 :     return ret;
     368              : }
     369              : 
     370              : 
     371              : bool
     372     89441166 : MSTransportableControl::hasTransportables() const {
     373     89441166 :     return !myTransportables.empty();
     374              : }
     375              : 
     376              : 
     377              : bool
     378     72769366 : MSTransportableControl::hasNonWaiting() const {
     379     72769366 :     return !myWaiting4Departure.empty() || getMovingNumber() > 0 || myWaitingUntilNumber > 0 || myHaveNewWaiting;
     380              : }
     381              : 
     382              : 
     383              : int
     384        86116 : MSTransportableControl::getActiveCount() {
     385        86116 :     return (int)myWaiting4Departure.size() + myRunningNumber - myWaitingForVehicleNumber;
     386              : }
     387              : 
     388              : 
     389              : int
     390     72073254 : MSTransportableControl::getMovingNumber() const {
     391     72073254 :     return myMovementModel->getActiveNumber() + myAccessNumber;
     392              : }
     393              : 
     394              : 
     395              : int
     396         7752 : MSTransportableControl::getRidingNumber() const {
     397         7752 :     return myRunningNumber - myWaitingUntilNumber - myWaitingForVehicleNumber - getMovingNumber();
     398              : }
     399              : 
     400              : int
     401        12756 : MSTransportableControl::getDepartedNumber() const {
     402        12756 :     return myLoadedNumber - myWaitingForDepartureNumber - myDiscardedNumber;
     403              : }
     404              : 
     405              : void
     406         8736 : MSTransportableControl::abortAnyWaitingForVehicle() {
     407        10669 :     for (const auto& it : myWaiting4Vehicle) {
     408         1933 :         const MSEdge* edge = it.first;
     409        66567 :         for (MSTransportable* const p : it.second) {
     410        64634 :             edge->removeTransportable(p);
     411        64634 :             MSStageDriving* stage = dynamic_cast<MSStageDriving*>(p->getCurrentStage());
     412        64634 :             const std::string waitDescription = stage == nullptr ? "waiting" : stage->getWaitingDescription();
     413       129268 :             WRITE_WARNING(p->getObjectType() + " '" + p->getID() + "' aborted " + waitDescription + ".");
     414        64634 :             if (myAbortWaitingTimeout >= 0) {
     415            0 :                 p->setAbortWaiting(-1);
     416              :             }
     417        64634 :             erase(p);
     418              :         }
     419              :     }
     420              :     myWaiting4Vehicle.clear();
     421         8736 :     myWaitingForVehicleNumber = 0;
     422         8736 : }
     423              : 
     424              : void
     425          108 : MSTransportableControl::abortWaitingForVehicle(MSTransportable* t) {
     426          108 :     const MSEdge* edge = t->getEdge();
     427              :     auto it = myWaiting4Vehicle.find(edge);
     428          108 :     if (it != myWaiting4Vehicle.end()) {
     429          108 :         TransportableVector& waiting = it->second;
     430          108 :         auto it2 = std::find(waiting.begin(), waiting.end(), t);
     431          108 :         if (it2 != waiting.end()) {
     432          108 :             if (myAbortWaitingTimeout >= 0) {
     433           16 :                 (*it2)->setAbortWaiting(-1);
     434              :             }
     435              :             waiting.erase(it2);
     436          108 :             myWaitingForVehicleNumber--;
     437              :         }
     438              :     }
     439          108 : }
     440              : 
     441              : void
     442           42 : MSTransportableControl::abortWaiting(MSTransportable* t) {
     443           84 :     for (std::map<SUMOTime, TransportableVector>::iterator it = myWaiting4Departure.begin(); it != myWaiting4Departure.end(); ++it) {
     444           42 :         TransportableVector& ts = it->second;
     445           42 :         TransportableVector::iterator it2 = std::find(ts.begin(), ts.end(), t);
     446           42 :         if (it2 != ts.end()) {
     447              :             ts.erase(it2);
     448              :         }
     449              :     }
     450           42 :     for (std::map<SUMOTime, TransportableVector>::iterator it = myWaitingUntil.begin(); it != myWaitingUntil.end(); ++it) {
     451            0 :         TransportableVector& ts = it->second;
     452            0 :         TransportableVector::iterator it2 = std::find(ts.begin(), ts.end(), t);
     453            0 :         if (it2 != ts.end()) {
     454              :             ts.erase(it2);
     455              :         }
     456              :     }
     457           42 : }
     458              : 
     459              : 
     460              : MSTransportable*
     461       302991 : MSTransportableControl::buildPerson(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan,
     462              :                                     SumoRNG* rng) const {
     463       302991 :     const double speedFactor = vtype->computeChosenSpeedDeviation(pars->speedFactor, rng);
     464       302991 :     return new MSPerson(pars, vtype, plan, speedFactor);
     465              : }
     466              : 
     467              : 
     468              : MSTransportable*
     469       196944 : MSTransportableControl::buildContainer(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan) const {
     470       196944 :     return new MSTransportable(pars, vtype, plan, false);
     471              : }
     472              : 
     473              : 
     474              : void
     475           53 : MSTransportableControl::saveState(OutputDevice& out) {
     476           53 :     std::ostringstream oss;
     477          318 :     oss << myRunningNumber << " " << myLoadedNumber << " " << myEndedNumber << " " << myWaitingForDepartureNumber << " " << myArrivedNumber << " " << myDiscardedNumber;
     478          159 :     oss << " " << myJammedNumber << " " << myWaitingForVehicleNumber << " " << myHaveNewWaiting;
     479           53 :     out.writeAttr(SUMO_ATTR_STATE, oss.str());
     480          268 :     for (const auto& it : myTransportables) {
     481          215 :         it.second->saveState(out);
     482              :     }
     483           53 : }
     484              : 
     485              : 
     486              : void
     487           57 : MSTransportableControl::loadState(const std::string& state) {
     488           57 :     std::istringstream iss(state);
     489           57 :     iss >> myRunningNumber >> myLoadedNumber >> myEndedNumber >> myWaitingForDepartureNumber >> myArrivedNumber >> myDiscardedNumber;
     490           57 :     iss >> myJammedNumber >> myWaitingForVehicleNumber >> myHaveNewWaiting;
     491           57 : }
     492              : 
     493              : void
     494        10203 : MSTransportableControl::clearState() {
     495        40200 :     for (std::map<std::string, MSTransportable*>::iterator i = myTransportables.begin(); i != myTransportables.end(); ++i) {
     496        29997 :         delete (*i).second;
     497              :     }
     498              :     myTransportables.clear();
     499              :     myWaiting4Vehicle.clear();
     500              :     myWaiting4Departure.clear();
     501              :     myWaitingUntil.clear();
     502        10203 :     myLoadedNumber = 0;
     503        10203 :     myDiscardedNumber = 0;
     504        10203 :     myRunningNumber = 0;
     505        10203 :     myJammedNumber = 0;
     506        10203 :     myWaitingForDepartureNumber = 0;
     507        10203 :     myWaitingForVehicleNumber = 0;
     508        10203 :     myWaitingUntilNumber = 0;
     509        10203 :     myEndedNumber = 0;
     510        10203 :     myArrivedNumber = 0;
     511        10203 :     myHaveNewWaiting = false;
     512        10203 :     if (myMovementModel != myNonInteractingModel) {
     513         6134 :         myMovementModel->clearState();
     514              :     }
     515        10203 :     myNonInteractingModel->clearState();
     516        10203 : }
     517              : 
     518              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1