]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/centralstation.cpp
Use skylight for nicer lighting
[r2c2.git] / source / libr2c2 / centralstation.cpp
index 833560ae727a5839151105b625da6e363a76a662..5e82f2e5f117c23d9137bb80ff41b0b4359d2ecb 100644 (file)
@@ -1,4 +1,5 @@
 #include <algorithm>
+#include <msp/core/maputils.h>
 #include <msp/core/refptr.h>
 #include <msp/io/print.h>
 #include <msp/net/resolve.h>
@@ -14,7 +15,7 @@ using namespace Msp;
 
 namespace R2C2 {
 
-CentralStation::CentralStation(const string &host):
+CentralStation::CentralStation(const Options &opts):
        socket(Net::INET),
        pending_commands(0),
        power(false),
@@ -23,7 +24,7 @@ CentralStation::CentralStation(const string &host):
        accessories_synced(false),
        sensors_synced(false)
 {
-       RefPtr<Net::SockAddr> addr = Net::resolve(host+":15471");
+       RefPtr<Net::SockAddr> addr = Net::resolve(opts.get<string>(string())+":15471");
        socket.connect(*addr);
 
        IO::print("Connected to central station at %s\n", addr->str());
@@ -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,7 +150,7 @@ 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;
@@ -150,14 +160,14 @@ void CentralStation::add_turnout(unsigned addr, const TrackType &type)
        const vector<TrackPart> &parts = type.get_parts();
        for(vector<TrackPart>::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 || end.dir<start.dir-0.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.dir>start.dir ? left : right) = true;
+                       (end.rotation>start.rotation ? left : right) = true;
                        straight &= ~(1<<i->get_path());
                }
-               else if(start.dir<-0.01 || start.dir>0.01)
+               else if(abs(start.rotation).radians()>0.01)
                        cross = true;
        }
 
@@ -173,6 +183,13 @@ void CentralStation::add_turnout(unsigned addr, const TrackType &type)
 
        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)
@@ -185,6 +202,27 @@ 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);
+}
+
 CentralStation::MagnetAccessory &CentralStation::add_accessory(unsigned addr, MagnetAccessory::Type type, MagnetAccessory::Symbol symbol)
 {
        unsigned id = map_address(accessories, accessory_addr, addr);
@@ -215,6 +253,13 @@ CentralStation::MagnetAccessory &CentralStation::add_accessory(unsigned addr, Ma
        }
 }
 
+void CentralStation::remove_accessory(unsigned 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);
@@ -255,9 +300,11 @@ void CentralStation::accessory_state_changed(const MagnetAccessory &accessory) c
 {
        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);
 }
 
-void CentralStation::add_sensor(unsigned addr)
+unsigned CentralStation::add_sensor(unsigned addr)
 {
        sensors.insert(SensorMap::value_type(addr, Sensor()));
 
@@ -266,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
@@ -276,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())
@@ -494,8 +552,9 @@ void CentralStation::process_reply(const Message &msg)
                                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<<k->second.bits)-1)));
 
                                        k->second.synced = true;