void AIControl::set_reverse(bool r)
{
pending_reverse = r;
+ if(r==reverse)
+ return;
+
if(train.get_controller().get_speed())
set_target_speed(0);
else
get_train(pkt.address).process_packet(pkt);
}
+void Client::receive(const TrainAIControlPacket &pkt)
+{
+ get_train(pkt.address).process_packet(pkt);
+}
+
void Client::receive(const TrainStatusPacket &pkt)
{
get_train(pkt.address).process_packet(pkt);
Msp::Net::PacketReceiver<TrainInfoPacket>,
Msp::Net::PacketReceiver<TrainFunctionPacket>,
Msp::Net::PacketReceiver<TrainControlPacket>,
+ Msp::Net::PacketReceiver<TrainAIControlPacket>,
Msp::Net::PacketReceiver<TrainStatusPacket>,
Msp::Net::PacketReceiver<RouteInfoPacket>,
Msp::Net::PacketReceiver<TrainRoutePacket>,
virtual void receive(const TrainInfoPacket &);
virtual void receive(const TrainControlPacket &);
virtual void receive(const TrainFunctionPacket &);
+ virtual void receive(const TrainAIControlPacket &);
virtual void receive(const TrainStatusPacket &);
virtual void receive(const RouteInfoPacket &);
virtual void receive(const TrainRoutePacket &);
unsigned functions;
};
+struct TrainAIControlPacket
+{
+ unsigned address;
+ float target_speed;
+ char reverse;
+};
+
struct TrainStatusPacket
{
unsigned address;
(&TrainControlPacket::control) (&TrainControlPacket::value);
add<TrainFunctionPacket>() (&TrainFunctionPacket::address)
(&TrainFunctionPacket::functions);
+ add<TrainAIControlPacket>() (&TrainAIControlPacket::address)
+ (&TrainAIControlPacket::target_speed) (&TrainAIControlPacket::reverse);
add<TrainStatusPacket>() (&TrainStatusPacket::address)
(&TrainStatusPacket::status);
add<RouteInfoPacket>() (&RouteInfoPacket::name);
#include <msp/core/refptr.h>
#include <msp/net/inet.h>
#include <msp/net/resolve.h>
+#include "libr2c2/aicontrol.h"
#include "libr2c2/catalogue.h"
#include "libr2c2/driver.h"
#include "libr2c2/route.h"
send(pkt);
}
-void Server::train_ai_event(const Train &train, TrainAI &, const TrainAI::Message &ev)
+void Server::train_ai_event(const Train &train, TrainAI &ai, const TrainAI::Message &ev)
{
if(ev.type=="route-changed")
{
pkt.status = ev.value.value<std::string>();
send(pkt);
}
+ else if(ev.type=="target-speed-changed" || ev.type=="reverse-changed")
+ {
+ AIControl *control = dynamic_cast<AIControl *>(&ai);
+ if(control)
+ {
+ TrainAIControlPacket pkt;
+ pkt.address = train.get_address();
+ pkt.target_speed = control->get_target_speed();
+ pkt.reverse = control->get_reverse();
+ send(pkt);
+ }
+ }
}
template<typename P>
pkt.name = train.get_name();
comm.send(pkt);
}
+ if(AIControl *control = train.get_ai_of_type<AIControl>())
+ {
+ TrainAIControlPacket pkt;
+ pkt.address = train.get_address();
+ pkt.target_speed = control->get_target_speed();
+ pkt.reverse = control->get_reverse();
+ comm.send(pkt);
+ }
for(unsigned j=0;; ++j)
{
const char *name = train.get_controller().enumerate_controls(j);
}
}
+void Server::Connection::receive(const TrainAIControlPacket &pkt)
+{
+ try
+ {
+ Train &train = server.layout.get_train(pkt.address);
+ train.ai_message(TrainAI::Message("set-target-speed", pkt.target_speed));
+ train.ai_message(TrainAI::Message("set-reverse", pkt.reverse));
+ }
+ catch(const exception &e)
+ {
+ error(e.what());
+ }
+}
+
void Server::Connection::receive(const TrainRoutePacket &pkt)
{
try
struct Connection: Msp::Net::PacketReceiver<DriverStatePacket>,
Msp::Net::PacketReceiver<TrainControlPacket>,
Msp::Net::PacketReceiver<TrainFunctionPacket>,
+ Msp::Net::PacketReceiver<TrainAIControlPacket>,
Msp::Net::PacketReceiver<TrainRoutePacket>
{
Server &server;
virtual void receive(const DriverStatePacket &);
virtual void receive(const TrainControlPacket &);
virtual void receive(const TrainFunctionPacket &);
+ virtual void receive(const TrainAIControlPacket &);
virtual void receive(const TrainRoutePacket &);
void comm_error(const std::exception &);
void error(const std::string &);
loco_type(client.get_catalogue().get<VehicleType>(pkt.loco_type)),
address(pkt.address),
name(pkt.name),
+ target_speed(0),
+ reverse(false),
functions(0)
{ }
return i!=controls.end() ? i->second : 0;
}
+void NetTrain::set_target_speed(float s)
+{
+ TrainAIControlPacket pkt;
+ pkt.address = address;
+ pkt.target_speed = s;
+ pkt.reverse = reverse;
+ client.send(pkt);
+}
+
+void NetTrain::set_reverse(bool r)
+{
+ TrainAIControlPacket pkt;
+ pkt.address = address;
+ pkt.target_speed = target_speed;
+ pkt.reverse = r;
+ client.send(pkt);
+}
+
void NetTrain::set_function(unsigned i, bool set)
{
TrainFunctionPacket pkt;
signal_function_changed.emit(i, (functions>>i)&1);
}
+void NetTrain::process_packet(const TrainAIControlPacket &pkt)
+{
+ if(pkt.target_speed!=target_speed)
+ {
+ target_speed = pkt.target_speed;
+ signal_target_speed_changed.emit(target_speed);
+ }
+
+ if(pkt.reverse!=reverse)
+ {
+ reverse = pkt.reverse;
+ signal_reverse_changed.emit(reverse);
+ }
+}
+
void NetTrain::process_packet(const TrainStatusPacket &pkt)
{
status = pkt.status;
sigc::signal<void, const std::string &> signal_name_changed;
sigc::signal<void, const std::string &, float> signal_control_changed;
sigc::signal<void, unsigned, bool> signal_function_changed;
+ sigc::signal<void, float> signal_target_speed_changed;
+ sigc::signal<void, bool> signal_reverse_changed;
sigc::signal<void, const std::string &> signal_route_changed;
sigc::signal<void, const std::string &> signal_status_changed;
unsigned address;
std::string name;
std::map<std::string, float> controls;
+ float target_speed;
+ bool reverse;
unsigned functions;
std::string route;
std::string status;
const std::string &get_name() const { return name; }
void set_control(const std::string &, float);
float get_control(const std::string &) const;
+ void set_target_speed(float);
+ void set_reverse(bool);
+ float get_target_speed() const { return target_speed; }
+ bool get_reverse() const { return reverse; }
void set_function(unsigned, bool);
bool get_function(unsigned i) const { return (functions>>i)&1; }
void set_route(const std::string &);
void process_packet(const TrainControlPacket &);
void process_packet(const TrainFunctionPacket &);
+ void process_packet(const TrainAIControlPacket &);
void process_packet(const TrainRoutePacket &);
void process_packet(const TrainStatusPacket &);
};