X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Fcentralstation.cpp;h=5e82f2e5f117c23d9137bb80ff41b0b4359d2ecb;hb=b78b49d85fbb9b2901c77e6450cfd41c0a818ac1;hp=979749e401a446469b506638a08ac716cc639978;hpb=621c5c938d70ba0d155e0eda91a708db0a52c0dc;p=r2c2.git diff --git a/source/libr2c2/centralstation.cpp b/source/libr2c2/centralstation.cpp index 979749e..5e82f2e 100644 --- a/source/libr2c2/centralstation.cpp +++ b/source/libr2c2/centralstation.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -14,16 +15,16 @@ using namespace Msp; namespace R2C2 { -CentralStation::CentralStation(const string &host): +CentralStation::CentralStation(const Options &opts): socket(Net::INET), pending_commands(0), power(false), halted(false), locos_synced(false), - turnouts_synced(false), + accessories_synced(false), sensors_synced(false) { - RefPtr addr = Net::resolve(host+":15471"); + RefPtr addr = Net::resolve(opts.get(string())+":15471"); socket.connect(*addr); IO::print("Connected to central station at %s\n", addr->str()); @@ -40,7 +41,7 @@ CentralStation::~CentralStation() command("release(1, view)", true); for(LocoMap::iterator i=locos.begin(); (i!=locos.end() && !(i->first&0x10000)); ++i) command(format("release(%d, view, control)", i->first)); - for(TurnoutMap::iterator i=turnouts.begin(); (i!=turnouts.end() && !(i->first&0x10000)); ++i) + for(AccessoryMap::iterator i=accessories.begin(); (i!=accessories.end() && !(i->first&0x10000)); ++i) command(format("release(%d, view, control)", i->first)); while(IO::poll(socket, IO::P_INPUT, 100*Time::msec)) while(receive()) ; @@ -88,7 +89,7 @@ unsigned CentralStation::get_protocol_speed_steps(const string &name) const } } -void CentralStation::add_loco(unsigned addr, const string &proto_name, const VehicleType &type) +unsigned CentralStation::add_loco(unsigned addr, const string &proto_name, const VehicleType &type) { Protocol proto = map_protocol(proto_name); @@ -109,6 +110,15 @@ void CentralStation::add_loco(unsigned addr, const string &proto_name, const Veh } else command(format("request(%d, view, control, force)", id)); + + return addr; +} + +void CentralStation::remove_loco(unsigned addr) +{ + unsigned id = map_address(locos, loco_addr, addr); + if(id) + command(format("release(%d, view, control)", id)); } void CentralStation::set_loco_speed(unsigned addr, unsigned speed) @@ -140,8 +150,9 @@ void CentralStation::set_loco_function(unsigned addr, unsigned func, bool state) command(format("set(%d, func[%d, %d])", id, func, state)); } -void CentralStation::add_turnout(unsigned addr, const TrackType &type) +unsigned CentralStation::add_turnout(unsigned addr, const TrackType &type) { + unsigned straight = type.get_paths(); bool left = false; bool right = false; bool cross = false; @@ -149,84 +160,151 @@ void CentralStation::add_turnout(unsigned addr, const TrackType &type) const vector &parts = type.get_parts(); for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) { - TrackPoint start = i->get_point(0); - TrackPoint end = i->get_point(i->get_length()); - if(end.dir>start.dir+0.01) - left = true; - else if(end.dir0.01) + OrientedPoint start = i->get_point(0); + OrientedPoint end = i->get_point(i->get_length()); + if(abs(end.rotation-start.rotation).radians()<0.01) + { + (end.rotation>start.rotation ? left : right) = true; + straight &= ~(1<get_path()); + } + else if(abs(start.rotation).radians()>0.01) cross = true; } - unsigned symbol = Turnout::LEFT; + MagnetAccessory::Symbol symbol = MagnetAccessory::TURNOUT_LEFT; if(cross) - symbol = Turnout::DOUBLESLIP; + symbol = MagnetAccessory::TURNOUT_DOUBLESLIP; else if(left && right) - symbol = Turnout::THREEWAY; + symbol = MagnetAccessory::TURNOUT_THREEWAY; else if(left) - symbol = Turnout::LEFT; + symbol = (straight ? MagnetAccessory::TURNOUT_LEFT : MagnetAccessory::TURNOUT_CURVED_LEFT); else if(right) - symbol = Turnout::RIGHT; + symbol = (straight ? MagnetAccessory::TURNOUT_RIGHT : MagnetAccessory::TURNOUT_CURVED_RIGHT); + + MagnetAccessory &turnout = add_accessory(addr, MagnetAccessory::TURNOUT, symbol); + turnout.bits = type.get_state_bits(); + + return addr; +} + +void CentralStation::remove_turnout(unsigned addr) +{ + remove_accessory(addr); +} + +void CentralStation::set_turnout(unsigned addr, unsigned state) +{ + set_accessory_state(addr, MagnetAccessory::TURNOUT, state); +} + +unsigned CentralStation::get_turnout(unsigned addr) const +{ + return get_accessory_state(addr, MagnetAccessory::TURNOUT); +} + +unsigned CentralStation::add_signal(unsigned addr, const SignalType &) +{ + add_accessory(addr, MagnetAccessory::SIGNAL, MagnetAccessory::SEMAPHORE_HOME); + return addr; +} + +void CentralStation::remove_signal(unsigned addr) +{ + remove_accessory(addr); +} + +void CentralStation::set_signal(unsigned addr, unsigned state) +{ + set_accessory_state(addr, MagnetAccessory::SIGNAL, state); +} + +unsigned CentralStation::get_signal(unsigned addr) const +{ + return get_accessory_state(addr, MagnetAccessory::SIGNAL); +} - unsigned id = map_address(turnouts, turnout_addr, addr); +CentralStation::MagnetAccessory &CentralStation::add_accessory(unsigned addr, MagnetAccessory::Type type, MagnetAccessory::Symbol symbol) +{ + unsigned id = map_address(accessories, accessory_addr, addr); if(!id) { id = addr|0x10000; - Turnout &turnout = turnouts[id]; - turnout.address = addr; - turnout.bits = type.get_state_bits(); - turnout.symbol = symbol; + MagnetAccessory &accessory = accessories[id]; + accessory.address = addr; + accessory.type = type; + accessory.symbol = symbol; - turnout_addr[addr] = id; + accessory_addr[addr] = id; - if(turnouts_synced) + if(accessories_synced) command("create(11, append)"); + + return accessory; } else { - Turnout &turnout = turnouts[id]; + MagnetAccessory &accessory = accessories[id]; command(format("request(%d, view, control)", id)); - if(turnout.symbol!=symbol) + if(accessory.symbol!=symbol) command(format("set(%d, symbol[%d])", symbol)); + + return accessory; } } -void CentralStation::set_turnout(unsigned addr, unsigned state) +void CentralStation::remove_accessory(unsigned addr) { - unsigned id = map_address(turnouts, turnout_addr, addr); + unsigned id = map_address(accessories, accessory_addr, addr); + if(id) + command(format("release(%d, view, control)", id)); +} + +void CentralStation::set_accessory_state(unsigned addr, MagnetAccessory::Type type, unsigned state) +{ + unsigned id = map_address(accessories, accessory_addr, addr); if(id) { - Turnout &turnout = turnouts[id]; - unsigned mask = (1<second.type==type) return i->second.state; } return 0; } -void CentralStation::add_sensor(unsigned addr) +void CentralStation::accessory_state_changed(const MagnetAccessory &accessory) const +{ + if(accessory.type==MagnetAccessory::TURNOUT) + signal_turnout.emit(accessory.address, accessory.state); + else if(accessory.type==MagnetAccessory::SIGNAL) + signal_signal.emit(accessory.address, accessory.state); +} + +unsigned CentralStation::add_sensor(unsigned addr) { sensors.insert(SensorMap::value_type(addr, Sensor())); @@ -235,6 +313,12 @@ void CentralStation::add_sensor(unsigned addr) if(addr>s88.size()*16) command("create(26, add[0])"); } + + return addr; +} + +void CentralStation::remove_sensor(unsigned) +{ } bool CentralStation::get_sensor(unsigned addr) const @@ -245,6 +329,11 @@ bool CentralStation::get_sensor(unsigned addr) const return false; } +float CentralStation::get_telemetry_value(const string &name) const +{ + throw key_error(name); +} + void CentralStation::tick() { while(Message msg = receive()) @@ -317,8 +406,8 @@ void CentralStation::process_reply(const Message &msg) { for(Message::ObjectMap::const_iterator i=msg.content.begin(); i!=msg.content.end(); ++i) { - if(turnouts.count(i->first)) - turnouts[i->first].synced = true; + if(accessories.count(i->first)) + accessories[i->first].synced = true; process_object(i->first, i->second); } @@ -370,8 +459,8 @@ void CentralStation::process_reply(const Message &msg) { for(Message::ObjectMap::const_iterator i=msg.content.begin(); i!=msg.content.end(); ++i) { - TurnoutMap::iterator j = turnouts.find(i->first); - if(j==turnouts.end()) + AccessoryMap::iterator j = accessories.find(i->first); + if(j==accessories.end()) { bool found = false; Message::AttribMap::const_iterator k = i->second.find("addr"); @@ -379,30 +468,30 @@ void CentralStation::process_reply(const Message &msg) { unsigned addr = lexical_cast(k->second); - j = turnouts.find(addr|0x10000); - if(j!=turnouts.end()) + j = accessories.find(addr|0x10000); + if(j!=accessories.end()) { command(format("request(%d, view, control)", i->first)); command(format("set(%d, symbol[%d])", i->first, j->second.symbol)); command(format("get(%d, state)", i->first)); - turnouts.insert(TurnoutMap::value_type(i->first, j->second)); - turnouts.erase(j); + accessories.insert(AccessoryMap::value_type(i->first, j->second)); + accessories.erase(j); found = true; } } if(!found) - turnouts.insert(TurnoutMap::value_type(i->first, Turnout())); + accessories.insert(AccessoryMap::value_type(i->first, MagnetAccessory())); } process_object(i->first, i->second); } - turnouts_synced = true; + accessories_synced = true; - for(TurnoutMap::const_iterator i=turnouts.lower_bound(0x10000); i!=turnouts.end(); ++i) + for(AccessoryMap::const_iterator i=accessories.lower_bound(0x10000); i!=accessories.end(); ++i) command("create(11, append)"); } else if(msg.header.value=="queryObjects(26)") @@ -459,17 +548,18 @@ void CentralStation::process_reply(const Message &msg) if(j!=i->second.end()) { unsigned id = lexical_cast(j->second); - TurnoutMap::iterator k = turnouts.lower_bound(0x10000); - if(k!=turnouts.end()) + AccessoryMap::iterator k = accessories.lower_bound(0x10000); + if(k!=accessories.end()) { command(format("request(%d, view, control)", id)); - command(format("set(%d, addr[%d], symbol[%d], name1[\"Switch\"], name2[\"%d\"], name3[\"\"])", - id, k->second.address, k->second.symbol, k->second.address)); + const char *label = (k->second.type==MagnetAccessory::SIGNAL ? "Signal" : "Switch"); + command(format("set(%d, addr[%d], symbol[%d], name1[\"%s\"], name2[\"%d\"], name3[\"\"])", + id, k->second.address, k->second.symbol, label, k->second.address)); command(format("set(%d, state[%d])", id, k->second.state&((1<second.bits)-1))); k->second.synced = true; - turnouts.insert(TurnoutMap::value_type(id, k->second)); - turnouts.erase(k); + accessories.insert(AccessoryMap::value_type(id, k->second)); + accessories.erase(k); } } } @@ -554,29 +644,29 @@ void CentralStation::process_object(unsigned id, const Message::AttribMap &attri if(funcs_changed&(1<first=="addr") { - turnout_addr.erase(turnout.address); - turnout.address = lexical_cast(i->second); - turnout_addr[turnout.address] = id; + accessory_addr.erase(accessory.address); + accessory.address = lexical_cast(i->second); + accessory_addr[accessory.address] = id; } else if(i->first=="state") { unsigned state = lexical_cast(i->second); - unsigned mask = (1<