From 4f2b6023dee412373a6a0b13ba4d617ffbb9bb38 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 27 Jan 2013 15:21:13 +0200 Subject: [PATCH] Generalize turnouts to magnet accessories in the central station driver --- source/libr2c2/centralstation.cpp | 138 ++++++++++++++++++------------ source/libr2c2/centralstation.h | 39 ++++++--- 2 files changed, 110 insertions(+), 67 deletions(-) diff --git a/source/libr2c2/centralstation.cpp b/source/libr2c2/centralstation.cpp index 3a9624a..833560a 100644 --- a/source/libr2c2/centralstation.cpp +++ b/source/libr2c2/centralstation.cpp @@ -20,7 +20,7 @@ CentralStation::CentralStation(const string &host): power(false), halted(false), locos_synced(false), - turnouts_synced(false), + accessories_synced(false), sensors_synced(false) { RefPtr addr = Net::resolve(host+":15471"); @@ -40,7 +40,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()) ; @@ -161,73 +161,102 @@ void CentralStation::add_turnout(unsigned addr, const TrackType &type) 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 = (straight ? Turnout::LEFT : Turnout::CURVED_LEFT); + symbol = (straight ? MagnetAccessory::TURNOUT_LEFT : MagnetAccessory::TURNOUT_CURVED_LEFT); else if(right) - symbol = (straight ? Turnout::RIGHT : Turnout::CURVED_RIGHT); + symbol = (straight ? MagnetAccessory::TURNOUT_RIGHT : MagnetAccessory::TURNOUT_CURVED_RIGHT); - unsigned id = map_address(turnouts, turnout_addr, addr); + MagnetAccessory &turnout = add_accessory(addr, MagnetAccessory::TURNOUT, symbol); + turnout.bits = type.get_state_bits(); +} + +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); +} + +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::set_accessory_state(unsigned addr, MagnetAccessory::Type type, unsigned state) { - unsigned id = map_address(turnouts, turnout_addr, addr); + 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::accessory_state_changed(const MagnetAccessory &accessory) const +{ + if(accessory.type==MagnetAccessory::TURNOUT) + signal_turnout.emit(accessory.address, accessory.state); +} + void CentralStation::add_sensor(unsigned addr) { sensors.insert(SensorMap::value_type(addr, Sensor())); @@ -319,8 +348,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); } @@ -372,8 +401,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"); @@ -381,30 +410,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)") @@ -461,8 +490,8 @@ 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[\"\"])", @@ -470,8 +499,8 @@ void CentralStation::process_reply(const Message &msg) 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); } } } @@ -556,29 +585,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< AddressMap; typedef std::map LocoMap; - typedef std::map TurnoutMap; + typedef std::map AccessoryMap; typedef std::map SensorMap; Msp::Net::StreamSocket socket; @@ -110,9 +116,9 @@ private: LocoMap locos; AddressMap loco_addr; bool locos_synced; - TurnoutMap turnouts; - AddressMap turnout_addr; - bool turnouts_synced; + AccessoryMap accessories; + AddressMap accessory_addr; + bool accessories_synced; SensorMap sensors; std::vector s88; bool sensors_synced; @@ -138,6 +144,13 @@ public: virtual void set_turnout(unsigned, unsigned); virtual unsigned get_turnout(unsigned) const; +private: + MagnetAccessory &add_accessory(unsigned, MagnetAccessory::Type, MagnetAccessory::Symbol); + void set_accessory_state(unsigned, MagnetAccessory::Type, unsigned); + unsigned get_accessory_state(unsigned, MagnetAccessory::Type) const; + void accessory_state_changed(const MagnetAccessory &) const; + +public: virtual void add_sensor(unsigned); virtual void set_sensor(unsigned, bool) { } virtual bool get_sensor(unsigned) const; -- 2.43.0