-#include "control.h"
-#include "section.h"
-#include "trafficmanager.h"
-#include "turnout.h"
-
-using namespace Msp;
-
-#include <iostream>
-using namespace std;
-
-namespace Marklin {
-
-Section::Section(TrafficManager &tm, Track *start):
- trfc_mgr(tm),
- id(next_id++),
- sensor_id(0),
- train(0)
-{
- tracks.insert(start);
-
- if(start->get_sensor_id())
- {
- sensor_id=start->get_sensor_id();
- const Track::EndpointSeq &eps=start->get_endpoints();
- for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i)
- endpoints.push_back(Endpoint(start, &*i));
- }
- else
- {
- TrackSeq queue;
- queue.push_back(start);
-
- while(!queue.empty())
- {
- Track *track=queue.front();
- queue.erase(queue.begin());
-
- const Track::EndpointSeq &eps=track->get_endpoints();
- for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i)
- if(i->link && tracks.count(i->link)==0)
- {
- if(!i->link->get_sensor_id())
- {
- queue.push_back(i->link);
- tracks.insert(i->link);
- }
- else
- endpoints.push_back(Endpoint(track, &*i));
- }
- }
- }
-
- unsigned n=0;
- for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i, ++n)
- {
- unsigned route=1<<n;
- i->routes|=route;
- set<Track *> visited;
- find_routes(i->track, i->track_ep, route, visited);
- }
-}
-
-const Section::Endpoint *Section::get_endpoint_by_link(const Section *other) const
-{
- for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
- if(i->link==other)
- return &*i;
-
- return 0;
-}
-
-const Section::Endpoint *Section::traverse(const Endpoint *ep) const
-{
- Track *track=ep->track;
- const Track::Endpoint *track_ep=ep->track_ep;
-
- while(1)
- {
- unsigned cur_route=0;
- unsigned tid=track->get_turnout_id();
- if(tid)
- {
- Turnout *turnout=trfc_mgr.get_control().get_turnout(tid);
- if(turnout)
- cur_route=turnout->get_route();
- }
-
- const Track::Endpoint *other_ep=track->traverse(track_ep, cur_route);
- if(!other_ep)
- return 0;
-
- for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
- if(i->track==track && i->track_ep==other_ep)
- return &*i;
-
- track_ep=track->get_endpoint_by_link(other_ep->link);
- track=other_ep->link;
-
- if(tracks.count(track)==0)
- return 0;
- }
-}
-
-void Section::check_link(Section &other)
-{
- for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
- {
- if(i->link)
- continue;
-
- for(EndpointSeq::iterator j=other.endpoints.begin(); j!=other.endpoints.end(); ++j)
- if(j->track==i->track_ep->link && j->track_ep->link==i->track && !j->link)
- {
- i->link=&other;
- j->link=this;
- }
- }
-}
-
-bool Section::reserve(const Train *t)
-{
- if(!t || !train)
- {
- train=t;
- return true;
- }
- else
- return false;
-}
-
-void Section::print_debug()
-{
- cout<<"Section "<<id;
- if((*tracks.begin())->get_sensor_id())
- cout<<", sensor="<<(*tracks.begin())->get_sensor_id();
- cout<<'\n';
- for(EndpointSeq::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
- {
- cout<<" Endpoint, link=";
- if(i->link)
- cout<<i->link->id;
- else
- cout<<"none";
- cout<<", routes="<<i->routes<<'\n';
- }
-}
-
-void Section::find_routes(Track *track, const Track::Endpoint *track_ep, unsigned route, std::set<Marklin::Track *> &visited)
-{
- visited.insert(track);
-
- const Track::EndpointSeq &eps=track->get_endpoints();
- for(Track::EndpointSeq::const_iterator i=eps.begin(); i!=eps.end(); ++i)
- {
- if(&*i==track_ep) continue;
- if(!i->link) continue;
- if(!(i->routes&track_ep->routes)) continue;
- if(visited.count(i->link)) continue;
-
- if(tracks.count(i->link))
- find_routes(i->link, i->link->get_endpoint_by_link(track), route, visited);
- else
- {
- for(EndpointSeq::iterator j=endpoints.begin(); j!=endpoints.end(); ++j)
- if(j->track==track && j->track_ep==&*i)
- j->routes|=route;
- }
- }
-
- visited.erase(--visited.end());
-}
-
-unsigned Section::next_id=1;
-
-
-Section::Endpoint::Endpoint(Track *t, const Track::Endpoint *e):
- track(t),
- track_ep(e),
- link(0),
- routes(0)
-{ }
-
-} // namespace Marklin