]> git.tdb.fi Git - r2c2.git/commitdiff
Unify destination and waypoints
authorMikko Rasa <tdb@tdb.fi>
Wed, 11 Feb 2015 12:43:15 +0000 (14:43 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 11 Feb 2015 12:43:15 +0000 (14:43 +0200)
Destination is really just a special case of a waypoint, so there's no
point in keeping it separate.  It just adds duplicated logic, which was
about to get worse with some upcoming new features.

source/libr2c2/timetable.cpp
source/libr2c2/trainrouteplanner.cpp
source/libr2c2/trainrouteplanner.h
source/libr2c2/trainrouter.cpp
source/libr2c2/trainrouter.h

index 2fadcd54b4f55d210b7c3bee6eab58a382f2f4e0..0d68a7be8aea5c88f515a60192e4aac62d6267ce 100644 (file)
@@ -178,7 +178,7 @@ void Timetable::update_route()
        {
                if(i->type==ARRIVE)
                {
-                       train.ai_message(Message("set-destination", i->target));
+                       train.ai_message(Message("add-waypoint", i->target));
                        break;
                }
                else if(i->type==DEPART)
index 5bffec1d899c535fc295bf2847faea29d7a2987d..08d787805140610a41af21100c4894ea0870c615 100644 (file)
@@ -22,7 +22,7 @@ TrainRoutePlanner::TrainRoutePlanner(Layout &layout):
        for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
        {
                TrainRoutingInfo info(*i->second);
-               if(info.destination)
+               if(!info.waypoints.empty())
                        routed_trains.push_back(info);
        }
 }
@@ -216,24 +216,18 @@ TrainRoutePlanner::TrainRoutingInfo::TrainRoutingInfo(Train &t):
        speed(train->get_maximum_speed()),
        first_noncritical(train->get_first_noncritical_block().block()),
        router(train->get_ai_of_type<TrainRouter>()),
-       destination(0),
+       waypoints(router ? router->get_n_waypoints() : 0),
        has_duration(false)
 {
-       if(router)
+       if(!waypoints.empty())
        {
-               destination = router->get_destination();
-               if(destination)
+               metrics.resize(waypoints.size());
+               for(unsigned i=0; i<waypoints.size(); ++i)
                {
-                       waypoints.resize(router->get_n_waypoints());
-                       metrics.resize(waypoints.size()+1);
-                       metrics[0] = &router->get_metric(-1);
-                       for(unsigned i=0; i<waypoints.size(); ++i)
-                       {
-                               waypoints[i] = &router->get_waypoint(i);
-                               metrics[i+1] = &router->get_metric(i);
-                       }
-                       has_duration = router->get_trip_duration();
+                       waypoints[i] = &router->get_waypoint(i);
+                       metrics[i] = &router->get_metric(i);
                }
+               has_duration = router->get_trip_duration();
        }
 
        // If no maximum speed is specified, use a sensible default
@@ -278,7 +272,7 @@ TrainRoutePlanner::TrainRoutingState::TrainRoutingState(TrainRoutingInfo &inf):
        state(MOVING),
        delay(info->router->get_departure_delay()),
        duration(info->router->get_trip_duration()),
-       waypoint(info->waypoints.empty() ? -1 : 0),
+       waypoint(0),
        blocked_by(-1)
 {
        const Vehicle *veh = &info->train->get_vehicle(0);
@@ -352,16 +346,16 @@ bool TrainRoutePlanner::TrainRoutingState::check_arrival()
 {
        TrackIter next_track = track.next(path);
 
-       if(waypoint<0 && info->destination->has_track(*track) && !info->destination->has_track(*next_track))
-       {
-               state = ARRIVED;
-               return true;
-       }
-       else if(waypoint>=0 && info->waypoints[waypoint]->has_track(*track) && !info->waypoints[waypoint]->has_track(*next_track))
+       const TrackChain *wp_chain = info->waypoints[waypoint];
+       if(wp_chain->has_track(*track) && !wp_chain->has_track(*next_track))
        {
-               ++waypoint;
-               if(waypoint>=static_cast<int>(info->waypoints.size()))
-                       waypoint = -1;
+               if(waypoint+1<info->waypoints.size())
+                       ++waypoint;
+               else
+               {
+                       state = ARRIVED;
+                       return true;
+               }
        }
 
        if(info->first_noncritical->has_track(*track))
@@ -449,7 +443,7 @@ void TrainRoutePlanner::TrainRoutingState::advance_track(unsigned next_path)
 void TrainRoutePlanner::TrainRoutingState::update_estimate()
 {
        TrackIter iter = track.reverse(path);
-       float distance = info->metrics[waypoint+1]->get_distance_from(*iter.track(), iter.entry());
+       float distance = info->metrics[waypoint]->get_distance_from(*iter.track(), iter.entry());
        distance += track->get_type().get_path_length(path)-offset;
        remaining_estimate = distance;
 }
index 34dcce69daeddb8a5f8d20255497eca8a453fcef..b76d663ab5f8caea318ec2bf612bc1d4ab9d83c4 100644 (file)
@@ -34,7 +34,6 @@ private:
                float speed;
                Block *first_noncritical;
                TrainRouter *router;
-               const TrackChain *destination;
                std::vector<const TrackChain *> waypoints;
                std::vector<const TrainRouteMetric *> metrics;
                bool has_duration;
@@ -78,7 +77,7 @@ private:
                TrainState state;
                Msp::Time::TimeDelta delay;
                Msp::Time::TimeDelta duration;
-               int waypoint;
+               unsigned waypoint;
                float distance_traveled;
                float remaining_estimate;
                Msp::Time::TimeDelta wait_time;
index 266bc6fc3641f4e6a72c069771132cb734f0546b..2d6ab54550284f636a16d52870fee744f196b405 100644 (file)
@@ -16,8 +16,7 @@ TrainRouter::TrainRouter(Train &t):
        TrainAI(t),
        priority(0),
        arrival(ON_THE_WAY),
-       destination(0),
-       destination_changed(false),
+       waypoints_changed(false),
        metrics_stale(false),
        current_sequence(0),
        sequence_check_pending(false)
@@ -47,7 +46,6 @@ bool TrainRouter::set_route(const Route *r)
                create_lead_route();
        }
 
-       destination = 0;
        waypoints.clear();
        sequence_points.clear();
        current_sequence = 0;
@@ -122,15 +120,18 @@ void TrainRouter::route_changed()
 
 void TrainRouter::set_destination(const TrackChain &d)
 {
-       destination = &d;
-       destination_changed = true;
+       if(waypoints.empty())
+               waypoints.push_back(&d);
+       else
+               waypoints.back() = &d;
+       waypoints_changed = true;
        metrics_stale = true;
 }
 
 void TrainRouter::add_waypoint(const TrackChain &wp)
 {
        waypoints.push_back(&wp);
-       destination_changed = true;
+       waypoints_changed = true;
        metrics_stale = true;
 }
 
@@ -144,23 +145,23 @@ const TrackChain &TrainRouter::get_waypoint(unsigned index) const
 
 const TrainRouteMetric &TrainRouter::get_metric(int index) const
 {
-       if(!destination)
+       if(waypoints.empty())
                throw logic_error("no metrics");
        else if(metrics_stale)
                throw logic_error("metrics are stale");
 
        if(index<0)
-               return *metrics.front();
+               return *metrics.back();
        else if(static_cast<unsigned>(index)>=waypoints.size())
                throw out_of_range("TrainRouter::get_metric");
        else
-               return *metrics[index+1];
+               return *metrics[index];
 }
 
 void TrainRouter::set_departure_delay(const Time::TimeDelta &d)
 {
        delay = d;
-       destination_changed = true;
+       waypoints_changed = true;
 }
 
 void TrainRouter::set_trip_duration(const Time::TimeDelta &d)
@@ -213,12 +214,12 @@ void TrainRouter::tick(const Time::TimeDelta &dt)
        else if(duration)
                duration = max(duration-dt, Time::zero);
 
-       if(destination_changed && !planner)
+       if(waypoints_changed && !planner)
                start_planning(train.get_layout());
 
        if(planner && planner->check()!=TrainRoutePlanner::PENDING)
        {
-               destination_changed = false;
+               waypoints_changed = false;
                if(planner->get_result()==TrainRoutePlanner::COMPLETE)
                {
                        const list<Route *> &planned_routes = planner->get_routes_for(train);
@@ -245,8 +246,8 @@ void TrainRouter::tick(const Time::TimeDelta &dt)
 
        if(arrival==RESERVED_TO_END && !train.get_speed())
        {
-               signal_arrived.emit(destination);
-               signal_event.emit(Message("arrived", destination));
+               signal_arrived.emit(waypoints.back());
+               signal_event.emit(Message("arrived", waypoints.back()));
                arrival = ARRIVED;
        }
        else if(arrival==ARRIVED && !train.get_block_allocator().is_active())
@@ -351,7 +352,7 @@ void TrainRouter::train_advanced(Block &block)
 {
        BlockIter b_iter = train.get_block_allocator().iter_for(block);
 
-       if(!waypoints.empty())
+       if(waypoints.size()>1)
        {
                // A waypoint is considered reached when the train has advanced through it.
                const TrackChain &wp = *waypoints.front();
@@ -402,15 +403,14 @@ void TrainRouter::create_metrics()
 
        metrics_stale = false;
 
-       if(!destination)
+       if(waypoints.empty())
                return;
 
-       metrics.push_back(new TrainRouteMetric(*destination));
        for(vector<const TrackChain *>::const_iterator i=waypoints.begin(); i!=waypoints.end(); ++i)
                metrics.push_back(new TrainRouteMetric(**i));
 
-       for(unsigned i=metrics.size(); --i>0; )
-               metrics[i]->chain_to(*metrics[(i+1)%metrics.size()]);
+       for(unsigned i=metrics.size()-1; i-->0; )
+               metrics[i]->chain_to(*metrics[i+1]);
 }
 
 bool TrainRouter::create_lead_route()
index 3d8b72246f2d02ce492b7c6672ba9a4ee5c1711a..80908d51b863ab63294f35df5dd994d197480ab2 100644 (file)
@@ -57,9 +57,8 @@ private:
        RouteList routes;
        RouteList::iterator reserving_route;
        ArrivalState arrival;
-       const TrackChain *destination;
        std::vector<const TrackChain *> waypoints;
-       bool destination_changed;
+       bool waypoints_changed;
        std::vector<TrainRouteMetric *> metrics;
        bool metrics_stale;
        std::list<SequencePoint> sequence_points;
@@ -84,7 +83,7 @@ private:
 
 public:
        void set_destination(const TrackChain &);
-       const TrackChain *get_destination() const { return destination; }
+       const TrackChain *get_destination() const { return waypoints.empty() ? 0 : waypoints.back(); }
        void add_waypoint(const TrackChain &);
        unsigned get_n_waypoints() const { return waypoints.size(); }
        const TrackChain &get_waypoint(unsigned) const;