X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Ftimetable.cpp;h=bd9f5f0f046d5c24cd5c99eccf05ddd6b8233247;hb=59e4c75da550e96ae74162a5ed70e8b1999721d8;hp=bd9d4b37313123c3b87f323f56e95e76a6f749f7;hpb=a9180bc4bb7ff4c403e206cc2c785ff32544a0d6;p=r2c2.git diff --git a/source/libmarklin/timetable.cpp b/source/libmarklin/timetable.cpp index bd9d4b3..bd9f5f0 100644 --- a/source/libmarklin/timetable.cpp +++ b/source/libmarklin/timetable.cpp @@ -5,6 +5,7 @@ Copyright © 2010 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ +#include #include #include "block.h" #include "catalogue.h" @@ -20,6 +21,7 @@ namespace Marklin { Timetable::Timetable(Train &t): train(t), + enabled(false), current_row(0), executing(true), pending_block(0) @@ -28,8 +30,52 @@ Timetable::Timetable(Train &t): train.get_layout().get_driver().signal_sensor.connect(sigc::mem_fun(this, &Timetable::sensor_event)); } +void Timetable::set_enabled(bool e) +{ + enabled = e; +} + +void Timetable::reset() +{ + current_row = 0; + wait_timeout = Time::TimeStamp(); + pending_block = 0; + executing = true; +} + +void Timetable::clear() +{ + rows.clear(); + reset(); +} + +void Timetable::append(const Row &row) +{ + rows.push_back(row); +} + +void Timetable::insert(unsigned i, const Row &row) +{ + if(i>rows.size()) + throw InvalidParameterValue("Insert position out of range"); + + rows.insert(rows.begin()+i, row); + if(i<=current_row) + ++current_row; +} + +const Timetable::Row &Timetable::get_row(unsigned i) const +{ + if(i>=rows.size()) + throw InvalidParameterValue("Row index out of range"); + return rows[i]; +} + void Timetable::tick(const Time::TimeStamp &t) { + if(rows.empty() || !enabled) + return; + if(wait_timeout && t>=wait_timeout) { wait_timeout = Time::TimeStamp(); @@ -44,7 +90,6 @@ void Timetable::tick(const Time::TimeStamp &t) { case GOTO: train.go_to(**parse_location(row.strparam).get_tracks().begin()); - executing = false; break; case TRAVEL: pending_block = &parse_location(row.strparam); @@ -54,6 +99,9 @@ void Timetable::tick(const Time::TimeStamp &t) wait_timeout = t+row.intparam*Time::sec; executing = false; break; + case ARRIVE: + executing = false; + break; case SPEED: train.set_control("speed", row.intparam/3.6*train.get_layout().get_catalogue().get_scale()); break; @@ -82,6 +130,9 @@ void Timetable::save(list &st) const case WAIT: st.push_back((DataFile::Statement("wait"), i->intparam)); break; + case ARRIVE: + st.push_back(DataFile::Statement("arrive")); + break; case SPEED: st.push_back((DataFile::Statement("speed"), i->intparam)); break; @@ -112,7 +163,7 @@ void Timetable::sensor_event(unsigned addr, bool state) void Timetable::train_arrived() { Row &row = rows[current_row]; - if(row.type==GOTO) + if(row.type==ARRIVE) { current_row = (current_row+1)%rows.size(); executing = true; @@ -131,10 +182,60 @@ Timetable::Row::Row(RowType t, const string &p): strparam(p) { } +string Timetable::Row::str() const +{ + switch(type) + { + case GOTO: + return "go to "+strparam; + case TRAVEL: + return "travel to "+strparam; + case WAIT: + return format("wait for %d seconds", intparam); + case ARRIVE: + return "wait for arrival"; + case SPEED: + return format("set speed %d km/h", intparam); + case ROUTE: + return "set route "+strparam; + default: + return "invalid row"; + } +} + +Timetable::Row Timetable::Row::parse(const string &s) +{ + if(!s.compare(0, 6, "go to ")) + return Row(GOTO, s.substr(6)); + else if(!s.compare(0, 10, "travel to ")) + return Row(TRAVEL, s.substr(10)); + else if(!s.compare(0, 9, "wait for ") && isdigit(s[9])) + { + unsigned nondigit = 10; + while(nondigit(s.substr(9, nondigit-9))); + } + else if(s=="wait for arrival") + return Row(ARRIVE, 0); + else if(!s.compare(0, 10, "set speed ")) + { + unsigned nondigit = 11; + while(nondigit(s.substr(10, nondigit-10))); + } + else if(!s.compare(0, 10, "set route ")) + return Row(ROUTE, s.substr(10)); + + throw InvalidParameterValue("Invalid row"); +} + Timetable::Loader::Loader(Timetable &tt): DataFile::ObjectLoader(tt) { + add("arrive", &Loader::arrive); add("goto", &Loader::go_to); add("route", &Loader::route); add("speed", &Loader::speed); @@ -142,6 +243,11 @@ Timetable::Loader::Loader(Timetable &tt): add("wait", &Loader::wait); } +void Timetable::Loader::arrive() +{ + obj.rows.push_back(Row(ARRIVE, 0)); +} + void Timetable::Loader::go_to(const string &t) { obj.rows.push_back(Row(GOTO, t));