From 4d84248a4990e913a56f013e67a608ad9698233e Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 26 Dec 2009 09:29:23 +0000 Subject: [PATCH] Compute deterministic IDs for blocks Save train route and block information --- source/engineer/engineer.cpp | 7 ++++ source/engineer/trainpanel.cpp | 3 +- source/libmarklin/block.cpp | 19 +++++++-- source/libmarklin/block.h | 3 +- source/libmarklin/trafficmanager.cpp | 9 +++++ source/libmarklin/trafficmanager.h | 1 + source/libmarklin/train.cpp | 60 ++++++++++++++++++++++++++-- source/libmarklin/train.h | 8 ++++ 8 files changed, 100 insertions(+), 10 deletions(-) diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 7bd0f77..308e5b2 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -176,6 +176,10 @@ int Engineer::main() y -= tpanel->get_geometry().h; } + const list &blocks = trfc_mgr->get_blocks(); + for(list::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) + reset_block_color(**i); + wnd->show(); Application::main(); @@ -265,6 +269,9 @@ void Engineer::tick() const list &trains = trfc_mgr->get_trains(); for(list::const_iterator i=trains.begin(); i!=trains.end(); ++i) { + if(!(*i)->is_placed()) + continue; + GL::PushMatrix _push; const Point &tp = (*i)->get_position(); diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index 5a1e531..339f4ec 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -52,7 +52,8 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): tgl_forward->signal_toggled.connect(sigc::mem_fun(this, &TrainPanel::forward_toggled)); train.get_locomotive().signal_reverse_changed.connect(sigc::mem_fun(this, &TrainPanel::train_reverse_changed)); - add(*(lbl_route=new GLtk::Label(res, "Free run"))); + const Route *route = train.get_route(); + add(*(lbl_route=new GLtk::Label(res, (route ? route->get_name() : "Free run")))); lbl_route->set_style("digital"); lbl_route->set_geometry(GLtk::Geometry(10, 58, geom.w-20, 24)); train.signal_route_changed.connect(sigc::mem_fun(this, &TrainPanel::train_route_changed)); diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index d4a6878..a29469c 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -5,6 +5,7 @@ Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ +#include #include "control.h" #include "block.h" #include "tracktype.h" @@ -16,11 +17,9 @@ using namespace Msp; namespace Marklin { -unsigned Block::next_id = 1; - Block::Block(TrafficManager &tm, Track &start): trfc_mgr(tm), - id(next_id++), + id(0), sensor_id(start.get_sensor_id()), turnout_id(start.get_turnout_id()), train(0) @@ -49,6 +48,11 @@ Block::Block(TrafficManager &tm, Track &start): } } + if(sensor_id) + id = 0x1000|sensor_id; + else if(turnout_id) + id = 0x2000|turnout_id; + for(unsigned i=0; ilink = this; } } + + if(!sensor_id && !turnout_id && endpoints.size()==2) + { + unsigned id1 = endpoints[0].link ? endpoints[0].link->get_id() : 1; + unsigned id2 = endpoints[1].link ? endpoints[1].link->get_id() : 1; + if(id2 &get_tracks() const { return tracks; } @@ -55,8 +56,6 @@ public: void print_debug(); private: void find_paths(Track &, unsigned, unsigned, std::set &); - - static unsigned next_id; }; } // namespace Marklin diff --git a/source/libmarklin/trafficmanager.cpp b/source/libmarklin/trafficmanager.cpp index b652d04..49dda42 100644 --- a/source/libmarklin/trafficmanager.cpp +++ b/source/libmarklin/trafficmanager.cpp @@ -58,6 +58,15 @@ TrafficManager::~TrafficManager() delete *i; } +Block &TrafficManager::get_block(unsigned id) const +{ + for(list::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) + if((*i)->get_id()==id) + return **i; + + throw KeyError("Unknown block", lexical_cast(id)); +} + Block &TrafficManager::get_block_by_track(const Track &t) const { for(list::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) diff --git a/source/libmarklin/trafficmanager.h b/source/libmarklin/trafficmanager.h index d4ea2b3..266d2ff 100644 --- a/source/libmarklin/trafficmanager.h +++ b/source/libmarklin/trafficmanager.h @@ -45,6 +45,7 @@ public: Control &get_control() const { return control; } Layout &get_layout() const { return layout; } const std::list &get_blocks() const { return blocks; } + Block &get_block(unsigned) const; Block &get_block_by_track(const Track &) const; const std::list &get_trains() const { return trains; } Train &get_train_by_locomotive(const Locomotive &) const; diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index 5524a5d..e64ef00 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -11,6 +11,7 @@ Distributed under the GPL #include #include "control.h" #include "except.h" +#include "layout.h" #include "route.h" #include "tracktype.h" #include "trafficmanager.h" @@ -186,6 +187,21 @@ void Train::save(list &st) const for(unsigned i=0; i<=14; ++i) if(real_speed[i].weight) st.push_back((DataFile::Statement("real_speed"), i, real_speed[i].speed, real_speed[i].weight)); + if(route) + st.push_back((DataFile::Statement("route"), route->get_name())); + + if(!cur_blocks.empty()) + { + list blocks = cur_blocks; + if(loco.get_reverse()) + reverse_blocks(blocks); + + Block *prev = blocks.front().block->get_endpoints()[blocks.front().entry].link; + st.push_back((DataFile::Statement("block_hint"), prev->get_id())); + + for(list::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) + st.push_back((DataFile::Statement("block"), i->block->get_id())); + } } void Train::locomotive_reverse_changed(bool) @@ -193,9 +209,7 @@ void Train::locomotive_reverse_changed(bool) for(list::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i) i->block->reserve(0); rsv_blocks.clear(); - cur_blocks.reverse(); - for(list::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) - i->entry = i->block->traverse(i->entry); + reverse_blocks(cur_blocks); reserve_more(); if(cur_track) @@ -530,6 +544,13 @@ void Train::release_blocks(list &blocks) blocks.clear(); } +void Train::reverse_blocks(list &blocks) const +{ + blocks.reverse(); + for(list::iterator i=blocks.begin(); i!=blocks.end(); ++i) + i->entry = i->block->traverse(i->entry); +} + Train::RealSpeed::RealSpeed(): speed(0), @@ -544,10 +565,36 @@ void Train::RealSpeed::add(float s, float w) Train::Loader::Loader(Train &t): - DataFile::BasicLoader(t) + DataFile::BasicLoader(t), + prev_block(0) { + add("block", &Loader::block); + add("block_hint", &Loader::block_hint); add("name", &Train::name); add("real_speed", &Loader::real_speed); + add("route", &Loader::route); +} + +void Train::Loader::block(unsigned id) +{ + Block &blk = obj.trfc_mgr.get_block(id); + int entry = -1; + if(prev_block) + entry = blk.get_endpoint_by_link(*prev_block); + if(entry<0) + entry = 0; + + blk.reserve(&obj); + obj.cur_blocks.push_back(BlockRef(&blk, entry)); + obj.status = "Stopped"; + obj.set_position(blk.get_endpoints()[entry]); + + prev_block = &blk; +} + +void Train::Loader::block_hint(unsigned id) +{ + prev_block = &obj.trfc_mgr.get_block(id); } void Train::Loader::real_speed(unsigned i, float speed, float weight) @@ -556,4 +603,9 @@ void Train::Loader::real_speed(unsigned i, float speed, float weight) obj.real_speed[i].weight = weight; } +void Train::Loader::route(const string &n) +{ + obj.route = &obj.trfc_mgr.get_layout().get_route(n); +} + } // namespace Marklin diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index 5f75a2a..5ef2353 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -26,10 +26,16 @@ class Train: public sigc::trackable public: class Loader: public Msp::DataFile::BasicLoader { + private: + Block *prev_block; + public: Loader(Train &); private: + void block(unsigned); + void block_hint(unsigned); void real_speed(unsigned, float, float); + void route(const std::string &); }; sigc::signal signal_name_changed; @@ -91,6 +97,7 @@ public: const std::string &get_status() const { return status; } const Point &get_position() const { return pos; } void place(Block &, unsigned); + bool is_placed() const { return !cur_blocks.empty(); } bool free_block(Block &); int get_entry_to_block(Block &) const; void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &); @@ -107,6 +114,7 @@ private: void set_status(const std::string &); void set_position(const Block::Endpoint &); void release_blocks(std::list &); + void reverse_blocks(std::list &) const; }; } // namespace Marklin -- 2.43.0