]> git.mxchange.org Git - flightgear.git/blob - utils/fgpanel/FGPanelProtocol.cxx
Merge branch 'next' into comm-subsystem
[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 protected:
42   SGPropertyNode_ptr _node;
43 };
44
45 class BoolPropertySetter : public PropertySetter {
46 public:
47   BoolPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
48   virtual void setValue( const char * value ) {
49     _node->setBoolValue( atoi( value ) != 0 );
50   }
51 };
52
53 class IntPropertySetter : public PropertySetter {
54 public:
55   IntPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
56   virtual void setValue( const char * value ) {
57     _node->setIntValue( atol( value ) );
58   }
59 };
60
61 class FloatPropertySetter : public PropertySetter {
62 public:
63   FloatPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
64   virtual void setValue( const char * value ) {
65     _node->setFloatValue( strtof( value, NULL ) );
66   }
67 };
68
69 class DoublePropertySetter : public PropertySetter {
70 public:
71   DoublePropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
72   virtual void setValue( const char * value ) {
73     _node->setDoubleValue( strtod( value, NULL ) );
74   }
75 };
76
77 class StringPropertySetter : public PropertySetter {
78 public:
79   StringPropertySetter( SGPropertyNode_ptr node ) : PropertySetter(node) {}
80   virtual void setValue( const char * value ) {
81     _node->setStringValue( value );
82   }
83 };
84
85 FGPanelProtocol::FGPanelProtocol( SGPropertyNode_ptr aRoot )
86   : SGSubsystem(),
87    root(aRoot),
88    io(NULL)
89 {
90   SGPropertyNode_ptr outputNode = root->getNode( "protocol/generic/output" );
91   if( outputNode ) {
92     vector<SGPropertyNode_ptr> chunks = outputNode->getChildren( "chunk" );
93     for( vector<SGPropertyNode_ptr>::size_type i = 0; i < chunks.size(); i++ ) {
94       SGPropertyNode_ptr chunk = chunks[i];
95
96       SGPropertyNode_ptr nodeNode = chunk->getNode("node", false );
97       if( nodeNode == NULL )
98         continue;
99
100       SGPropertyNode_ptr node = ApplicationProperties::Properties->getNode( nodeNode->getStringValue(), true );
101
102       string type = "";
103       SGPropertyNode_ptr typeNode = chunk->getNode( "type", false );
104       if( typeNode != NULL ) type = typeNode->getStringValue();
105       if( type == "float" ) {
106         propertySetterVector.push_back( new FloatPropertySetter( node ) );
107       } else if( type == "double" || type == "fixed" ) {
108         propertySetterVector.push_back( new DoublePropertySetter( node ) );
109       } else if( type == "bool" || type == "boolean" ) {
110         propertySetterVector.push_back( new BoolPropertySetter( node ) );
111       } else if( type == "string" ) {
112         propertySetterVector.push_back( new StringPropertySetter( node ) );
113       } else {
114         propertySetterVector.push_back( new IntPropertySetter( node ) );
115       }
116     }
117   }
118 }
119
120 FGPanelProtocol::~FGPanelProtocol()
121 {
122   for( PropertySetterVector::size_type i = 0; i < propertySetterVector.size(); i++ )
123     delete propertySetterVector[i];
124 }
125
126 void FGPanelProtocol::update( double dt )
127 {
128   char buf[2][8192];
129
130   if( io == NULL )
131     return;
132
133   // read all available lines, keep last one
134   int Page = 0;
135   bool HaveData = false;
136   while ( io->readline( buf[Page], sizeof(buf[Page])-1 ) > 0 )
137   {
138       HaveData = true;
139       Page ^= 1;
140   }
141
142   if ( HaveData ) {
143     // process most recent line of data
144     Page ^= 1;
145     buf[Page][sizeof(buf[Page])-1] = 0;
146     vector<string> tokens = simgear::strutils::split( buf[Page], "," );
147     for( vector<string>::size_type i = 0; i < tokens.size(); i++ ) {
148       if( i < propertySetterVector.size() )
149         propertySetterVector[i]->setValue( tokens[i].c_str() );
150     }
151   }
152 }
153
154 void FGPanelProtocol::init()
155 {
156   SGPropertyNode_ptr listenNode = root->getNode( "listen" );
157   if( listenNode == NULL ) {
158     return;
159   }
160
161   string hostname = listenNode->getNode( "host", true )->getStringValue();
162   string port = listenNode->getNode( "port", true )->getStringValue();
163   string style = listenNode->getNode( "style", true )->getStringValue();
164
165   if( io != NULL )
166     delete io;
167
168   io = new SGSocket( hostname, port, style );
169
170   if( !io->open( SG_IO_IN ) ) {
171     cerr << "can't open socket " << style << ":" << hostname << ":" << port << endl;
172   }
173 }
174
175 void FGPanelProtocol::reinit()
176 {
177   init();
178 }