Line data Source code
1 : #include "Dynamic/Env/Event/EventPopQueue.hpp" 2 : 3 : #include <limits> 4 : 5 : #include "Dynamic/Env/Connection.hpp" 6 : #include "Dynamic/Env/Env.hpp" 7 : #include "Dynamic/Env/Event/EventDespawnVehicle.hpp" 8 : #include "Dynamic/Env/Event/EventSpawnVehicle.hpp" 9 : #include "Dynamic/Env/Event/EventUpdateVehicle.hpp" 10 : #include "Dynamic/Env/Lane.hpp" 11 : #include "Dynamic/Env/Vehicle.hpp" 12 : 13 : using namespace std; 14 : using namespace Dynamic::Env; 15 : 16 0 : EventPopQueue::EventPopQueue(Time t_, Lane &lane_): 17 : Event(t_), 18 0 : lane(lane_) {} 19 : 20 0 : void EventPopQueue::process(Env &env) { 21 0 : if(env.getTime() < lane.nextPopTime - TIME_EPSILON) 22 0 : return; 23 : 24 0 : if(lane.stopped.empty()) 25 : return; 26 : 27 0 : auto p = lane.stopped.front(); 28 : 29 0 : auto &[vehicle, action] = p; 30 : 31 : // clang-format off 32 0 : if( 33 0 : action->connection.isRed() 34 0 : || action->connection.toLane.isFull() 35 : ) { 36 0 : return; 37 : } 38 : // clang-format on 39 : 40 0 : Time yieldUntil = action->connection.mustYieldUntil(); 41 0 : if(yieldUntil > env.getTime()) { 42 : // Vehicle must yield 43 0 : env.pushEvent(make_shared<EventPopQueue>( 44 : yieldUntil, 45 : lane 46 : )); 47 : 48 0 : return; 49 : } 50 : 51 : // Move vehicle at front of queue 52 0 : lane.stopped.pop(); 53 : 54 0 : vehicle.get().moveToAnotherEdge(env, action); 55 : 56 : // Change lastUpdateTime for despawning 57 : // clang-format off 58 0 : if( 59 0 : env.getDespawnTime() < numeric_limits<Time>::infinity() && 60 0 : !lane.stopped.empty() 61 : ) { 62 : // clang-format on 63 0 : Vehicle &frontVehicle = lane.stopped.front().first.get(); 64 0 : frontVehicle.lastUpdateTime = env.getTime(); 65 0 : env.pushEvent(make_shared<EventDespawnVehicle>( 66 0 : env.getTime() + env.getDespawnTime(), 67 0 : frontVehicle.id 68 : )); 69 : } 70 : 71 : /* 72 : * Process next waiting vehicle (instantiate vehicle or get vehicle from 73 : * previous queue) 74 : */ 75 0 : lane.processNextWaitingVehicle(env); 76 : 77 : // TODO: check if EventPopQueue should only be created if !stopped.empty() 78 : // Schedule next EventPopQueue 79 0 : Time tFuture = env.getTime() + Lane::QUEUE_PERIOD; 80 0 : env.pushEvent(make_shared<EventPopQueue>( 81 : tFuture, 82 : lane 83 : )); 84 0 : lane.nextPopTime = tFuture; 85 : 86 : // If queue dissipated, pull from every lane. 87 0 : if(lane.stopped.empty()) { 88 0 : for(Connection &connection: lane.getIncomingConnections()) { 89 0 : Lane &prevLane = connection.fromLane; 90 0 : env.pushEvent(make_shared<EventPopQueue>( 91 : tFuture, 92 : prevLane 93 : )); 94 : } 95 : } 96 : }