]> git.mxchange.org Git - flightgear.git/blob - utils/fgpanel/FGPanelProtocol.cxx
Fix standalone terrasync build
[flightgear.git] / utils / fgpanel / FGPanelProtocol.cxx
1 //
2 //  Written and (c) Torsten Dreyer - Torsten(at)t3r_dot_de
3 //
4 //  This program is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU General Public License as
6 //  published by the Free Software Foundation; either version 2 of the
7 //  License, or (at your option) any later version.
8 // 
9 //  This program is distributed in the hope that it will be useful, but
10 //  WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 //  General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //
18 #ifdef HAVE_CONFIG_H
19 #  include <config.h>
20 #endif
21
22 #ifdef HAVE_WINDOWS_H
23 #include <windows.h>
24 #endif
25
26 #ifdef WIN32
27 #define strtof strtod
28 #endif
29
30 #include "FGPanelProtocol.hxx"
31 #include "ApplicationProperties.hxx"
32 #include <simgear/io/sg_socket.hxx>
33 #include <simgear/misc/strutils.hxx>
34
35 using namespace std;
36
37 class PropertySetter {
38 public:
39   PropertySetter( SGPropertyNode_ptr node ) : _node(node) {}
40   virtual void setValue( const char * value ) = 0;
41   virtual ~PropertySetter() {};
42 protected:
43   SGPropertyNode_ptr _node;
44 };
45
46 class BoolPropertySetter : public PropertySetter {
47 public:
48   BoolPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
49   virtual void setValue( const char * value ) {
50     _node->setBoolValue( atoi( value ) != 0 );
51   }
52 };
53
54 class IntPropertySetter : public PropertySetter {
55 public:
56   IntPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
57   virtual void setValue( const char * value ) {
58     _node->setIntValue( atol( value ) );
59   }
60 };
61
62 class FloatPropertySetter : public PropertySetter {
63 public:
64   FloatPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
65   virtual void setValue( const char * value ) {
66     _node->setFloatValue( strtof( value, NULL ) );
67   }
68 };
69
70 class DoublePropertySetter : public PropertySetter {
71 public:
72   DoublePropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
73   virtual void setValue( const char * value ) {
74     _node->setDoubleValue( strtod( value, NULL ) );
75   }
76 };
77
78 class StringPropertySetter : public PropertySetter {
79 public:
80   StringPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
81   virtual void setValue( const char * value ) {
82     _node->setStringValue( value );
83   }
84 };
85
86 FGPanelProtocol::FGPanelProtocol( SGPropertyNode_ptr aRoot )
87   : SGSubsystem(),
88    root(aRoot),
89    io(NULL)
90 {
91   SGPropertyNode_ptr outputNode = root->getNode( "protocol/generic/output" );
92   if( outputNode ) {
93     vector<SGPropertyNode_ptr> chunks = outputNode->getChildren( "chunk" );
94     for( vector<SGPropertyNode_ptr>::size_type i = 0; i < chunks.size(); i++ ) {
95       SGPropertyNode_ptr chunk = chunks[i];
96
97       SGPropertyNode_ptr nodeNode = chunk->getNode("node", false );
98       if( nodeNode == NULL )
99         continue;
100
101       SGPropertyNode_ptr node = ApplicationProperties::Properties->getNode( nodeNode->getStringValue(), true );
102
103       string type = "";
104       SGPropertyNode_ptr typeNode = chunk->getNode( "type", false );
105       if( typeNode != NULL ) type = typeNode->getStringValue();
106       if( type == "float" ) {
107         propertySetterVector.push_back( new FloatPropertySetter( node ) );
108       } else if( type == "double" || type == "fixed" ) {
109         propertySetterVector.push_back( new DoublePropertySetter( node ) );
110       } else if( type == "bool" || type == "boolean" ) {
111         propertySetterVector.push_back( new BoolPropertySetter( node ) );
112       } else if( type == "string" ) {
113         propertySetterVector.push_back( new StringPropertySetter( node ) );
114       } else {
115         propertySetterVector.push_back( new IntPropertySetter( node ) );
116       }
117     }
118   }
119 }
120
121 FGPanelProtocol::~FGPanelProtocol()
122 {
123   for( PropertySetterVector::size_type i = 0; i < propertySetterVector.size(); i++ )
124     delete propertySetterVector[i];
125 }
126
127 void FGPanelProtocol::update( double dt )
128 {
129   char buf[2][8192];
130
131   if( io == NULL )
132     return;
133
134   // read all available lines, keep last one
135   int Page = 0;
136   bool HaveData = false;
137   while ( io->readline( buf[Page], sizeof(buf[Page])-1 ) > 0 )
138   {
139       HaveData = true;
140       Page ^= 1;
141   }
142
143   if ( HaveData ) {
144     // process most recent line of data
145     Page ^= 1;
146     buf[Page][sizeof(buf[Page])-1] = 0;
147     vector<string> tokens = simgear::strutils::split( buf[Page], "," );
148     for( vector<string>::size_type i = 0; i < tokens.size(); i++ ) {
149       if( i < propertySetterVector.size() )
150         propertySetterVector[i]->setValue( tokens[i].c_str() );
151     }
152   }
153 }
154
155 void FGPanelProtocol::init()
156 {
157   SGPropertyNode_ptr listenNode = root->getNode( "listen" );
158   if( listenNode == NULL ) {
159     return;
160   }
161
162   string hostname = listenNode->getNode( "host", true )->getStringValue();
163   string port = listenNode->getNode( "port", true )->getStringValue();
164   string style = listenNode->getNode( "style", true )->getStringValue();
165
166   if( io != NULL )
167     delete io;
168
169   io = new SGSocket( hostname, port, style );
170
171   if( !io->open( SG_IO_IN ) ) {
172     cerr << "can't open socket " << style << ":" << hostname << ":" << port << endl;
173   }
174 }
175
176 void FGPanelProtocol::reinit()
177 {
178   init();
179 }