1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! Intermediate structures so that sim and game crates don't have a cyclic dependency.

use geom::{Angle, Distance, PolyLine, Pt2D, Time};
use map_model::{BuildingID, Map, ParkingLotID, Traversable, TurnID};

use crate::{CarID, PedestrianID, PersonID, VehicleType};

#[derive(Clone)]
pub struct DrawPedestrianInput {
    pub id: PedestrianID,
    pub pos: Pt2D,
    pub facing: Angle,
    pub waiting_for_turn: Option<TurnID>,
    pub preparing_bike: bool,
    pub waiting_for_bus: bool,
    pub on: Traversable,
}

pub struct DrawPedCrowdInput {
    pub low: Distance,
    pub high: Distance,
    pub members: Vec<PedestrianID>,
    pub location: PedCrowdLocation,
}

#[derive(Clone)]
pub enum PedCrowdLocation {
    /// bool is contraflow
    Sidewalk(Traversable, bool),
    BldgDriveway(BuildingID),
    LotDriveway(ParkingLotID),
}

#[derive(Clone)]
pub struct DrawCarInput {
    pub id: CarID,
    pub waiting_for_turn: Option<TurnID>,
    pub status: CarStatus,
    pub show_parking_intent: bool,
    /// Front of the car
    pub on: Traversable,
    /// Possibly the rest
    pub partly_on: Vec<Traversable>,
    pub label: Option<String>,

    // Starts at the BACK of the car.
    pub body: PolyLine,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum CarStatus {
    Moving,
    Parked,
}

pub struct UnzoomedAgent {
    /// None means a pedestrian.
    pub vehicle_type: Option<VehicleType>,
    pub pos: Pt2D,
    /// None means a bus.
    pub person: Option<PersonID>,
    /// True only for cars currently looking for parking. I don't want this struct to grow, but
    /// this is important enough to call out here.
    pub parking: bool,
}

// TODO Can we return borrows instead? Nice for time travel, not for main sim?
// actually good for main sim too; we're constantly calculating stuff while sim is paused
// otherwise? except we don't know what to calculate. maybe cache it?
pub trait GetDrawAgents {
    fn time(&self) -> Time;
    /// Every time the time changes, this should increase. For smoothly animating stuff.
    fn step_count(&self) -> usize;
    fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCarInput>;
    fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrianInput>;
    fn get_draw_cars(&self, on: Traversable, map: &Map) -> Vec<DrawCarInput>;
    fn get_draw_peds(
        &self,
        on: Traversable,
        map: &Map,
    ) -> (Vec<DrawPedestrianInput>, Vec<DrawPedCrowdInput>);
    fn get_all_draw_cars(&self, map: &Map) -> Vec<DrawCarInput>;
    fn get_all_draw_peds(&self, map: &Map) -> Vec<DrawPedestrianInput>;
    fn get_unzoomed_agents(&self, map: &Map) -> Vec<UnzoomedAgent>;
}

pub struct DontDrawAgents;

impl GetDrawAgents for DontDrawAgents {
    fn time(&self) -> Time {
        Time::START_OF_DAY
    }
    fn step_count(&self) -> usize {
        0
    }
    fn get_draw_car(&self, _: CarID, _: &Map) -> Option<DrawCarInput> {
        None
    }
    fn get_draw_ped(&self, _: PedestrianID, _: &Map) -> Option<DrawPedestrianInput> {
        None
    }
    fn get_draw_cars(&self, _: Traversable, _: &Map) -> Vec<DrawCarInput> {
        Vec::new()
    }
    fn get_draw_peds(
        &self,
        _: Traversable,
        _: &Map,
    ) -> (Vec<DrawPedestrianInput>, Vec<DrawPedCrowdInput>) {
        (Vec::new(), Vec::new())
    }
    fn get_all_draw_cars(&self, _: &Map) -> Vec<DrawCarInput> {
        Vec::new()
    }
    fn get_all_draw_peds(&self, _: &Map) -> Vec<DrawPedestrianInput> {
        Vec::new()
    }
    fn get_unzoomed_agents(&self, _: &Map) -> Vec<UnzoomedAgent> {
        Vec::new()
    }
}