btn->set_tooltip("Add selected tracks to current route (A)");
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_route));
- designer.get_layout().signal_route_added.connect(sigc::mem_fun(this, &Routebar::route_added));
- designer.get_layout().signal_route_removed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
+ designer.get_layout().signal_track_chain_added.connect(sigc::mem_fun(this, &Routebar::track_chain_added));
+ designer.get_layout().signal_track_chain_removed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
- const set<Route *> &routes = designer.get_layout().get_routes();
+ const set<Route *> &routes = designer.get_layout().get_all<Route>();
for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
(*i)->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
if(index==drp_routes->get_n_items()-1)
{
Layout &rlayout = designer.get_layout();
- const set<Route *> &routes = rlayout.get_routes();
Route *route = new Route(rlayout);
+ const set<Route *> &routes = rlayout.get_all<Route>();
route->set_name(format("Route %d", routes.size()));
designer.edit_route(route);
}
else
{
- const set<Route *> &routes = designer.get_layout().get_routes();
+ const set<Route *> &routes = designer.get_layout().get_all<Route>();
set<Route *>::const_iterator i = routes.begin();
advance(i, index);
designer.edit_route(*i);
delete route;
}
-void Routebar::route_added(Route &r)
+void Routebar::track_chain_added(TrackChain &tc)
{
- r.signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
- update_routes();
+ if(Route *r = dynamic_cast<Route *>(&tc))
+ {
+ r->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
+ update_routes();
+ }
}
void Routebar::update_routes()
{
drp_routes->clear();
- const set<Route *> &routes = designer.get_layout().get_routes();
+ const set<Route *> &routes = designer.get_layout().get_all<Route>();
int selected = -1;
unsigned n = 0;
for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
private:
void route_selected(unsigned, const std::string &);
void delete_route_clicked();
- void route_added(R2C2::Route &);
+ void track_chain_added(R2C2::TrackChain &);
void update_routes();
};
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_zone));
Layout &rlayout = designer.get_layout();
- rlayout.signal_zone_added.connect(sigc::mem_fun(this, &Zonebar::zone_added));
- rlayout.signal_zone_removed.connect(sigc::hide(sigc::mem_fun(this, &Zonebar::update_groups)));
+ rlayout.signal_track_chain_added.connect(sigc::mem_fun(this, &Zonebar::track_chain_added));
+ rlayout.signal_track_chain_removed.connect(sigc::hide(sigc::mem_fun(this, &Zonebar::update_groups)));
- const Layout::ZoneSet &zones = rlayout.get_zones();
- for(Layout::ZoneSet::const_iterator i=zones.begin(); i!=zones.end(); ++i)
+ const set<Zone *> &zones = rlayout.get_all<Zone>();
+ for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
(*i)->signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
update_groups();
}
-void Zonebar::zone_added(Zone &zone)
+void Zonebar::track_chain_added(TrackChain &chain)
{
- zone.signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
- update_groups();
+ if(Zone *zone = dynamic_cast<Zone *>(&chain))
+ {
+ zone->signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
+ update_groups();
+ }
}
void Zonebar::zone_renamed(const string &, const string &, unsigned)
void Zonebar::update_groups()
{
- const Layout::ZoneSet &zones = designer.get_layout().get_zones();
+ const set<Zone *> &zones = designer.get_layout().get_all<Zone>();
set<string> groups;
- for(Layout::ZoneSet::const_iterator i=zones.begin(); i!=zones.end(); ++i)
+ for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
groups.insert((*i)->get_group());
Zone *cur = designer.get_current_zone();
Zonebar(Designer &);
private:
- void zone_added(R2C2::Zone &);
+ void track_chain_added(R2C2::TrackChain &);
void zone_renamed(const std::string &, const std::string &, unsigned);
void group_selected(unsigned, const std::string &);
void number_selected(unsigned, const std::string &);
layout.signal_train_added.connect(sigc::mem_fun(this, &Engineer::train_added));
layout.signal_block_reserved.connect(sigc::hide<1>(sigc::mem_fun(this, &Engineer::reset_block_color)));
layout.signal_emergency.connect(sigc::mem_fun(this, &Engineer::set_status));
- const set<Block *> &blocks = layout.get_blocks();
+ const set<Block *> &blocks = layout.get_all<Block>();
for(set<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
(*i)->get_sensor().signal_state_changed.connect(sigc::hide(sigc::bind(sigc::mem_fun(this, &Engineer::reset_block_color), sigc::ref(**i))));
if(TrainRouter *router = train.get_ai_of_type<TrainRouter>())
current_route = router->get_route();
- const set<Route *> &routes = engineer.get_layout().get_routes();
+ const set<Route *> &routes = engineer.get_layout().get_all<Route>();
unsigned n = 1;
for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
if(!(*i)->is_temporary())
{
if(drp_route->get_selected_index()>0)
{
- const set<Route *> &routes = engineer.get_layout().get_routes();
+ const set<Route *> &routes = engineer.get_layout().get_all<Route>();
set<Route *>::const_iterator i = routes.begin();
unsigned n = drp_route->get_selected_index()-1;
while(i!=routes.end())
sensor = new TrackCircuit(layout, *this);
- layout.add_block(*this);
+ layout.add(*this);
}
Block::~Block()
blk->break_link(*this);
}
- layout.remove_block(*this);
+ layout.remove(*this);
delete sensor;
}
while(!trains.empty())
delete trains.begin()->second;
- while(!routes.empty())
- delete *routes.begin();
- while(!zones.empty())
- delete *zones.begin();
+ track_chains.del<Route>();
+ track_chains.del<Zone>();
objects.del<Signal>();
objects.del<Track>();
- while(!blocks.empty())
- delete *blocks.begin();
+ track_chains.del<Block>();
}
Driver &Layout::get_driver() const
}
}
+void Layout::add(TrackChain &g)
+{
+ if(track_chains.insert(g))
+ signal_track_chain_added.emit(g);
+}
+
+void Layout::add(Block &b)
+{
+ if(track_chains.insert(b))
+ {
+ b.signal_reserved.connect(sigc::bind<0>(signal_block_reserved, sigc::ref(b)));
+ signal_track_chain_added.emit(b);
+ }
+}
+
+void Layout::add(Sensor &s)
+{
+ if(sensors.insert(s))
+ {
+ s.signal_state_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Layout::sensor_state_changed), sigc::ref(s)));
+ s.signal_state_changed.connect(sigc::bind<0>(signal_sensor_state_changed, sigc::ref(s)));
+ }
+}
+
template<>
const set<Object *> &Layout::get_all<Object>() const
{
return objects.get<Vehicle>();
}
+template<>
+const set<TrackChain *> &Layout::get_all<TrackChain>() const
+{
+ return track_chains.get();
+}
+
+template<>
+const set<Block *> &Layout::get_all<Block>() const
+{
+ return track_chains.get<Block>();
+}
+
+template<>
+const set<Route *> &Layout::get_all<Route>() const
+{
+ return track_chains.get<Route>();
+}
+
+template<>
+const set<Zone *> &Layout::get_all<Zone>() const
+{
+ return track_chains.get<Zone>();
+}
+
+template<>
+const set<Sensor *> &Layout::get_all<Sensor>() const
+{
+ return sensors.get<Sensor>();
+}
+
+template<>
+const set<TrackCircuit *> &Layout::get_all<TrackCircuit>() const
+{
+ return sensors.get<TrackCircuit>();
+}
+
template<typename T>
T *Layout::pick(const Ray &ray)
{
}
}
+void Layout::remove(TrackChain &g)
+{
+ if(track_chains.erase(g))
+ signal_track_chain_removed.emit(g);
+}
+
+void Layout::remove(Sensor &s)
+{
+ sensors.erase(s);
+}
+
unsigned Layout::allocate_turnout_id()
{
set<unsigned> used_ids;
return result;
}
-void Layout::add_block(Block &b)
-{
- blocks.insert(&b);
- b.signal_reserved.connect(sigc::bind<0>(signal_block_reserved, sigc::ref(b)));
-}
-
Block &Layout::get_block(unsigned id) const
{
+ const set<Block *> &blocks = track_chains.get<Block>();
for(set<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
if((*i)->get_id()==id)
return **i;
void Layout::create_blocks()
{
set<Track *> used_tracks;
- for(set<Block *>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
+ const set<Block *> *blocks = &track_chains.get<Block>();
+ for(set<Block *>::const_iterator i=blocks->begin(); i!=blocks->end(); ++i)
{
const set<Track *> &btracks = (*i)->get_tracks();
used_tracks.insert(btracks.begin(), btracks.end());
used_tracks.insert(block->get_tracks().begin(), block->get_tracks().end());
}
- for(set<Block *>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
- for(set<Block *>::iterator j=i; j!=blocks.end(); ++j)
+ blocks = &track_chains.get<Block>();
+ for(set<Block *>::iterator i=blocks->begin(); i!=blocks->end(); ++i)
+ for(set<Block *>::iterator j=i; j!=blocks->end(); ++j)
if(j!=i)
(*i)->check_link(**j);
}
create_blocks();
}
-void Layout::remove_block(Block &b)
-{
- blocks.erase(&b);
-}
-
-void Layout::add_route(Route &r)
-{
- if(routes.insert(&r).second)
- signal_route_added.emit(r);
-}
-
Route &Layout::get_route(const string &name) const
{
+ const set<Route *> &routes = track_chains.get<Route>();
for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
if((*i)->get_name()==name)
return **i;
void Layout::update_routes()
{
+ const set<Route *> &routes = track_chains.get<Route>();
for(set<Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
(*i)->update_turnouts();
}
-void Layout::remove_route(Route &r)
-{
- if(routes.erase(&r))
- signal_route_removed.emit(r);
-}
-
-void Layout::add_zone(Zone &z)
-{
- if(zones.insert(&z).second)
- signal_zone_added.emit(z);
-}
-
Layout::ZoneArray Layout::get_zones(const string &group) const
{
ZoneArray result;
- for(ZoneSet::const_iterator i=zones.begin(); i!=zones.end(); ++i)
+ const set<Zone *> &zones = track_chains.get<Zone>();
+ for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
if((*i)->get_group()==group)
result.push_back(*i);
Zone &Layout::get_zone(const string &group, unsigned num) const
{
- for(ZoneSet::const_iterator i=zones.begin(); i!=zones.end(); ++i)
+ const set<Zone *> &zones = track_chains.get<Zone>();
+ for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
if((*i)->get_group()==group && (*i)->get_number()==num)
return **i;
throw key_error(format("%s %d", group, num));
}
-void Layout::remove_zone(Zone &z)
-{
- if(zones.erase(&z))
- signal_zone_removed.emit(z);
-}
-
void Layout::add_train(Train &t)
{
insert_unique(trains, t.get_address(), &t);
signal_train_removed.emit(t);
}
-void Layout::add_sensor(Sensor &s)
-{
- if(sensors.insert(&s).second)
- {
- s.signal_state_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Layout::sensor_state_changed), sigc::ref(s)));
- s.signal_state_changed.connect(sigc::bind<0>(signal_sensor_state_changed, sigc::ref(s)));
- }
-}
-
-void Layout::remove_sensor(Sensor &s)
-{
- sensors.erase(&s);
-}
-
void Layout::tick()
{
if(driver)
dt = t-last_tick;
last_tick = t;
- for(set<Sensor *>::iterator i=sensors.begin(); i!=sensors.end(); ++i)
+ for(set<Sensor *>::iterator i=sensors.get().begin(); i!=sensors.get().end(); ++i)
(*i)->tick(dt);
const set<Signal *> &signals = objects.get<Signal>();
for(set<Signal *>::iterator i=signals.begin(); i!=signals.end(); ++i)
writer.write(st);
}
+ const set<Route *> &routes = track_chains.get<Route>();
for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
{
if((*i)->is_temporary())
writer.write(st);
}
- for(ZoneSet::const_iterator i=zones.begin(); i!=zones.end(); ++i)
+ const set<Zone *> &zones = track_chains.get<Zone>();
+ for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
{
DataFile::Statement st("zone");
(*i)->save(st.sub);
class Route;
class Signal;
class Track;
+class TrackChain;
class Train;
class Vehicle;
class Zone;
};
public:
- typedef std::set<Zone *> ZoneSet;
typedef std::vector<Zone *> ZoneArray;
sigc::signal<void, Object &> signal_object_added;
sigc::signal<void, Object &> signal_object_removed;
- sigc::signal<void, Route &> signal_route_added;
- sigc::signal<void, Route &> signal_route_removed;
- sigc::signal<void, Zone &> signal_zone_added;
- sigc::signal<void, Zone &> signal_zone_removed;
+ sigc::signal<void, TrackChain &> signal_track_chain_added;
+ sigc::signal<void, TrackChain &> signal_track_chain_removed;
sigc::signal<void, Train &> signal_train_added;
sigc::signal<void, Train &> signal_train_removed;
sigc::signal<void, Block &, Train *> signal_block_reserved;
Driver *driver;
std::string base;
Storage<Object> objects;
- std::set<Route *> routes;
- ZoneSet zones;
- std::set<Block *> blocks;
- std::set<Sensor *> sensors;
+ Storage<TrackChain> track_chains;
+ Storage<Sensor> sensors;
std::map<unsigned, Train *> trains;
Msp::Time::TimeStamp last_tick;
unsigned next_turnout_id;
void add(Object &);
void add(Track &);
+ void add(TrackChain &);
+ void add(Block &);
+ void add(Sensor &);
template<typename T>
const std::set<T *> &get_all() const;
void remove(Object &);
void remove(Track &);
+ void remove(TrackChain &);
+ void remove(Sensor &);
unsigned allocate_turnout_id();
- void add_block(Block &);
Block &get_block(unsigned) const;
- const std::set<Block *> &get_blocks() const { return blocks; }
void create_blocks();
void create_blocks(Track &);
- void remove_block(Block &);
- void add_route(Route &);
- const std::set<Route *> &get_routes() const { return routes; }
Route &get_route(const std::string &) const;
void update_routes();
- void remove_route(Route &);
- void add_zone(Zone &);
- const ZoneSet &get_zones() const { return zones; }
ZoneArray get_zones(const std::string &) const;
Zone &get_zone(const std::string &, unsigned) const;
- void remove_zone(Zone &);
void add_train(Train &);
Train &get_train(unsigned) const;
const std::map<unsigned, Train *> &get_trains() const { return trains; }
void remove_train(Train &);
- void add_sensor(Sensor &);
- void remove_sensor(Sensor &);
-
void tick();
void emergency(const std::string &);
TrackChain(l),
temporary(false)
{
- layout.add_route(*this);
+ layout.add(*this);
}
Route::~Route()
{
- layout.remove_route(*this);
+ layout.remove(*this);
}
void Route::set_name(const string &n)
if(layout.has_driver())
layout.get_driver().signal_sensor.connect(sigc::mem_fun(this, &Sensor::event));
- layout.add_sensor(*this);
+ layout.add(*this);
}
Sensor::~Sensor()
{
- layout.remove_sensor(*this);
+ layout.remove(*this);
}
void Sensor::tick(const Time::TimeDelta &dt)
TrackChain(l),
number(0)
{
- layout.add_zone(*this);
+ layout.add(*this);
}
Zone::~Zone()
{
- layout.remove_zone(*this);
+ layout.remove(*this);
}
void Zone::set_name(const string &g, const string &q, unsigned n)
comm.send(pkt);
}
- const set<Route *> &routes = server.layout.get_routes();
+ const set<Route *> &routes = server.layout.get_all<Route>();
for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
if(!(*i)->is_temporary())
{