{
if(placing_train)
{
- Section *sect=trfc_man->get_section_by_track(track->get_track());
+ Block *block=trfc_man->get_block_by_track(&track->get_track());
}
else
{
--- /dev/null
+#include "control.h"
+#include "block.h"
+#include "trafficmanager.h"
+#include "turnout.h"
+
+using namespace Msp;
+
+#include <iostream>
+using namespace std;
+
+namespace Marklin {
+
+Block::Block(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 Block::Endpoint *Block::get_endpoint_by_link(const Block *other) const
+{
+ for(EndpointSeq::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
+ if(i->link==other)
+ return &*i;
+
+ return 0;
+}
+
+const Block::Endpoint *Block::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 Block::check_link(Block &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 Block::reserve(const Train *t)
+{
+ if(!t || !train)
+ {
+ train=t;
+ return true;
+ }
+ else
+ return false;
+}
+
+void Block::print_debug()
+{
+ cout<<"Block "<<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 Block::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 Block::next_id=1;
+
+
+Block::Endpoint::Endpoint(Track *t, const Track::Endpoint *e):
+ track(t),
+ track_ep(e),
+ link(0),
+ routes(0)
+{ }
+
+} // namespace Marklin
--- /dev/null
+#ifndef MARKLIN_3D_SECTION_H_
+#define MARKLIN_3D_SECTION_H_
+
+#include <list>
+#include <set>
+#include "track.h"
+
+namespace Marklin {
+
+class Train;
+class TrafficManager;
+
+class Block
+{
+public:
+ struct Endpoint
+ {
+ Track *track;
+ const Track::Endpoint *track_ep;
+ Block *link;
+ unsigned routes;
+
+ Endpoint(Track *, const Track::Endpoint *);
+ };
+ typedef std::list<Endpoint> EndpointSeq;
+
+ Block(TrafficManager &, Track *);
+ unsigned get_sensor_id() const { return sensor_id; }
+ const TrackSet &get_tracks() const { return tracks; }
+ const Endpoint *get_endpoint_by_link(const Block *) const;
+ const Endpoint *traverse(const Endpoint *) const;
+ void check_link(Block &);
+ bool reserve(const Train *);
+ void print_debug();
+private:
+ TrafficManager &trfc_mgr;
+ unsigned id;
+ unsigned sensor_id;
+ TrackSet tracks;
+ EndpointSeq endpoints;
+ const Train *train;
+
+ void find_routes(Track *, const Track::Endpoint *, unsigned, TrackSet &);
+
+ static unsigned next_id;
+};
+typedef std::list<Block *> BlockSeq;
+
+} // namespace Marklin
+
+#endif
+++ /dev/null
-#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
+++ /dev/null
-#ifndef MARKLIN_3D_SECTION_H_
-#define MARKLIN_3D_SECTION_H_
-
-#include <list>
-#include <set>
-#include "track.h"
-
-namespace Marklin {
-
-class Train;
-class TrafficManager;
-
-class Section
-{
-public:
- struct Endpoint
- {
- Track *track;
- const Track::Endpoint *track_ep;
- Section *link;
- unsigned routes;
-
- Endpoint(Track *, const Track::Endpoint *);
- };
- typedef std::list<Endpoint> EndpointSeq;
-
- Section(TrafficManager &, Track *);
- unsigned get_sensor_id() const { return sensor_id; }
- const TrackSet &get_tracks() const { return tracks; }
- const Endpoint *get_endpoint_by_link(const Section *) const;
- const Endpoint *traverse(const Endpoint *) const;
- void check_link(Section &);
- bool reserve(const Train *);
- void print_debug();
-private:
- TrafficManager &trfc_mgr;
- unsigned id;
- unsigned sensor_id;
- TrackSet tracks;
- EndpointSeq endpoints;
- const Train *train;
-
- void find_routes(Track *, const Track::Endpoint *, unsigned, TrackSet &);
-
- static unsigned next_id;
-};
-typedef std::list<Section *> SectionSeq;
-
-} // namespace Marklin
-
-#endif
}
if(used_tracks.count(*i)==0)
{
- Section *sect=new Section(*this, *i);
- sections.push_back(sect);
- used_tracks.insert(sect->get_tracks().begin(), sect->get_tracks().end());
+ Block *block=new Block(*this, *i);
+ blocks.push_back(block);
+ used_tracks.insert(block->get_tracks().begin(), block->get_tracks().end());
}
}
- for(SectionSeq::iterator i=sections.begin(); i!=sections.end(); ++i)
+ for(BlockSeq::iterator i=blocks.begin(); i!=blocks.end(); ++i)
{
- for(SectionSeq::iterator j=i; j!=sections.end(); ++j)
+ for(BlockSeq::iterator j=i; j!=blocks.end(); ++j)
if(j!=i)
(*i)->check_link(**j);
(*i)->print_debug();
}
}
-Section *TrafficManager::get_section_by_track(const Track *t) const
+Block *TrafficManager::get_block_by_track(const Track *t) const
{
- for(SectionSeq::const_iterator i=sections.begin(); i!=sections.end(); ++i)
+ for(BlockSeq::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
{
const TrackSet &tracks=(*i)->get_tracks();
if(tracks.count(const_cast<Track *>(t)))
#ifndef LIBMARKLIN_TRAFFICMANAGER_H_
#define LIBMARKLIN_TRAFFICMANAGER_H_
-#include "section.h"
+#include "block.h"
#include "train.h"
namespace Marklin {
public:
TrafficManager(Control &, Layout &);
Control &get_control() const { return control; }
- Section *get_section_by_track(const Track *) const;
+ Block *get_block_by_track(const Track *) const;
void add_train(Train *);
private:
Control &control;
Layout &layout;
- SectionSeq sections;
+ BlockSeq blocks;
TrainSeq trains;
void turnout_route_changed(unsigned, Turnout *);
void Train::set_speed(unsigned speed)
{
target_speed=speed;
- if(rsv_sections.empty() && !reserve_more())
+ if(rsv_blocks.empty() && !reserve_more())
return;
loco.set_speed(speed);
}
-void Train::place(Section *sect, const Section::Endpoint *entry)
+void Train::place(Block *block, const Block::Endpoint *entry)
{
- for(SectRefSeq::iterator i=rsv_sections.begin(); i!=rsv_sections.end();)
+ for(BlockRefSeq::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
{
- i->section->reserve(0);
- i=rsv_sections.erase(i);
+ i->block->reserve(0);
+ i=rsv_blocks.erase(i);
}
- for(SectRefSeq::iterator i=cur_sections.begin(); i!=cur_sections.end();)
+ for(BlockRefSeq::iterator i=cur_blocks.begin(); i!=cur_blocks.end();)
{
- i->section->reserve(0);
- i=cur_sections.erase(i);
+ i->block->reserve(0);
+ i=cur_blocks.erase(i);
}
- if(!sect->reserve(this))
+ if(!block->reserve(this))
return;
- cur_sections.push_back(SectionRef(sect, entry));
+ cur_blocks.push_back(BlockRef(block, entry));
}
-bool Train::free_section(Section *sect)
+bool Train::free_block(Block *block)
{
- for(SectRefSeq::iterator i=rsv_sections.begin(); i!=rsv_sections.end(); ++i)
- if(i->section==sect)
+ for(BlockRefSeq::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
+ if(i->block==block)
{
- while(i!=rsv_sections.end())
+ while(i!=rsv_blocks.end())
{
- i->section->reserve(0);
- i=rsv_sections.erase(i);
+ i->block->reserve(0);
+ i=rsv_blocks.erase(i);
}
return true;
}
{
if(state)
{
- SectRefSeq::iterator i;
- for(i=rsv_sections.begin(); i!=rsv_sections.end(); ++i)
- if(i->section->get_sensor_id() && i->section->get_sensor_id()!=addr)
+ BlockRefSeq::iterator i;
+ for(i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i)
+ if(i->block->get_sensor_id() && i->block->get_sensor_id()!=addr)
break;
- cur_sections.splice(cur_sections.begin(), rsv_sections, rsv_sections.begin(), i);
+ cur_blocks.splice(cur_blocks.begin(), rsv_blocks, rsv_blocks.begin(), i);
reserve_more();
- if(rsv_sections.empty())
+ if(rsv_blocks.empty())
loco.set_speed(0);
}
else
{
- SectRefSeq::iterator i;
- for(i=cur_sections.begin(); i!=cur_sections.end(); ++i)
- if(i->section->get_sensor_id()==addr)
+ BlockRefSeq::iterator i;
+ for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
+ if(i->block->get_sensor_id()==addr)
break;
- if(i!=cur_sections.end())
+ if(i!=cur_blocks.end())
{
++i;
- for(SectRefSeq::iterator j=cur_sections.begin(); j!=i; ++j)
- j->section->reserve(0);
- cur_sections.erase(cur_sections.begin(), i);
+ for(BlockRefSeq::iterator j=cur_blocks.begin(); j!=i; ++j)
+ j->block->reserve(0);
+ cur_blocks.erase(cur_blocks.begin(), i);
}
reserve_more();
bool Train::reserve_more()
{
- SectionRef *last=0;
- if(!rsv_sections.empty())
- last=&rsv_sections.back();
- else if(!cur_sections.empty())
- last=&cur_sections.back();
+ BlockRef *last=0;
+ if(!rsv_blocks.empty())
+ last=&rsv_blocks.back();
+ else if(!cur_blocks.empty())
+ last=&cur_blocks.back();
if(!last)
return false;
bool result=false;
- unsigned size=rsv_sections.size();
+ unsigned size=rsv_blocks.size();
while(size<5)
{
- const Section::Endpoint *exit=last->section->traverse(last->entry);
+ const Block::Endpoint *exit=last->block->traverse(last->entry);
if(exit->link->reserve(this))
{
- rsv_sections.push_back(SectionRef(exit->link, exit->link->get_endpoint_by_link(last->section)));
- last=&rsv_sections.back();
+ rsv_blocks.push_back(BlockRef(exit->link, exit->link->get_endpoint_by_link(last->block)));
+ last=&rsv_blocks.back();
++size;
result=true;
}
#define LIBMARKLIN_TRAIN_H_
#include <sigc++/trackable.h>
-#include "section.h"
+#include "block.h"
namespace Marklin {
Train(TrafficManager &, Locomotive &);
const std::string &get_name() const { return name; }
void set_speed(unsigned);
- void place(Section *, const Section::Endpoint *);
- bool free_section(Section *);
+ void place(Block *, const Block::Endpoint *);
+ bool free_block(Block *);
void tick();
private:
- struct SectionRef
+ struct BlockRef
{
- Section *section;
- const Section::Endpoint *entry;
+ Block *block;
+ const Block::Endpoint *entry;
- SectionRef(Section *s, const Section::Endpoint *e): section(s), entry(e) { }
+ BlockRef(Block *s, const Block::Endpoint *e): block(s), entry(e) { }
};
- typedef std::list<SectionRef> SectRefSeq;
+ typedef std::list<BlockRef> BlockRefSeq;
TrafficManager &trfc_mgr;
std::string name;
Locomotive &loco;
- SectRefSeq cur_sections;
- SectRefSeq rsv_sections;
+ BlockRefSeq cur_blocks;
+ BlockRefSeq rsv_blocks;
unsigned target_speed;
void sensor_event(unsigned, bool);