]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/trainrouteplanner.h
c4850d46a61c00185f9630b8259885d0582b5f5e
[r2c2.git] / source / libr2c2 / trainrouteplanner.h
1 #ifndef LIBR2C2_TRAINROUTEPLANNER_H_
2 #define LIBR2C2_TRAINROUTEPLANNER_H_
3
4 #include <list>
5 #include <vector>
6 #include <msp/core/thread.h>
7 #include <msp/time/timedelta.h>
8 #include "trackiter.h"
9 #include "trainrouter.h"
10
11 namespace R2C2 {
12
13 class Layout;
14 class Route;
15 class Track;
16 class Train;
17
18 class TrainRoutePlanner
19 {
20 public:
21         enum Result
22         {
23                 PENDING,
24                 COMPLETE,
25                 FAILED
26         };
27
28 private:
29         struct TrainRoutingState;
30
31         struct TrainRoutingInfo
32         {
33                 Train *train;
34                 float speed;
35                 TrainRouter *router;
36                 std::list<Route *> routes;
37                 Track *track_history[2];
38                 std::list<TrainRouter::SequencePoint> sequence;
39
40                 TrainRoutingInfo(Train &);
41         };
42
43         struct OccupiedTrack
44         {
45                 Track *track;
46                 float path_length;
47                 OccupiedTrack *next;
48                 unsigned n_tracks;
49                 unsigned refcount;
50
51                 OccupiedTrack(Track &, unsigned, OccupiedTrack *);
52                 OccupiedTrack(const OccupiedTrack &);
53                 ~OccupiedTrack();
54         };
55
56         enum TrainState
57         {
58                 MOVING,
59                 WAITING,
60                 BLOCKED,
61                 ARRIVED
62         };
63
64         struct TrainRoutingState
65         {
66                 TrainRoutingInfo *info;
67                 TrackIter track;
68                 unsigned path;
69                 OccupiedTrack *occupied_tracks;
70                 float offset;
71                 float back_offset;
72                 TrainState state;
73                 Msp::Time::TimeDelta delay;
74                 Msp::Time::TimeDelta duration;
75                 int waypoint;
76                 float distance_traveled;
77                 float remaining_estimate;
78                 Msp::Time::TimeDelta wait_time;
79                 int blocked_by;
80
81                 TrainRoutingState(TrainRoutingInfo &);
82                 TrainRoutingState(const TrainRoutingState &);
83                 ~TrainRoutingState();
84
85                 Msp::Time::TimeDelta get_time_to_next_track() const;
86                 bool is_occupying(Track &) const;
87                 bool check_arrival();
88                 void advance(float);
89                 void advance(const Msp::Time::TimeDelta &);
90                 void advance_track(unsigned);
91                 void update_estimate();
92         };
93
94         struct RoutingStep
95         {
96                 Msp::Time::TimeDelta time;
97                 Msp::Time::TimeDelta cost_estimate;
98                 std::vector<TrainRoutingState> trains;
99                 const RoutingStep *prev;
100
101                 RoutingStep();
102                 RoutingStep(const RoutingStep *);
103
104                 void create_successors(std::list<RoutingStep> &) const;
105                 bool update_states();
106                 bool check_deadlocks() const;
107                 int get_occupant(Track &) const;
108                 int find_next_train() const;
109                 void advance(const Msp::Time::TimeDelta &);
110                 void update_estimate();
111                 bool is_viable() const;
112                 bool is_goal() const;
113
114                 bool operator<(const RoutingStep &) const;
115         };
116
117         class PlanningThread: public Msp::Thread
118         {
119         private:
120                 TrainRoutePlanner &planner;
121
122         public:
123                 PlanningThread(TrainRoutePlanner &);
124
125         private:
126                 virtual void main();
127         };
128
129         std::vector<TrainRoutingInfo> routed_trains;
130         std::list<RoutingStep> steps;
131         std::list<RoutingStep> queue;
132         const RoutingStep *goal;
133         Result result;
134         PlanningThread *thread;
135
136 public:
137         TrainRoutePlanner(Layout &);
138         ~TrainRoutePlanner();
139
140         Result plan();
141         void plan_async();
142         Result check();
143         Result get_result() { return result; }
144         const std::list<Route *> &get_routes_for(const Train &) const;
145         const std::list<TrainRouter::SequencePoint> &get_sequence_for(const Train &) const;
146 private:
147         const TrainRoutingInfo &get_train_info(const Train &) const;
148         const RoutingStep &get_step();
149         void prepare_plan();
150         void create_plan();
151         void add_steps(const RoutingStep &);
152         void finalize_plan();
153 };
154
155 } // namespace R2C2
156
157 #endif