1 use crate::{
2     AgentID, CarID, OffMapLocation, ParkingSpot, PedestrianID, PersonID, TripID, TripMode,
3 };
4 use geom::Duration;
5 use map_model::{
6     BuildingID, BusRouteID, BusStopID, CompressedMovementID, IntersectionID, LaneID, Map, Path,
7     PathRequest, Traversable,
8 };
9 use serde::{Deserialize, Serialize};
10 
11 // Many of these were created for a test framework that's been abandoned. They could be removed or
12 // have their API adjusted, but it's not urgent; publishing an event that's not used by Analytics
13 // has no performance impact.
14 #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
15 pub enum Event {
16     CarReachedParkingSpot(CarID, ParkingSpot),
17     CarLeftParkingSpot(CarID, ParkingSpot),
18 
19     BusArrivedAtStop(CarID, BusRouteID, BusStopID),
20     BusDepartedFromStop(CarID, BusRouteID, BusStopID),
21     // How long waiting at the stop?
22     PassengerBoardsTransit(PersonID, CarID, BusRouteID, BusStopID, Duration),
23     PassengerAlightsTransit(PersonID, CarID, BusRouteID, BusStopID),
24 
25     PersonEntersBuilding(PersonID, BuildingID),
26     PersonLeavesBuilding(PersonID, BuildingID),
27     // None if aborted
28     PersonLeavesMap(
29         PersonID,
30         Option<AgentID>,
31         IntersectionID,
32         Option<OffMapLocation>,
33     ),
34     PersonEntersMap(PersonID, AgentID, IntersectionID, Option<OffMapLocation>),
35     PersonEntersRemoteBuilding(PersonID, OffMapLocation),
36     PersonLeavesRemoteBuilding(PersonID, OffMapLocation),
37 
38     PedReachedParkingSpot(PedestrianID, ParkingSpot),
39 
40     BikeStoppedAtSidewalk(CarID, LaneID),
41 
42     // If the agent is a transit vehicle, then include a count of how many passengers are on
43     // board.
44     AgentEntersTraversable(AgentID, Traversable, Option<usize>),
45     IntersectionDelayMeasured(CompressedMovementID, Duration, AgentID),
46 
47     TripFinished {
48         trip: TripID,
49         mode: TripMode,
50         total_time: Duration,
51         blocked_time: Duration,
52     },
53     TripAborted(TripID),
54     TripPhaseStarting(TripID, PersonID, Option<PathRequest>, TripPhaseType),
55 
56     // Just use for parking replanning. Not happy about copying the full path in here, but the way
57     // to plumb info into Analytics is Event.
58     PathAmended(Path),
59 
60     Alert(AlertLocation, String),
61 }
62 
63 #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
64 pub enum AlertLocation {
65     Nil,
66     Intersection(IntersectionID),
67     Person(PersonID),
68     Building(BuildingID),
69 }
70 
71 #[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
72 pub enum TripPhaseType {
73     Driving,
74     Walking,
75     Biking,
76     Parking,
77     WaitingForBus(BusRouteID, BusStopID),
78     // What stop did they board at?
79     RidingBus(BusRouteID, BusStopID, CarID),
80     Aborted,
81     Finished,
82     DelayedStart,
83     Remote,
84 }
85 
86 impl TripPhaseType {
describe(self, map: &Map) -> String87     pub fn describe(self, map: &Map) -> String {
88         match self {
89             TripPhaseType::Driving => "driving".to_string(),
90             TripPhaseType::Walking => "walking".to_string(),
91             TripPhaseType::Biking => "biking".to_string(),
92             TripPhaseType::Parking => "parking".to_string(),
93             TripPhaseType::WaitingForBus(r, _) => {
94                 format!("waiting for bus {}", map.get_br(r).full_name)
95             }
96             TripPhaseType::RidingBus(r, _, _) => format!("riding bus {}", map.get_br(r).full_name),
97             TripPhaseType::Aborted => "trip aborted due to some bug".to_string(),
98             TripPhaseType::Finished => "trip finished".to_string(),
99             TripPhaseType::DelayedStart => "delayed by previous trip taking too long".to_string(),
100             TripPhaseType::Remote => "remote trip outside the map boundaries".to_string(),
101         }
102     }
103 }
104