X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Ftrainrouteplanner.cpp;h=fc62faaa48ab25d6478e42dc55205cc3f5c92f46;hb=f305e582aef0dceafd3b7b00bf9374bb69bdf8b0;hp=22ac5400ea4fb050437ccdff14de77dbafc483e9;hpb=b42a312323d36775ab550630b3ee818c3b948bf6;p=r2c2.git diff --git a/source/libr2c2/trainrouteplanner.cpp b/source/libr2c2/trainrouteplanner.cpp index 22ac540..fc62faa 100644 --- a/source/libr2c2/trainrouteplanner.cpp +++ b/source/libr2c2/trainrouteplanner.cpp @@ -2,6 +2,7 @@ #include "layout.h" #include "route.h" #include "train.h" +#include "trainroutemetric.h" #include "trainrouteplanner.h" #include "trainrouter.h" #include "vehicle.h" @@ -65,24 +66,49 @@ void TrainRoutePlanner::create_routes(const RoutingStep &goal) { for(vector::iterator i=routed_trains.begin(); i!=routed_trains.end(); ++i) { - i->route = new Route(i->train->get_layout()); - i->route->set_name("Router"); - i->route->set_temporary(true); + Route *route = new Route(i->train->get_layout()); + route->set_name("Router"); + route->set_temporary(true); + i->routes.push_front(route); + + for(unsigned j=0; j<3; ++j) + i->track_history[j] = 0; } for(const RoutingStep *i=&goal; i; i=i->prev) { for(vector::const_iterator j=i->trains.begin(); j!=i->trains.end(); ++j) { + Track **history = j->info->track_history; + if(j->track.track()==history[0]) + continue; + if(j->state==WAITING || j->state==BLOCKED) j->info->waits.push_front(&*j); - j->info->route->add_track(*j->track); + + Route *route = j->info->routes.front(); + if(route->has_track(*j->track)) + { + route = new Route(j->info->train->get_layout()); + route->set_name("Router"); + route->set_temporary(true); + for(unsigned k=2; k>0; --k) + route->add_track(*history[k]); + j->info->routes.push_front(route); + } + + if(history[0]) + route->add_track(*history[0]); + for(unsigned k=2; k>0; --k) + history[k] = history[k-1]; + history[0] = j->track.track(); } } for(vector::iterator i=routed_trains.begin(); i!=routed_trains.end(); ++i) { - i->router->set_route(i->route); + for(list::iterator j=i->routes.begin(); j!=i->routes.end(); ++j) + i->router->add_route(**j); const TrainRoutingState *current_wait = 0; for(list::const_iterator j=i->waits.begin(); j!=i->waits.end(); ++j) if(!current_wait || (*j)->track.track()!=current_wait->track.track()) @@ -98,8 +124,7 @@ void TrainRoutePlanner::create_routes(const RoutingStep &goal) TrainRoutePlanner::TrainRoutingInfo::TrainRoutingInfo(Train &t): train(&t), speed(train->get_maximum_speed()), - router(train->get_ai_of_type()), - route(0) + router(train->get_ai_of_type()) { // If no maximum speed is specified, use a sensible default if(!speed) @@ -164,6 +189,8 @@ TrainRoutePlanner::TrainRoutingState::TrainRoutingState(TrainRoutingInfo &inf): break; iter = iter.next(); } + + update_estimate(); } TrainRoutePlanner::TrainRoutingState::TrainRoutingState(const TrainRoutingState &other): @@ -176,6 +203,7 @@ TrainRoutePlanner::TrainRoutingState::TrainRoutingState(const TrainRoutingState state(other.state), delay(other.delay), waypoint(other.waypoint), + remaining_estimate(other.remaining_estimate), blocked_by(other.blocked_by) { ++occupied_tracks->refcount; @@ -241,6 +269,8 @@ void TrainRoutePlanner::TrainRoutingState::advance(float distance) } --occupied_tracks->n_tracks; } + + remaining_estimate -= distance; } void TrainRoutePlanner::TrainRoutingState::advance_track(unsigned next_path) @@ -253,6 +283,14 @@ void TrainRoutePlanner::TrainRoutingState::advance_track(unsigned next_path) offset = 0; } +void TrainRoutePlanner::TrainRoutingState::update_estimate() +{ + TrackIter iter = track.reverse(path); + float distance = info->router->get_metric(waypoint).get_distance_from(*iter.track(), iter.entry()); + distance += track->get_type().get_path_length(path)-offset; + remaining_estimate = distance; +} + TrainRoutePlanner::RoutingStep::RoutingStep(): prev(0) @@ -260,6 +298,7 @@ TrainRoutePlanner::RoutingStep::RoutingStep(): TrainRoutePlanner::RoutingStep::RoutingStep(const RoutingStep *p): time(p->time), + total_estimate(p->total_estimate), trains(p->trains), prev(p) { } @@ -299,6 +338,8 @@ void TrainRoutePlanner::RoutingStep::create_successors(list &new_st if(next_entry_ep.has_path(i)) { train.path = i; + train.update_estimate(); + next.update_estimate(); if(next.is_viable()) new_steps.push_back(next); } @@ -411,8 +452,25 @@ void TrainRoutePlanner::RoutingStep::advance(const Time::TimeDelta &dt) } } +void TrainRoutePlanner::RoutingStep::update_estimate() +{ + for(vector::const_iterator i=trains.begin(); i!=trains.end(); ++i) + { + Time::TimeDelta t = time+(i->remaining_estimate/i->info->speed)*Time::sec+i->delay; + if(i==trains.begin() || t>total_estimate) + total_estimate = t; + } +} + bool TrainRoutePlanner::RoutingStep::is_viable() const { + if(total_estimate::const_iterator i=trains.begin(); i!=trains.end(); ++i) + if(i->remaining_estimate<0) + return false; + for(vector::const_iterator i=trains.begin(); i!=trains.end(); ++i) if(i->state==MOVING) return true; @@ -430,7 +488,7 @@ bool TrainRoutePlanner::RoutingStep::is_goal() const bool TrainRoutePlanner::RoutingStep::operator<(const RoutingStep &other) const { - return time