source: xplra/src/client/c/hu/varadiistvan/xplra/XPlane.h@ 110:9ac6386fe9ff

Last change on this file since 110:9ac6386fe9ff was 110:9ac6386fe9ff, checked in by István Váradi <ivaradi@…>, 17 months ago

The C++ client API can connect over TCP

File size: 12.5 KB
RevLine 
[13]1// Copyright (c) 2013 by István Váradi
2
3// This file is part of XPLRA, a remote-access plugin for X-Plane
4
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7
8// 1. Redistributions of source code must retain the above copyright notice, this
9// list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25// The views and conclusions contained in the software and documentation are those
26// of the authors and should not be interpreted as representing official policies,
27// either expressed or implied, of the FreeBSD Project.
28
29#ifndef HU_VARADIISTVAN_XPLRA_XPLANE_H
30#define HU_VARADIISTVAN_XPLRA_XPLANE_H
[14]31//-----------------------------------------------------------------------------
32
33#include "Exception.h"
34
35#include <hu/varadiistvan/scpl/io/Waiter.h>
36
[26]37#include <set>
[110]38#include <memory>
[26]39
[14]40#include <inttypes.h>
41
42//-----------------------------------------------------------------------------
43
44namespace hu { namespace varadiistvan { namespace scpl { namespace io {
45
[110]46class BufferedStream;
[14]47class DataStream;
48
49} /* namespace hu::varadiistvan::scpl::io */ } /* namespace hu::varadiistvan::scpl */ } /* namespace hu::varadiistvan */ } /* namespace hu */
50
[13]51//------------------------------------------------------------------------------
52
53namespace hu { namespace varadiistvan { namespace xplra {
54
55//------------------------------------------------------------------------------
56
[26]57class MultiBuffer;
58class MultiGetter;
59class MultiSetter;
60
61//------------------------------------------------------------------------------
62
[14]63/**
64 * The main class to access X-Plane.
65 *
66 * The calls are synchronous and not thread-safe.
67 */
[13]68class XPlane
69{
[14]70private:
71 /**
[110]72 * The default TCP port.
73 */
74 static const unsigned short defaultTCPPort = 0x5852;
75
76 /**
[26]77 * Type for the set of multi-dataref buffers.
78 */
79 typedef std::set<MultiBuffer*> multiBuffers_t;
80
81 /**
[14]82 * The waiter to use.
83 */
84 scpl::io::Waiter waiter;
85
86 /**
[110]87 * The client socket as a stream, over which we are communicating with X-Plane.
[14]88 */
[110]89 scpl::io::BufferedStream* socket;
[14]90
91 /**
92 * The data stream to handle the data conversions.
93 */
94 scpl::io::DataStream* stream;
95
[26]96 /**
97 * The buffers created by this object.
98 */
99 multiBuffers_t multiBuffers;
100
[14]101public:
102 /**
103 * Construct the object. It will not be connected to the simulator
104 * yet.
105 */
[107]106 XPlane() noexcept;
[14]107
108 /**
109 * Destroy the object. If connected, the connection will be
[26]110 * closed. It destroys all existing buffers, so their references
111 * become invalid.
[14]112 */
[107]113 ~XPlane() noexcept;
[14]114
115 /**
[110]116 * Connect to the simulator locally.
[14]117 */
[107]118 void connect();
[14]119
120 /**
[110]121 * Connect to the simulator on TCP to the given address.
122 */
123 void connectTCP(const std::string& address,
124 unsigned short port = defaultTCPPort);
125
126 /**
[14]127 * Check if we are connected to the simulator.
128 */
[107]129 bool isConnected() const noexcept;
[14]130
131 /**
132 * Disconnect from the simulator.
133 */
[107]134 void disconnect() noexcept;
[14]135
136 /**
[26]137 * Create a new getter of multiple datarefs and return a reference
138 * to it.
139 */
[107]140 MultiGetter& createMultiGetter() noexcept;
[26]141
142 /**
143 * Create a new setter of multiple datarefs and return a reference
144 * to it.
145 */
[107]146 MultiSetter& createMultiSetter() noexcept;
[26]147
148 /**
149 * Destroy the given getter or setter of multiple datarefs. As the
150 * buffer is unregistered, if it has been registered previously,
151 * and unregistration may fail, this function might throw an
152 * exception.
153 *
154 * @return if the buffer was found and could be destroyed
155 */
[107]156 bool destroyMultiBuffer(MultiBuffer& buffer);
[26]157
158 /**
[36]159 * Get the versions of X-Plane, XPLM and the XPLRA plugin.
160 */
[107]161 void getVersions(int& xplaneVersion, int& xplmVersion, int& xplraVersion);
[36]162
163 /**
[40]164 * Reload the plugins loaded in X-Plane. After this the connection
165 * fails.
166 */
[107]167 void reloadPlugins();
[40]168
169 /**
[87]170 * Save the current situation into the file with the given path,
171 * which is relative to the directory of X-Plane.
172 */
[107]173 void saveSituation(const char* path);
[87]174
175 /**
[14]176 * Get the integer value of the dataref with the given name.
177 */
[107]178 int getInt(const char* name);
[14]179
[15]180 /**
181 * Get a float value.
182 */
[107]183 float getFloat(const char* name);
[15]184
185 /**
186 * Get a double value.
187 */
[107]188 double getDouble(const char* name);
[15]189
[16]190 /**
191 * Get a possibly partial array of floats.
192 *
[66]193 * @param name the name of the dataref
194 * @param dest the destination buffer
[16]195 * @param length the length of the destination buffer
196 * @param offset the offset from which to get the array
197 *
198 * @return the number of values acquired actually
199 */
200 size_t getFloatArray(const char* name, float* dest,
[107]201 size_t length, size_t offset = 0);
[16]202
203 /**
204 * Get a possibly partial array of floats. The result array will
205 * be created with a length needed to hold the returned value.
206 *
[66]207 * @param name the name of the dataref
208 * @param length will contain the number of floats read
[16]209 * @param offset the offset from which to get the array
210 */
211 float* getFloatArray(const char* name, size_t& length,
[107]212 size_t offset = 0);
[16]213
214 /**
215 * Get a possibly partial array of integers.
216 *
[66]217 * @param name the name of the dataref
218 * @param dest the destination buffer
[16]219 * @param length the length of the destination buffer
220 * @param offset the offset from which to get the array
221 *
222 * @return the number of values acquired actually
223 */
224 size_t getIntArray(const char* name, int32_t* dest,
[107]225 size_t length, size_t offset = 0);
[16]226
227 /**
228 * Get a possibly partial array of integers. The result array will
229 * be created with a length needed to hold the returned value.
230 *
[66]231 * @param name the name of the dataref
232 * @param length will contain the number of integers read
[16]233 * @param offset the offset from which to get the array
234 */
235 int32_t* getIntArray(const char* name, size_t& length,
[107]236 size_t offset = 0);
[16]237
238 /**
239 * Get a possibly partial array of bytes.
240 *
[66]241 * @param name the name of the dataref
242 * @param dest the destination buffer
[16]243 * @param length the length of the destination buffer
244 * @param offset the offset from which to get the array
245 *
246 * @return the number of values acquired actually
247 */
248 size_t getByteArray(const char* name, uint8_t* dest,
[107]249 size_t length, size_t offset = 0);
[16]250
251 /**
252 * Get a possibly partial array of bytes. The result array will
253 * be created with a length needed to hold the returned value.
254 *
[66]255 * @param name the name of the dataref
256 * @param length will contain the number of bytes read on return
[16]257 * @param offset the offset from which to get the array
258 */
[66]259 uint8_t* getByteArray(const char* name, size_t& length,
[107]260 size_t offset = 0);
[16]261
262 /**
263 * Get a string. A string is a byte array.
264 */
[107]265 std::string getString(const char* name, size_t offset = 0);
[16]266
[17]267 /**
268 * Set the given dataref to the given integer value.
269 */
[107]270 void setInt(const char* name, int value);
[17]271
272 /**
273 * Set the given dataref to the given float value.
274 */
[107]275 void setFloat(const char* name, float value);
[17]276
277 /**
278 * Set the given dataref to the given double value.
279 */
[107]280 void setDouble(const char* name, double value);
[17]281
[18]282 /**
283 * Set the given float array to values in the given buffer.
284 */
285 void setFloatArray(const char* name, const float* values, size_t length,
[107]286 size_t offset = 0);
[18]287
288 /**
289 * Set the given integer array to values in the given buffer.
290 */
291 void setIntArray(const char* name, const int32_t* values, size_t length,
[107]292 size_t offset = 0);
[18]293
294 /**
295 * Set the given byte array to values in the given buffer.
296 */
297 void setByteArray(const char* name, const uint8_t* values, size_t length,
[107]298 size_t offset = 0);
[18]299
300 /**
301 * Set the given string to the given value. Since strings are byte
302 * arrays, and the bytes after the string should be zeroed, the
303 * length must be given. The string will be converted to a byte
304 * array of the given length, padded with 0s.
305 */
306 void setString(const char* name, const char* value, size_t length,
[107]307 size_t offset = 0);
[18]308
[40]309 /**
310 * Show a textual message for a certain duration.
311 */
[107]312 void showMessage(const char* message, float duration);
[40]313
[54]314 /**
315 * Register the given hotkey codes for listening. If there is an
316 * existing set of hotkeys registered, those will be overwritten.
317 */
[107]318 void registerHotkeys(const uint16_t* codes, size_t length);
[54]319
320 /**
321 * Query the registered hotkeys whether they were pressed.
322 */
[107]323 void queryHotkeys(uint8_t* states, size_t length);
[54]324
325 /**
326 * Unregister the hotkeys.
327 */
328 void unregisterHotkeys();
329
[14]330private:
331 /**
332 * Check if we have a stream and if it has not failed.
333 */
[107]334 void checkStream();
[14]335
336 /**
337 * Check the given protocol result. If it signifies an error,
338 * throw a ProtocolException with the correct error code.
339 */
[40]340 void checkResult(uint8_t result, bool hasParameter = false,
[107]341 long parameter = 0);
[15]342
343 /**
[17]344 * Read and check the result. If it signifies an error,
[30]345 * throw a ProtocolException with the correct error code. If there
346 * is some problem with the stream, an IOException is thrown.
[17]347 */
[107]348 void checkResult(bool multi = false);
[17]349
350 /**
[15]351 * Issue the command to get a single, scalar value. The result is
352 * also checked, but the value should be read by the caller.
353 */
[107]354 void getScalar(const char* name, uint8_t type);
[16]355
356 /**
357 * Issue the command to get an array of values of the given
358 * type. It checks the result and retrieves the number of value
359 * items available.
360 *
361 * @return the number of value items available
362 */
363 size_t getArray(const char* name, uint8_t type,
[107]364 ssize_t length, size_t offset);
[16]365
[17]366
367 /**
368 * Issue the command to set a scalar value of the given type.
369 */
[107]370 void setScalar(const char* name, uint8_t type);
[18]371
372 /**
373 * Issue the command to set an array value of the given type.
374 */
375 void setArray(const char* name, uint8_t type, size_t length,
[107]376 size_t offset);
[19]377
[110]378 /**
379 * Connect with the given socket.
380 */
381 template <class ClientSocket>
382 void connect(std::unique_ptr<ClientSocket> clientSocket);
383
[19]384 friend class MultiBuffer;
385 friend class MultiGetter;
386 friend class MultiSetter;
[13]387};
388
389//------------------------------------------------------------------------------
[14]390// Inline definitions
391//------------------------------------------------------------------------------
392
[107]393inline XPlane::XPlane() noexcept :
[14]394 socket(0),
395 stream(0)
396{
397}
398
399//------------------------------------------------------------------------------
400
[107]401inline bool XPlane::isConnected() const noexcept
[14]402{
403 return socket!=0;
404}
405
406//------------------------------------------------------------------------------
[13]407
408} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
409
410//------------------------------------------------------------------------------
411#endif // HU_VARADIISTVAN_XPLRA_XPLANE_H
412
413// Local Variables:
414// mode: C++
415// c-basic-offset: 4
416// indent-tabs-mode: nil
417// End:
Note: See TracBrowser for help on using the repository browser.