-/* $Id$
-
-This file is part of R²C²
-Copyright © 2010 Mikkosoft Productions, Mikko Rasa
-Distributed under the GPL
-*/
-
#include <algorithm>
#include <msp/core/refptr.h>
#include <msp/io/print.h>
{
case MM: return 14;
case MM_27: return 27;
- case MFX: return 127;
+ case MFX: return 126;
default: return 0;
}
}
loco.protocol = proto;
loco.address = addr;
+ const VehicleType::FunctionMap &type_funcs = type.get_functions();
+ for(VehicleType::FunctionMap::const_iterator i=type_funcs.begin(); i!=type_funcs.end(); ++i)
+ loco.func_mask |= 1<<i->first;
+
if(locos_synced && proto!=MFX)
command("create(10)");
}
unsigned id = map_address(locos, loco_addr, addr);
if(id)
+ {
+ Locomotive &loco = locos[id];
+ if(loco.protocol==MFX && speed)
+ ++speed;
command(format("set(%d, speedstep[%d])", id, speed));
+ }
}
void CentralStation::set_loco_reverse(unsigned addr, bool rev)
void CentralStation::add_turnout(unsigned addr, const TrackType &type)
{
+ unsigned straight = type.get_paths();
bool left = false;
bool right = false;
bool cross = false;
{
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.dir<start.dir-0.01)
- right = true;
+ if(end.dir>start.dir+0.01 || end.dir<start.dir-0.01)
+ {
+ (end.dir>start.dir ? left : right) = true;
+ straight &= ~(1<<i->get_path());
+ }
else if(start.dir<-0.01 || start.dir>0.01)
cross = true;
}
- unsigned symbol;
+ unsigned symbol = Turnout::LEFT;
if(cross)
symbol = Turnout::DOUBLESLIP;
else if(left && right)
symbol = Turnout::THREEWAY;
else if(left)
- symbol = Turnout::LEFT;
+ symbol = (straight ? Turnout::LEFT : Turnout::CURVED_LEFT);
else if(right)
- symbol = Turnout::RIGHT;
+ symbol = (straight ? Turnout::RIGHT : Turnout::CURVED_RIGHT);
unsigned id = map_address(turnouts, turnout_addr, addr);
if(!id)
void CentralStation::tick()
{
- Time::TimeStamp t = Time::now();
- for(SensorMap::iterator i=sensors.begin(); i!=sensors.end(); ++i)
- if(i->second.off_timeout && t>i->second.off_timeout)
- {
- i->second.state = false;
- i->second.off_timeout = Time::TimeStamp();
- signal_sensor.emit(i->first, i->second.state);
- }
-
while(Message msg = receive())
{
if(msg.footer.code)
if(j!=locos.end())
{
command(format("request(%d, view, control, force)", i->first));
- command(format("get(%d, dir, func[0])", i->first));
+ string cmd = format("get(%d, dir", i->first);
+ for(unsigned l=0; j->second.func_mask>>l; ++l)
+ if((j->second.func_mask>>l)&1)
+ cmd += format(", func[%d]", l);
+ cmd += ')';
+ command(cmd);
locos.insert(LocoMap::value_type(i->first, j->second));
locos.erase(j);
{
s88.push_back(i->first);
command(format("request(%d, view)", i->first));
+ command(format("get(%d, state)", i->first));
}
sensors_synced = true;
else if(i->first=="speedstep")
{
loco.speed = lexical_cast<unsigned>(i->second);
+ if(loco.protocol==MFX && loco.speed)
+ --loco.speed;
speed_changed = true;
}
else if(i->first=="dir")
unsigned addr = base*16+j+1;
Sensor &sensor = sensors[addr];
bool s = state&(1<<j);
- if(s)
+ if(s!=sensor.state)
{
- sensor.off_timeout = Time::TimeStamp();
- if(!sensor.state)
- {
- sensor.state = true;
- signal_sensor.emit(addr, sensor.state);
- }
+ sensor.state = s;
+ signal_sensor.emit(addr, sensor.state);
}
- else if(sensor.state)
- sensor.off_timeout = Time::now()+700*Time::msec;
}
}
}
else if(name=="MFX")
return MFX;
else
- throw InvalidParameterValue("Unknown protocol");
+ throw invalid_argument("CentralStation::map_protocol");
}
template<typename T>
if(open_bracket!=string::npos)
{
string::size_type close_bracket = attr.rfind(']');
- attribs[attr.substr(0, open_bracket)] = attr.substr(open_bracket+1, close_bracket-open_bracket-1);
+ string attr_name = attr.substr(0, open_bracket);
+ string attr_value = attr.substr(open_bracket+1, close_bracket-open_bracket-1);
+ attribs.insert(Message::AttribMap::value_type(attr_name, attr_value));
}
else
- attribs[attr];
+ attribs.insert(Message::AttribMap::value_type(attr, string()));
}
}
address(0),
speed(0),
reverse(false),
+ func_mask(0),
funcs(0),
control(false)
{ }