34 #include "MultiGetter.h"
35 #include "MultiSetter.h"
36 #include "Exception.h"
61 using std::unique_ptr;
72 template <
class Value>
79 static std::vector< Slot<Value> > slots;
92 static int addValue(Value value) noexcept;
97 static Value getValue(
int valueID) noexcept;
102 static void clearValue(
int valueID) noexcept;
121 Slot(Value value) noexcept;
127 int setValue(Value value) noexcept;
133 Value getValue() const noexcept;
138 void clear(
int nextFreeIndex) noexcept;
143 template <class Value> vector< Slot<Value> > Slot<Value>::slots;
147 template <class Value>
int Slot<Value>::firstFree = -1;
151 template <class Value>
152 inline Slot<Value>::Slot(Value value) noexcept :
160 template <
class Value>
161 inline int Slot<Value>::setValue(Value value) noexcept
164 int nextFreeIndex = this->nextFreeIndex;
167 return nextFreeIndex;
172 template <
class Value>
173 inline Value Slot<Value>::getValue() const noexcept
175 return valid ? value :
static_cast<Value
>(0);
180 template <
class Value>
181 inline void Slot<Value>::clear(
int nextFreeIndex) noexcept
185 this->nextFreeIndex = nextFreeIndex;
190 template <
class Value>
191 int Slot<Value>::addValue(Value value) noexcept
196 slots.push_back(Slot<Value>(value));
198 Slot& slot = slots[id];
199 firstFree = slot.setValue(value);
207 template <
class Value>
208 Value Slot<Value>::getValue(
int valueID) noexcept
210 size_t index =
static_cast<size_t>(valueID);
211 return (index<slots.size()) ?
212 slots[index].getValue() :
static_cast<Value
>(0);
217 template <
class Value>
218 void Slot<Value>::clearValue(
int valueID) noexcept
220 size_t index =
static_cast<size_t>(valueID);
221 if (index<slots.size()) {
222 slots[index].clear(firstFree);
230 typedef Slot<MultiBuffer*> MultiBufferSlot;
238 class Connection :
public XPlane
244 typedef std::set<int> multiBufferIDs_t;
250 static Connection& get(
const MultiBuffer& buffer) noexcept;
261 unsigned long lastErrorSubCode;
266 std::string lastErrorString;
271 multiBufferIDs_t multiBufferIDs;
277 Connection() noexcept;
282 ~Connection() noexcept;
287 void handleException() noexcept;
292 int getLastError(
unsigned long* lastErrorSubCode) const noexcept;
297 const
char* getLastErrorString() const noexcept;
302 void clearLastError() noexcept;
309 int createMultiGetter() noexcept;
316 int createMultiSetter() noexcept;
326 bool destroyMultiBuffer(
int bufferID);
331 inline Connection& Connection::get(const
MultiBuffer& buffer) noexcept
333 return static_cast<Connection&
>(buffer.getXPlane());
338 inline Connection::Connection() noexcept :
346 Connection::~Connection() noexcept
348 for(multiBufferIDs_t::iterator i = multiBufferIDs.begin();
349 i!=multiBufferIDs.end(); ++i)
351 MultiBufferSlot::clearValue(*i);
357 void Connection::handleException() noexcept
364 lastErrorString = e.
what();
367 lastErrorSubCode =
static_cast<unsigned long>(e.
getErrorCode());
368 lastErrorString = e.
what();
371 lastErrorSubCode = 0;
372 lastErrorString = e.
what();
375 lastErrorSubCode = 0;
376 lastErrorString = e.
what();
379 lastErrorSubCode = 0;
380 lastErrorString = e.
what();
381 }
catch(
const exception& e) {
383 lastErrorSubCode = 0;
384 lastErrorString = e.what();
387 lastErrorSubCode = 0;
388 lastErrorString =
"<Exception of an unknown type>";
394 inline int Connection::getLastError(
unsigned long* lastErrorSubCode)
397 if (lastErrorSubCode!=0) *lastErrorSubCode = this->lastErrorSubCode;
398 return lastErrorCode;
403 inline const char* Connection::getLastErrorString() const noexcept
405 return (lastErrorCode==
ERROR_NONE) ? 0 : lastErrorString.c_str();
410 inline void Connection::clearLastError() noexcept
413 lastErrorSubCode = 0;
414 lastErrorString.clear();
419 inline int Connection::createMultiGetter() noexcept
422 return MultiBufferSlot::addValue(&getter);
427 inline int Connection::createMultiSetter() noexcept
430 return MultiBufferSlot::addValue(&setter);
435 bool Connection::destroyMultiBuffer(
int bufferID)
437 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
438 if (buffer==0)
return false;
440 if (XPlane::destroyMultiBuffer(*buffer)) {
441 multiBufferIDs.erase(bufferID);
442 MultiBufferSlot::clearValue(bufferID);
455 typedef Slot<Connection*> ConnectionSlot;
465 Connection* connection = ConnectionSlot::getValue(connectionID);
466 return (connection==0) ? -1 : connection->getLastError(subCode);
473 Connection* connection = ConnectionSlot::getValue(connectionID);
474 return (connection==0) ? 0 : connection->getLastErrorString();
481 Connection* connection = ConnectionSlot::getValue(connectionID);
482 if (connection!=0) connection->clearLastError();
490 unique_ptr<Connection> connection(
new Connection());
491 connection->connect();
492 return ConnectionSlot::addValue(connection.release());
503 unique_ptr<Connection> connection(
new Connection());
504 connection->connectTCP(address);
505 return ConnectionSlot::addValue(connection.release());
516 unique_ptr<Connection> connection(
new Connection());
517 connection->connectTCP(address, port);
518 return ConnectionSlot::addValue(connection.release());
527 int* xplaneVersion,
int* xplmVersion,
530 Connection* connection = ConnectionSlot::getValue(connectionID);
531 if (connection==0)
return -1;
533 connection->getVersions(*xplaneVersion, *xplmVersion, *xplraVersion);
536 connection->handleException();
545 Connection* connection = ConnectionSlot::getValue(connectionID);
546 if (connection==0)
return -1;
548 connection->reloadPlugins();
551 connection->handleException();
560 Connection* connection = ConnectionSlot::getValue(connectionID);
561 if (connection==0)
return -1;
563 connection->saveSituation(path);
566 connection->handleException();
573 extern "C" int xplra_get_int(
int* value,
int connectionID,
const char* name)
575 Connection* connection = ConnectionSlot::getValue(connectionID);
576 if (connection==0)
return -1;
578 *value = connection->getInt(name);
581 connection->handleException();
590 Connection* connection = ConnectionSlot::getValue(connectionID);
591 if (connection==0)
return -1;
593 *value = connection->getFloat(name);
596 connection->handleException();
604 int connectionID,
const char* name)
606 Connection* connection = ConnectionSlot::getValue(connectionID);
607 if (connection==0)
return -1;
609 *value = connection->getDouble(name);
612 connection->handleException();
620 int connectionID,
const char* name)
622 Connection* connection = ConnectionSlot::getValue(connectionID);
623 if (connection==0)
return -1;
625 return connection->getFloatArray(name, dest, length, offset);
627 connection->handleException();
635 int connectionID,
const char* name)
637 Connection* connection = ConnectionSlot::getValue(connectionID);
638 if (connection==0)
return 0;
640 return connection->getFloatArray(name, *length, offset);
642 connection->handleException();
650 int connectionID,
const char* name)
652 Connection* connection = ConnectionSlot::getValue(connectionID);
653 if (connection==0)
return -1;
655 return connection->getIntArray(name, dest, length, offset);
657 connection->handleException();
665 int connectionID,
const char* name)
667 Connection* connection = ConnectionSlot::getValue(connectionID);
668 if (connection==0)
return 0;
670 return connection->getIntArray(name, *length, offset);
672 connection->handleException();
680 int connectionID,
const char* name)
682 Connection* connection = ConnectionSlot::getValue(connectionID);
683 if (connection==0)
return -1;
685 return connection->getByteArray(name,
reinterpret_cast<uint8_t*
>(dest),
688 connection->handleException();
696 int connectionID,
const char* name)
698 Connection* connection = ConnectionSlot::getValue(connectionID);
699 if (connection==0)
return 0;
701 return connection->getByteArray(name, *length, offset);
703 connection->handleException();
712 Connection* connection = ConnectionSlot::getValue(connectionID);
713 if (connection==0)
return 0;
715 connection->setInt(name, value);
718 connection->handleException();
727 Connection* connection = ConnectionSlot::getValue(connectionID);
728 if (connection==0)
return 0;
730 connection->setFloat(name, value);
733 connection->handleException();
743 Connection* connection = ConnectionSlot::getValue(connectionID);
744 if (connection==0)
return 0;
746 connection->setDouble(name, value);
749 connection->handleException();
758 size_t length,
size_t offset)
760 Connection* connection = ConnectionSlot::getValue(connectionID);
761 if (connection==0)
return 0;
763 connection->setFloatArray(name, values, length, offset);
766 connection->handleException();
774 const int32_t* values,
775 size_t length,
size_t offset)
777 Connection* connection = ConnectionSlot::getValue(connectionID);
778 if (connection==0)
return 0;
780 connection->setIntArray(name, values, length, offset);
783 connection->handleException();
792 size_t length,
size_t offset)
794 Connection* connection = ConnectionSlot::getValue(connectionID);
795 if (connection==0)
return 0;
797 connection->setByteArray(name,
reinterpret_cast<const uint8_t*
>(values),
801 connection->handleException();
810 size_t length,
size_t offset)
812 Connection* connection = ConnectionSlot::getValue(connectionID);
813 if (connection==0)
return 0;
815 connection->setString(name, value, length, offset);
818 connection->handleException();
828 Connection* connection = ConnectionSlot::getValue(connectionID);
829 return (connection==0) ? -1 : connection->createMultiGetter();
836 Connection* connection = ConnectionSlot::getValue(connectionID);
837 return (connection==0) ? -1 : connection->createMultiSetter();
844 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
852 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
860 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
867 size_t length,
size_t offset)
869 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
877 size_t length,
size_t offset)
879 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
887 size_t length,
size_t offset)
889 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
898 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
899 return (buffer==0) ? -1 : (buffer->
finalize() ? 1 : 0);
906 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
907 if (buffer==0)
return -1;
912 Connection::get(*buffer).handleException();
921 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
922 if (buffer==0)
return -1;
927 Connection::get(*buffer).handleException();
936 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
944 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
945 if (buffer==0)
return -1;
950 Connection::get(*buffer).handleException();
959 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
960 if (buffer==0)
return -1;
962 buffer->
setInt(datarefID, value);
965 Connection::get(*buffer).handleException();
974 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
975 if (buffer==0)
return -1;
977 *dest = buffer->
getInt(datarefID);
980 Connection::get(*buffer).handleException();
990 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
991 if (buffer==0)
return 0;
995 Connection::get(*buffer).handleException();
1005 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1006 if (buffer==0)
return 0;
1010 Connection::get(*buffer).handleException();
1020 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1021 if (buffer==0)
return -1;
1023 buffer->
setFloat(datarefID, value);
1026 Connection::get(*buffer).handleException();
1036 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1037 if (buffer==0)
return -1;
1039 *dest = buffer->
getFloat(datarefID);
1042 Connection::get(*buffer).handleException();
1052 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1053 if (buffer==0)
return 0;
1057 Connection::get(*buffer).handleException();
1067 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1068 if (buffer==0)
return 0;
1072 Connection::get(*buffer).handleException();
1082 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1083 if (buffer==0)
return -1;
1088 Connection::get(*buffer).handleException();
1098 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1099 if (buffer==0)
return -1;
1104 Connection::get(*buffer).handleException();
1114 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1115 if (buffer==0)
return 0;
1119 Connection::get(*buffer).handleException();
1129 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1130 if (buffer==0)
return 0;
1134 Connection::get(*buffer).handleException();
1143 const float* value,
size_t length,
1146 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1147 if (buffer==0)
return -1;
1149 return buffer->
setFloatArray(datarefID, value, length, offset);
1151 Connection::get(*buffer).handleException();
1160 size_t length,
size_t offset,
1161 int bufferID,
size_t datarefID)
1163 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1164 if (buffer==0)
return -1;
1166 return buffer->
getFloatArray(datarefID, value, length, offset);
1168 Connection::get(*buffer).handleException();
1179 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1180 if (buffer==0)
return 0;
1184 Connection::get(*buffer).handleException();
1193 const int32_t* value,
size_t length,
1196 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1197 if (buffer==0)
return -1;
1199 return buffer->
setIntArray(datarefID, value, length, offset);
1201 Connection::get(*buffer).handleException();
1210 size_t length,
size_t offset,
1211 int bufferID,
size_t datarefID)
1213 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1214 if (buffer==0)
return -1;
1216 return buffer->
getIntArray(datarefID, value, length, offset);
1218 Connection::get(*buffer).handleException();
1229 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1230 if (buffer==0)
return 0;
1234 Connection::get(*buffer).handleException();
1243 const void* value,
size_t length,
1246 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1247 if (buffer==0)
return -1;
1250 reinterpret_cast<const uint8_t*
>(value),
1253 Connection::get(*buffer).handleException();
1262 size_t length,
size_t offset,
1263 int bufferID,
size_t datarefID)
1265 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1266 if (buffer==0)
return -1;
1269 reinterpret_cast<uint8_t*
>(value),
1272 Connection::get(*buffer).handleException();
1283 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1284 if (buffer==0)
return 0;
1288 Connection::get(*buffer).handleException();
1296 const char* value,
size_t offset)
1298 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1299 if (buffer==0)
return -1;
1301 return buffer->
setString(datarefID, value, offset);
1303 Connection::get(*buffer).handleException();
1314 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1315 if (buffer==0)
return 0;
1319 Connection::get(*buffer).handleException();
1328 Connection* connection = ConnectionSlot::getValue(connectionID);
1329 if (connection==0)
return -1;
1332 return connection->destroyMultiBuffer(bufferID) ? 0 : -1;
1334 connection->handleException();
1343 const char* message,
float duration)
1345 Connection* connection = ConnectionSlot::getValue(connectionID);
1346 if (connection==0)
return -1;
1349 connection->showMessage(message, duration);
1352 connection->handleException();
1361 const uint16_t* codes,
size_t length)
1363 Connection* connection = ConnectionSlot::getValue(connectionID);
1364 if (connection==0)
return -1;
1367 connection->registerHotkeys(codes, length);
1370 connection->handleException();
1378 uint8_t* states,
size_t length)
1380 Connection* connection = ConnectionSlot::getValue(connectionID);
1381 if (connection==0)
return -1;
1384 connection->queryHotkeys(states, length);
1387 connection->handleException();
1396 Connection* connection = ConnectionSlot::getValue(connectionID);
1397 if (connection==0)
return -1;
1400 connection->unregisterHotkeys();
1403 connection->handleException();
1413 Connection* connection = ConnectionSlot::getValue(connectionID);
1414 if (connection==0)
return -1;
1416 connection->disconnect();
1426 Connection* connection = ConnectionSlot::getValue(connectionID);
1427 if (connection==0)
return -1;
1430 connection->connect();
1442 Connection* connection = ConnectionSlot::getValue(connectionID);
1443 if (connection==0)
return -1;
1445 ConnectionSlot::clearValue(connectionID);
virtual const char * what() const
errorCode_t getErrorCode() const
bool unregisterSafelyFromXPlane() noexcept
double getDouble(size_t id) const
size_t setIntArray(size_t id, const int32_t *value, size_t length=0, size_t offset=0)
size_t getByteArray(size_t id, uint8_t *value, size_t length=0, size_t offset=0) const
const int32_t & getIntRef(size_t id) const
size_t addIntArray(const std::string &name, size_t length, size_t offset=0) noexcept
size_t addByteArray(const std::string &name, size_t length, size_t offset=0) noexcept
size_t setByteArray(size_t id, const uint8_t *value, size_t length=0, size_t offset=0)
void unregisterFromXPlane()
void setInt(size_t id, int value)
size_t addDouble(const std::string &name) noexcept
const char * getStringPtr(size_t id, size_t offset=0) const
const double & getDoubleRef(size_t id) const
size_t getIntArray(size_t id, int32_t *value, size_t length=0, size_t offset=0) const
void setDouble(size_t id, double value)
size_t getFloatArray(size_t id, float *value, size_t length=0, size_t offset=0) const
const float & getFloatRef(size_t id) const
size_t addFloat(const std::string &name) noexcept
size_t setString(size_t id, const std::string &value, size_t offset=0)
int getInt(size_t id) const
size_t setFloatArray(size_t id, const float *value, size_t length=0, size_t offset=0)
size_t addInt(const std::string &name) noexcept
size_t addFloatArray(const std::string &name, size_t length, size_t offset=0) noexcept
float getFloat(size_t id) const
void setFloat(size_t id, float value)
errorCode_t getErrorCode() const
int xplra_connect_tcp_port(const char *address, unsigned short port)
int xplra_multi_finalize(int bufferID)
size_t xplra_multi_add_int_array(int bufferID, const char *name, size_t length, size_t offset)
int xplra_set_byte_array(int connectionID, const char *name, const void *values, size_t length, size_t offset)
int xplra_query_hotkeys(int connectionID, uint8_t *states, size_t length)
const int32_t * xplra_multi_get_int_array_ptr(int bufferID, size_t datarefID, size_t offset)
int32_t * xplra_get_int_array_new(size_t *length, size_t offset, int connectionID, const char *name)
size_t xplra_multi_add_float_array(int bufferID, const char *name, size_t length, size_t offset)
int xplra_set_double(int connectionID, const char *name, double value)
const float * xplra_multi_get_float_const_ptr(int bufferID, size_t datarefID)
int xplra_get_double(double *value, int connectionID, const char *name)
int xplra_disconnect(int connectionID)
int xplra_multi_unregister_safely(int bufferID)
int xplra_reconnect(int connectionID)
int xplra_register_hotkeys(int connectionID, const uint16_t *codes, size_t length)
int xplra_set_float(int connectionID, const char *name, float value)
int xplra_show_message(int connectionID, const char *message, float duration)
int xplra_set_string(int connectionID, const char *name, const char *value, size_t length, size_t offset)
ssize_t xplra_multi_set_float_array(int bufferID, size_t datarefID, const float *value, size_t length, size_t offset)
ssize_t xplra_multi_get_byte_array(void *value, size_t length, size_t offset, int bufferID, size_t datarefID)
uint8_t * xplra_get_byte_array_new(size_t *length, size_t offset, int connectionID, const char *name)
const char * xplra_multi_get_string_ptr(int bufferID, size_t datarefID, size_t offset)
void xplra_clear_last_error(int connectionID)
int xplra_get_int(int *value, int connectionID, const char *name)
ssize_t xplra_multi_set_string(int bufferID, size_t datarefID, const char *value, size_t offset)
int xplra_multi_execute(int bufferID)
int xplra_get_last_error(int connectionID, unsigned long *subCode)
size_t xplra_multi_add_int(int bufferID, const char *name)
int xplra_connect_tcp(const char *address)
ssize_t xplra_get_float_array(float *dest, size_t length, size_t offset, int connectionID, const char *name)
ssize_t xplra_get_byte_array(void *dest, size_t length, size_t offset, int connectionID, const char *name)
ssize_t xplra_multi_set_byte_array(int bufferID, size_t datarefID, const void *value, size_t length, size_t offset)
int xplra_multi_set_int(int bufferID, size_t datarefID, int value)
int xplra_multi_create_setter(int connectionID)
int32_t * xplra_multi_get_int_ptr(int bufferID, size_t datarefID)
int xplra_set_int_array(int connectionID, const char *name, const int32_t *values, size_t length, size_t offset)
int xplra_multi_set_double(int bufferID, size_t datarefID, double value)
int xplra_reload_plugins(int connectionID)
int xplra_multi_get_float(float *dest, int bufferID, size_t datarefID)
const uint8_t * xplra_multi_get_byte_array_ptr(int bufferID, size_t datarefID, size_t offset)
ssize_t xplra_multi_set_int_array(int bufferID, size_t datarefID, const int32_t *value, size_t length, size_t offset)
const char * xplra_get_last_error_string(int connectionID)
int xplra_destroy(int connectionID)
float * xplra_get_float_array_new(size_t *length, size_t offset, int connectionID, const char *name)
double * xplra_multi_get_double_ptr(int bufferID, size_t datarefID)
size_t xplra_multi_add_double(int bufferID, const char *name)
#define ERROR_TYPE_MISMATCH
int xplra_get_float(float *value, int connectionID, const char *name)
const int32_t * xplra_multi_get_int_const_ptr(int bufferID, size_t datarefID)
ssize_t xplra_get_int_array(int32_t *dest, size_t length, size_t offset, int connectionID, const char *name)
ssize_t xplra_multi_get_float_array(float *value, size_t length, size_t offset, int bufferID, size_t datarefID)
int xplra_multi_get_int(int *dest, int bufferID, size_t datarefID)
int xplra_set_int(int connectionID, const char *name, int value)
int xplra_multi_create_getter(int connectionID)
int xplra_multi_set_float(int bufferID, size_t datarefID, float value)
size_t xplra_multi_add_float(int bufferID, const char *name)
int xplra_get_versions(int connectionID, int *xplaneVersion, int *xplmVersion, int *xplraVersion)
const double * xplra_multi_get_double_const_ptr(int bufferID, size_t datarefID)
float * xplra_multi_get_float_ptr(int bufferID, size_t datarefID)
int xplra_unregister_hotkeys(int connectionID)
#define INVALID_DATAREF_ID
#define ERROR_NOT_CONNECTED
int xplra_multi_get_double(double *dest, int bufferID, size_t datarefID)
int xplra_multi_unregister(int bufferID)
int xplra_multi_destroy_buffer(int connectionID, int bufferID)
int xplra_multi_register(int bufferID)
int xplra_save_situation(int connectionID, const char *path)
const float * xplra_multi_get_float_array_ptr(int bufferID, size_t datarefID, size_t offset)
int xplra_set_float_array(int connectionID, const char *name, const float *values, size_t length, size_t offset)
ssize_t xplra_multi_get_int_array(int32_t *value, size_t length, size_t offset, int bufferID, size_t datarefID)
size_t xplra_multi_add_byte_array(int bufferID, const char *name, size_t length, size_t offset)