#include <list>
#include <vector>
+#include <msp/core/thread.h>
#include <msp/time/timedelta.h>
#include "trackiter.h"
+#include "trainrouter.h"
namespace R2C2 {
class Route;
class Track;
class Train;
-class TrainRouter;
class TrainRoutePlanner
{
+public:
+ enum Result
+ {
+ PENDING,
+ COMPLETE,
+ FAILED
+ };
+
private:
struct TrainRoutingState;
{
Train *train;
float speed;
+ Block *first_noncritical;
TrainRouter *router;
- Route *route;
- std::list<TrainRoutingState *> waits;
+ const TrackChain *destination;
+ std::vector<const TrackChain *> waypoints;
+ std::vector<const TrainRouteMetric *> metrics;
+ bool has_duration;
+ std::list<Route *> routes;
+ Track *track_history[2];
+ std::list<TrainRouter::SequencePoint> sequence;
TrainRoutingInfo(Train &);
};
{
TrainRoutingInfo *info;
TrackIter track;
- unsigned path;
+ unsigned char path;
+ bool critical;
OccupiedTrack *occupied_tracks;
float offset;
float back_offset;
TrainState state;
Msp::Time::TimeDelta delay;
+ Msp::Time::TimeDelta duration;
int waypoint;
+ float distance_traveled;
+ float remaining_estimate;
+ Msp::Time::TimeDelta wait_time;
int blocked_by;
TrainRoutingState(TrainRoutingInfo &);
~TrainRoutingState();
Msp::Time::TimeDelta get_time_to_next_track() const;
- bool is_occupied(Track &) const;
+ bool is_occupying(Track &) const;
bool check_arrival();
void advance(float);
+ void advance(const Msp::Time::TimeDelta &);
void advance_track(unsigned);
+ void update_estimate();
};
struct RoutingStep
{
Msp::Time::TimeDelta time;
+ Msp::Time::TimeDelta penalty;
+ Msp::Time::TimeDelta cost_estimate;
std::vector<TrainRoutingState> trains;
- RoutingStep *prev;
+ const RoutingStep *prev;
RoutingStep();
- RoutingStep(RoutingStep *);
+ RoutingStep(const RoutingStep *);
- void create_successors(std::list<RoutingStep> &);
+ void create_successors(std::list<RoutingStep> &) const;
bool update_states();
bool check_deadlocks() const;
int get_occupant(Track &) const;
int find_next_train() const;
void advance(const Msp::Time::TimeDelta &);
+ void update_estimate();
bool is_viable() const;
bool is_goal() const;
bool operator<(const RoutingStep &) const;
};
+ class PlanningThread: public Msp::Thread
+ {
+ private:
+ TrainRoutePlanner &planner;
+
+ public:
+ PlanningThread(TrainRoutePlanner &);
+
+ private:
+ virtual void main();
+ };
+
std::vector<TrainRoutingInfo> routed_trains;
std::list<RoutingStep> steps;
+ std::list<RoutingStep> queue;
+ const RoutingStep *goal;
+ Result result;
+ PlanningThread *thread;
public:
TrainRoutePlanner(Layout &);
-
- void plan();
+ ~TrainRoutePlanner();
+
+ Result plan();
+ void plan_async();
+ Result check();
+ Result get_result() { return result; }
+ const std::list<Route *> &get_routes_for(const Train &) const;
+ const std::list<TrainRouter::SequencePoint> &get_sequence_for(const Train &) const;
private:
- void add_steps(RoutingStep &);
- void create_routes(RoutingStep &);
+ const TrainRoutingInfo &get_train_info(const Train &) const;
+ const RoutingStep &get_step();
+ void prepare_plan();
+ void create_plan();
+ void add_steps(const RoutingStep &);
+ void finalize_plan();
};
} // namespace R2C2