1 // Expose FGProtocol module to Nasal to enable I/O protocols to be implemented in Nasal space, e.g.
2 // to support REST/AJAX, JSON or HTTP WebSockets: https://code.google.com/p/flightgear-bugs/issues/detail?id=396
4 // Copyright (C) 2013 The FlightGear community
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License as
8 // published by the Free Software Foundation; either version 2 of the
9 // License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "NasalFGProtocol.hxx"
25 #include <Main/globals.hxx>
26 #include <Main/util.hxx>
27 #include <Main/fg_io.hxx>
29 // supported SGIOChannels
30 #include <simgear/io/iochannel.hxx>
31 #include <simgear/io/sg_file.hxx>
32 #include <simgear/io/sg_serial.hxx>
33 #include <simgear/io/sg_socket.hxx>
34 #include <simgear/io/sg_socket_udp.hxx>
36 #include <simgear/nasal/cppbind/from_nasal.hxx>
37 #include <simgear/nasal/cppbind/to_nasal.hxx>
38 #include <simgear/nasal/cppbind/NasalHash.hxx>
39 #include <simgear/nasal/cppbind/Ghost.hxx>
42 typedef boost::shared_ptr<simgear::NetChat> NasalNetChat_ptr;
43 typedef nasal::Ghost< NasalNetChat_ptr > NasalNetChat;
45 typedef boost::shared_ptr<simgear::NetChannel> NasalNetChannel_ptr;
46 typedef nasal::Ghost< NasalNetChannel_ptr > NasalNetChannel;
50 class NasalProtocolWrapper;
52 typedef boost::shared_ptr<NasalProtocolWrapper> NasalProtocolWrapper_ptr;
53 typedef nasal::Ghost< NasalProtocolWrapper_ptr > NasalProtocol;
55 class NasalProtocolWrapper : public FGProtocol {
57 NasalProtocolWrapper(const nasal::CallContext& ctx);
58 void register_handler();
70 //FIXME: move this out of the constructor, this was just for demonstration purposes
71 NasalProtocolWrapper::NasalProtocolWrapper(const nasal::CallContext& ctx) {
72 //TODO: see parse_port_config() in Main/fg_io.cxx
73 std::string medium = ctx.requireArg<std::string>(0);
74 std::string direction = ctx.requireArg<std::string>(1);
75 std::string rate_hz = ctx.requireArg<std::string>(2);
77 FGProtocol::set_direction( direction );
78 FGProtocol::set_hz( atof(rate_hz.c_str()) );
80 if(medium=="socket") {
81 // look for other arguments:
82 std::string host = ctx.requireArg<std::string>(3);
83 std::string port = ctx.requireArg<std::string>(4);
84 std::string style = ctx.requireArg<std::string>(5);
86 // http://docs.freeflightsim.org/simgear/classSGSocket.html
87 set_io_channel( new SGSocket( host, port, style ) );
90 SG_LOG(SG_IO, SG_ALERT, "NasalProtocolWrapper: Unsupported medium: "<< medium << std::endl);
96 NasalProtocolWrapper::register_handler() {
97 static_cast<FGIO*> (globals->get_subsystem( "io" )) ->add_channel( this );
101 NasalProtocolWrapper::open() {
102 SG_LOG(SG_GENERAL, SG_ALERT, "::open" << std::endl);
108 NasalProtocolWrapper::process() {
109 SG_LOG(SG_GENERAL, SG_ALERT, "::process" << std::endl);
114 NasalProtocolWrapper::close() {
115 SG_LOG(SG_GENERAL, SG_ALERT, "::close" << std::endl);
121 NasalProtocolWrapper::gen_message() {
122 SG_LOG(SG_GENERAL, SG_ALERT, "::gen_message" << std::endl);
127 NasalProtocolWrapper::parse_message() {
128 SG_LOG(SG_GENERAL, SG_ALERT, "::parse_message" << std::endl);
133 NasalProtocolWrapper::set_direction() {
134 SG_LOG(SG_GENERAL, SG_ALERT, "::set_direction" << std::endl);
140 naRef to_nasal_helper(naContext c, NasalProtocolWrapper *obj)
142 NasalProtocolWrapper_ptr ptr(obj);
143 return NasalProtocol::create(c, ptr );
147 NasalProtocolWrapper*
148 from_nasal_helper(naContext c, naRef ref, const NasalProtocolWrapper*)
150 return (NasalProtocolWrapper*) naGhost_ptr(ref);
153 naRef to_nasal_helper(naContext c, simgear::NetChat *obj)
155 NasalNetChat_ptr ptr(obj);
156 return NasalNetChat::create(c, ptr );
161 from_nasal_helper(naContext c, naRef ref, const simgear::NetChat*)
163 return (simgear::NetChat*) naGhost_ptr(ref);
166 naRef to_nasal_helper(naContext c, simgear::NetChannel *obj)
168 NasalNetChannel_ptr ptr(obj);
169 return NasalNetChannel::create(c, ptr );
174 from_nasal_helper(naContext c, naRef ref, const simgear::NetChannel*)
176 return (simgear::NetChannel*) naGhost_ptr(ref);
180 static naRef f_new_protocol(const nasal::CallContext& ctx)
182 NasalProtocolWrapper* proto = NULL;
184 proto = new NasalProtocolWrapper(ctx);
190 return ctx.to_nasal( proto );
193 //------------------------------------------------------------------------------
194 naRef initNasalFGProtocol(naRef globals, naContext c)
196 // This is where you want to expose all required methods from FGProtocol/NetChat/NetChannel
198 // http://docs.freeflightsim.org/simgear/classsimgear_1_1NetChat.html
199 NasalNetChat::init("io.netchat")
200 .method("setTerminator", &simgear::NetChat::setTerminator)
201 .method("getTerminator", &simgear::NetChat::getTerminator);
203 // http://docs.freeflightsim.org/simgear/classsimgear_1_1NetChannel.html
204 NasalNetChannel::init("io.netchannel")
205 .method("close", &simgear::NetChannel::close);
207 NasalProtocol::init("io.protocol")
208 .method("register", &NasalProtocolWrapper::register_handler)
209 .method("open", &NasalProtocolWrapper::open)
210 .method("close", &NasalProtocolWrapper::close)
211 .method("gen_message", &NasalProtocolWrapper::gen_message)
212 .method("parse_message", &NasalProtocolWrapper::parse_message)
213 .method("set_direction", &NasalProtocolWrapper::set_direction);
215 nasal::Hash globals_module(globals, c);
216 nasal::Hash protocol = globals_module.createHash("protocol");
217 protocol.set("new", &f_new_protocol);