33 #include "MultiGetter.h"
34 #include "MultiSetter.h"
36 #include <hu/varadiistvan/scpl/io/LocalClientSocket.h>
37 #include <hu/varadiistvan/scpl/io/TCPClientSocket.h>
38 #include <hu/varadiistvan/scpl/io/DataStream.h>
40 #include <xplra/Protocol.h>
54 using hu::varadiistvan::scpl::io::LocalClientSocket;
55 using hu::varadiistvan::scpl::io::TCPClientSocket;
56 using hu::varadiistvan::scpl::io::DataStream;
60 using std::unique_ptr;
66 const unsigned short XPlane::defaultTCPPort;
70 template <
class ClientSocket>
71 void XPlane::connect(std::unique_ptr<ClientSocket> clientSocket)
73 auto& connector = clientSocket->getConnector();
75 while (!connector.connect()) {
76 if (connector.failed()) {
86 signal(SIGPIPE, SIG_IGN);
89 socket = clientSocket.release();
106 }
else if (
stream->failed()) {
116 case Protocol::RESULT_OK:
118 case Protocol::RESULT_INVALID_COMMAND:
120 hasParameter, parameter);
121 case Protocol::RESULT_UNKNOWN_DATAREF:
123 hasParameter, parameter);
124 case Protocol::RESULT_INVALID_TYPE:
126 hasParameter, parameter);
127 case Protocol::RESULT_INVALID_LENGTH:
129 hasParameter, parameter);
130 case Protocol::RESULT_INVALID_OFFSET:
132 hasParameter, parameter);
133 case Protocol::RESULT_INVALID_COUNT:
135 hasParameter, parameter);
136 case Protocol::RESULT_INVALID_ID:
138 hasParameter, parameter);
139 case Protocol::RESULT_INVALID_DURATION:
141 hasParameter, parameter);
142 case Protocol::RESULT_OTHER_ERROR:
145 hasParameter, parameter);
153 uint8_t result =
stream->readU8();
154 bool hasParameter =
false;
157 if (result==Protocol::RESULT_UNKNOWN_DATAREF) {
158 parameter =
stream->readU32();
187 unique_ptr<LocalClientSocket> clientSocket(
new LocalClientSocket(
"xplra",
189 connect(std::move(clientSocket));
198 unique_ptr<TCPClientSocket> clientSocket(
new TCPClientSocket(address.c_str(),
201 connect(std::move(clientSocket));
236 multiBuffers_t::iterator i =
multiBuffers.find(&buffer);
249 stream->writeU8(Protocol::COMMAND_GET_VERSIONS);
253 xplaneVersion =
stream->readS32();
254 xplmVersion =
stream->readS32();
255 xplraVersion =
stream->readS32();
264 stream->writeU8(Protocol::COMMAND_RELOAD_PLUGINS);
273 stream->writeU8(Protocol::COMMAND_SAVE_SITUATION);
274 stream->writeString(path);
285 stream->writeU8(Protocol::COMMAND_GET_SINGLE);
286 stream->writeString(name, strlen(name));
299 int value =
stream->readS32();
310 float value =
stream->readFloat();
321 double value =
stream->readDouble();
329 ssize_t length,
size_t offset)
333 stream->writeU8(Protocol::COMMAND_GET_SINGLE);
334 stream->writeString(name, strlen(name));
336 stream->writeS32(
static_cast<int32_t
>(length));
337 stream->writeS32(
static_cast<int32_t
>(offset));
340 uint8_t result =
stream->readU8();
341 length =
stream->readS32();
351 size_t length,
size_t offset)
353 length =
getArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
365 length =
getArray(name, Protocol::TYPE_FLOAT_ARRAY, -1, offset);
367 unique_ptr<float[]> data(
new float[length]);
369 return data.release();
375 size_t length,
size_t offset)
377 length =
getArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
389 length =
getArray(name, Protocol::TYPE_INT_ARRAY, -1, offset);
391 unique_ptr<int32_t[]> data(
new int32_t[length]);
393 return data.release();
399 size_t length,
size_t offset)
401 length =
getArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
413 length =
getArray(name, Protocol::TYPE_BYTE_ARRAY, -1, offset);
415 unique_ptr<uint8_t[]> data(
new uint8_t[length]);
417 return data.release();
425 unique_ptr<uint8_t[]> data(
getByteArray(name, length, offset));
426 return string(
reinterpret_cast<char*
>(data.get()));
433 stream->writeU8(Protocol::COMMAND_SET_SINGLE);
434 stream->writeString(name, strlen(name));
453 stream->writeFloat(value);
463 stream->writeDouble(value);
473 stream->writeU8(Protocol::COMMAND_SET_SINGLE);
474 stream->writeString(name, strlen(name));
476 stream->writeS32(
static_cast<int32_t
>(length));
477 stream->writeS32(
static_cast<int32_t
>(offset));
485 setArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
486 stream->write(values, length*
sizeof(*values));
496 setArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
497 stream->write(values, length*
sizeof(*values));
507 setArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
508 stream->write(values, length*
sizeof(*values));
518 size_t valueLength = strlen(value);
519 if ((valueLength+1)>=length) {
520 setByteArray(name,
reinterpret_cast<const uint8_t*
>(value),
523 unique_ptr<uint8_t[]> buffer(
new uint8_t[length]);
524 memcpy(buffer.get(), value, valueLength);
525 memset(buffer.get() + valueLength, 0, length - valueLength);
534 stream->writeU8(Protocol::COMMAND_SHOW_MESSAGE);
535 stream->writeString(message);
536 stream->writeFloat(duration);
546 stream->writeU8(Protocol::COMMAND_REGISTER_HOTKEYS);
548 stream->write(codes,
sizeof(uint16_t)*length);
557 stream->writeU8(Protocol::COMMAND_QUERY_HOTKEYS);
561 size_t count =
stream->readU32();
563 stream->read(states, min(length, count));
565 while(length<count) {
569 }
else if (length>count) {
570 memset(states + count, 0, length - count);
579 stream->writeU8(Protocol::COMMAND_UNREGISTER_HOTKEYS);
void reregisterInXPlane()
void forgetRegistration() noexcept
@ INVALID_COMMAND
Invalid command issued.
@ INVALID_LENGTH
Invalid length.
@ INVALID_COUNT
Invalid count.
@ UNKNOWN_DATAREF
Unknown dataref.
@ INVALID_DURATION
Invalid duration.
@ INVALID_TYPE
Invalid type.
@ INVALID_OFFSET
Invalid offset.
void setArray(const char *name, uint8_t type, size_t length, size_t offset)
void registerHotkeys(const uint16_t *codes, size_t length)
int getInt(const char *name)
size_t getIntArray(const char *name, int32_t *dest, size_t length, size_t offset=0)
void getScalar(const char *name, uint8_t type)
size_t getByteArray(const char *name, uint8_t *dest, size_t length, size_t offset=0)
bool destroyMultiBuffer(MultiBuffer &buffer)
void setInt(const char *name, int value)
size_t getArray(const char *name, uint8_t type, ssize_t length, size_t offset)
float getFloat(const char *name)
void disconnect() noexcept
multiBuffers_t multiBuffers
void queryHotkeys(uint8_t *states, size_t length)
scpl::io::BufferedStream * socket
MultiGetter & createMultiGetter() noexcept
size_t getFloatArray(const char *name, float *dest, size_t length, size_t offset=0)
void showMessage(const char *message, float duration)
void setDouble(const char *name, double value)
void setFloatArray(const char *name, const float *values, size_t length, size_t offset=0)
scpl::io::DataStream * stream
void saveSituation(const char *path)
void setScalar(const char *name, uint8_t type)
void setIntArray(const char *name, const int32_t *values, size_t length, size_t offset=0)
void connectTCP(const std::string &address, unsigned short port=defaultTCPPort)
void checkResult(uint8_t result, bool hasParameter=false, long parameter=0)
void setString(const char *name, const char *value, size_t length, size_t offset=0)
void setByteArray(const char *name, const uint8_t *values, size_t length, size_t offset=0)
double getDouble(const char *name)
void getVersions(int &xplaneVersion, int &xplmVersion, int &xplraVersion)
MultiSetter & createMultiSetter() noexcept
std::string getString(const char *name, size_t offset=0)
void setFloat(const char *name, float value)