source: xplra/src/client/c/hu/varadiistvan/xplra/xplra.cc@ 111:9c29a0b10ea6

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

The C client API can connect over TCP

File size: 42.3 KB
Line 
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//------------------------------------------------------------------------------
30
31#include "xplra.h"
32
33#include "XPlane.h"
34#include "MultiGetter.h"
35#include "MultiSetter.h"
36#include "Exception.h"
37
38#include <vector>
39#include <memory>
40
41#include <cstdio>
42#include <cassert>
43
44//------------------------------------------------------------------------------
45
46using hu::varadiistvan::xplra::XPlane;
47using hu::varadiistvan::xplra::MultiBuffer;
48using hu::varadiistvan::xplra::MultiGetter;
49using hu::varadiistvan::xplra::MultiSetter;
50using hu::varadiistvan::xplra::Exception;
51using hu::varadiistvan::xplra::IOException;
52using hu::varadiistvan::xplra::ProtocolException;
53using hu::varadiistvan::xplra::NotConnectedException;
54using hu::varadiistvan::xplra::TypeMismatchException;
55using hu::varadiistvan::xplra::InvalidIDException;
56
57using std::exception;
58using std::string;
59using std::vector;
60using std::set;
61using std::unique_ptr;
62
63//------------------------------------------------------------------------------
64
65namespace {
66
67//------------------------------------------------------------------------------
68
69/**
70 * Template for handling slots.
71 */
72template <class Value>
73struct Slot
74{
75private:
76 /**
77 * The slots.
78 */
79 static std::vector< Slot<Value> > slots;
80
81 /**
82 * The index of the first free slot.
83 */
84 static int firstFree;
85
86public:
87 /**
88 * Add a new value.
89 *
90 * @return the ID of the new value
91 */
92 static int addValue(Value value) noexcept;
93
94 /**
95 * Get the value with the given ID.
96 */
97 static Value getValue(int valueID) noexcept;
98
99 /**
100 * Clear the value with the given ID.
101 */
102 static void clearValue(int valueID) noexcept;
103
104private:
105 /**
106 * Indicate if the slot contains a valid value or not.
107 */
108 bool valid;
109
110 union {
111 // The value, if the slot contains a value
112 Value value;
113
114 // The index of the next free slot
115 int nextFreeIndex;
116 };
117
118 /**
119 * Construct a slot with the given value
120 */
121 Slot(Value value) noexcept;
122
123 /**
124 * Set the value and return the former next free index. It
125 * should be called for a slot with no value.
126 */
127 int setValue(Value value) noexcept;
128
129 /**
130 * Get the value if this slot contains a value. Otherwise 0 is
131 * returned (converted to value).
132 */
133 Value getValue() const noexcept;
134
135 /**
136 * Clear the value and set the given next free index.
137 */
138 void clear(int nextFreeIndex) noexcept;
139};
140
141//------------------------------------------------------------------------------
142
143template <class Value> vector< Slot<Value> > Slot<Value>::slots;
144
145//------------------------------------------------------------------------------
146
147template <class Value> int Slot<Value>::firstFree = -1;
148
149//------------------------------------------------------------------------------
150
151template <class Value>
152inline Slot<Value>::Slot(Value value) noexcept :
153 valid(true)
154{
155 this->value = value;
156}
157
158//------------------------------------------------------------------------------
159
160template <class Value>
161inline int Slot<Value>::setValue(Value value) noexcept
162{
163 assert(!valid);
164 int nextFreeIndex = this->nextFreeIndex;
165 this->value = value;
166 valid = true;
167 return nextFreeIndex;
168}
169
170//------------------------------------------------------------------------------
171
172template <class Value>
173inline Value Slot<Value>::getValue() const noexcept
174{
175 return valid ? value : static_cast<Value>(0);
176}
177
178//------------------------------------------------------------------------------
179
180template <class Value>
181inline void Slot<Value>::clear(int nextFreeIndex) noexcept
182{
183 assert(valid);
184 valid = false;
185 this->nextFreeIndex = nextFreeIndex;
186}
187
188//------------------------------------------------------------------------------
189
190template <class Value>
191int Slot<Value>::addValue(Value value) noexcept
192{
193 int id = firstFree;
194 if (id<0) {
195 id = slots.size();
196 slots.push_back(Slot<Value>(value));
197 } else {
198 Slot& slot = slots[id];
199 firstFree = slot.setValue(value);
200 }
201
202 return id;
203}
204
205//------------------------------------------------------------------------------
206
207template <class Value>
208Value Slot<Value>::getValue(int valueID) noexcept
209{
210 size_t index = static_cast<size_t>(valueID);
211 return (index<slots.size()) ?
212 slots[index].getValue() : static_cast<Value>(0);
213}
214
215//------------------------------------------------------------------------------
216
217template <class Value>
218void Slot<Value>::clearValue(int valueID) noexcept
219{
220 size_t index = static_cast<size_t>(valueID);
221 if (index<slots.size()) {
222 slots[index].clear(firstFree);
223 firstFree = index;
224 }
225}
226
227//------------------------------------------------------------------------------
228//------------------------------------------------------------------------------
229
230typedef Slot<MultiBuffer*> MultiBufferSlot;
231
232//------------------------------------------------------------------------------
233//------------------------------------------------------------------------------
234
235/**
236 * Information about a connection.
237 */
238class Connection : public XPlane
239{
240private:
241 /**
242 * Type for the set of multi-dataref buffers belonging to this connection.
243 */
244 typedef std::set<int> multiBufferIDs_t;
245
246public:
247 /**
248 * Get the connection for the given multi-dataref buffer.
249 */
250 static Connection& get(const MultiBuffer& buffer) noexcept;
251
252private:
253 /**
254 * The last error code.
255 */
256 int lastErrorCode;
257
258 /**
259 * The last error subcode.
260 */
261 unsigned long lastErrorSubCode;
262
263 /**
264 * The string of the last error
265 */
266 std::string lastErrorString;
267
268 /**
269 * The set of multi-dataref buffers belonging to this connection.
270 */
271 multiBufferIDs_t multiBufferIDs;
272
273public:
274 /**
275 * Construct the connection
276 */
277 Connection() noexcept;
278
279 /**
280 * Destroy the connection.
281 */
282 ~Connection() noexcept;
283
284 /**
285 * Handle the currently pending exception.
286 */
287 void handleException() noexcept;
288
289 /**
290 * Get the last error code.
291 */
292 int getLastError(unsigned long* lastErrorSubCode) const noexcept;
293
294 /**
295 * Get the string representation of the last error code.
296 */
297 const char* getLastErrorString() const noexcept;
298
299 /**
300 * Clear the last error code.
301 */
302 void clearLastError() noexcept;
303
304 /**
305 * Create a multi-dataref getter object and register it in a slot.
306 *
307 * @return the ID of the new getter.
308 */
309 int createMultiGetter() noexcept;
310
311 /**
312 * Create a multi-dataref setter object and register it in a slot.
313 *
314 * @return the ID of the new setter.
315 */
316 int createMultiSetter() noexcept;
317
318 /**
319 * Destroy the multi-dataref buffer with the given ID.
320 *
321 * @param bufferID the ID of the buffer. It should be a valid ID,
322 * that belongs to this connection.
323 *
324 * @return whether the buffer was found and could be destroyed.
325 */
326 bool destroyMultiBuffer(int bufferID);
327};
328
329//------------------------------------------------------------------------------
330
331inline Connection& Connection::get(const MultiBuffer& buffer) noexcept
332{
333 return static_cast<Connection&>(buffer.getXPlane());
334}
335
336//------------------------------------------------------------------------------
337
338inline Connection::Connection() noexcept :
339 lastErrorCode(0),
340 lastErrorSubCode(0)
341{
342}
343
344//------------------------------------------------------------------------------
345
346Connection::~Connection() noexcept
347{
348 for(multiBufferIDs_t::iterator i = multiBufferIDs.begin();
349 i!=multiBufferIDs.end(); ++i)
350 {
351 MultiBufferSlot::clearValue(*i);
352 }
353}
354
355//------------------------------------------------------------------------------
356
357void Connection::handleException() noexcept
358{
359 try {
360 throw;
361 } catch(const IOException& e) {
362 lastErrorCode = ERROR_IO;
363 lastErrorSubCode = e.getErrorCode();
364 lastErrorString = e.what();
365 } catch(const ProtocolException& e) {
366 lastErrorCode = ERROR_PROTOCOL;
367 lastErrorSubCode = static_cast<unsigned long>(e.getErrorCode());
368 lastErrorString = e.what();
369 } catch(const NotConnectedException& e) {
370 lastErrorCode = ERROR_NOT_CONNECTED;
371 lastErrorSubCode = 0;
372 lastErrorString = e.what();
373 } catch(const TypeMismatchException& e) {
374 lastErrorCode = ERROR_TYPE_MISMATCH;
375 lastErrorSubCode = 0;
376 lastErrorString = e.what();
377 } catch(const InvalidIDException& e) {
378 lastErrorCode = ERROR_INVALID_ID;
379 lastErrorSubCode = 0;
380 lastErrorString = e.what();
381 } catch(const exception& e) {
382 lastErrorCode = ERROR_OTHER;
383 lastErrorSubCode = 0;
384 lastErrorString = e.what();
385 } catch(...) {
386 lastErrorCode = ERROR_OTHER;
387 lastErrorSubCode = 0;
388 lastErrorString = "<Exception of an unknown type>";
389 }
390}
391
392//------------------------------------------------------------------------------
393
394inline int Connection::getLastError(unsigned long* lastErrorSubCode)
395 const noexcept
396{
397 if (lastErrorSubCode!=0) *lastErrorSubCode = this->lastErrorSubCode;
398 return lastErrorCode;
399}
400
401//------------------------------------------------------------------------------
402
403inline const char* Connection::getLastErrorString() const noexcept
404{
405 return (lastErrorCode==ERROR_NONE) ? 0 : lastErrorString.c_str();
406}
407
408//------------------------------------------------------------------------------
409
410inline void Connection::clearLastError() noexcept
411{
412 lastErrorCode = ERROR_NONE;
413 lastErrorSubCode = 0;
414 lastErrorString.clear();
415}
416
417//------------------------------------------------------------------------------
418
419inline int Connection::createMultiGetter() noexcept
420{
421 MultiGetter& getter = XPlane::createMultiGetter();
422 return MultiBufferSlot::addValue(&getter);
423}
424
425//------------------------------------------------------------------------------
426
427inline int Connection::createMultiSetter() noexcept
428{
429 MultiSetter& setter = XPlane::createMultiSetter();
430 return MultiBufferSlot::addValue(&setter);
431}
432
433//------------------------------------------------------------------------------
434
435bool Connection::destroyMultiBuffer(int bufferID)
436{
437 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
438 if (buffer==0) return false;
439
440 if (XPlane::destroyMultiBuffer(*buffer)) {
441 multiBufferIDs.erase(bufferID);
442 MultiBufferSlot::clearValue(bufferID);
443 return true;
444 } else {
445 return false;
446 }
447}
448
449//------------------------------------------------------------------------------
450//------------------------------------------------------------------------------
451
452/**
453 * Slot for connections.
454 */
455typedef Slot<Connection*> ConnectionSlot;
456
457//------------------------------------------------------------------------------
458
459} /* anonymous namespace */
460
461//------------------------------------------------------------------------------
462
463extern "C" int xplra_get_last_error(int connectionID, unsigned long* subCode)
464{
465 Connection* connection = ConnectionSlot::getValue(connectionID);
466 return (connection==0) ? -1 : connection->getLastError(subCode);
467}
468
469//------------------------------------------------------------------------------
470
471extern "C" const char* xplra_get_last_error_string(int connectionID)
472{
473 Connection* connection = ConnectionSlot::getValue(connectionID);
474 return (connection==0) ? 0 : connection->getLastErrorString();
475}
476
477//------------------------------------------------------------------------------
478
479extern "C" void xplra_clear_last_error(int connectionID)
480{
481 Connection* connection = ConnectionSlot::getValue(connectionID);
482 if (connection!=0) connection->clearLastError();
483}
484
485//------------------------------------------------------------------------------
486
487extern "C" int xplra_connect()
488{
489 try {
490 unique_ptr<Connection> connection(new Connection());
491 connection->connect();
492 return ConnectionSlot::addValue(connection.release());
493 } catch(...) {
494 return -1;
495 }
496}
497
498//------------------------------------------------------------------------------
499
500extern "C" int xplra_connect_tcp(const char* address)
501{
502 try {
503 unique_ptr<Connection> connection(new Connection());
504 connection->connectTCP(address);
505 return ConnectionSlot::addValue(connection.release());
506 } catch(...) {
507 return -1;
508 }
509}
510
511//------------------------------------------------------------------------------
512
513extern "C" int xplra_connect_tcp_port(const char* address, unsigned short port)
514{
515 try {
516 unique_ptr<Connection> connection(new Connection());
517 connection->connectTCP(address, port);
518 return ConnectionSlot::addValue(connection.release());
519 } catch(...) {
520 return -1;
521 }
522}
523
524//------------------------------------------------------------------------------
525
526extern "C" int xplra_get_versions(int connectionID,
527 int* xplaneVersion, int* xplmVersion,
528 int* xplraVersion)
529{
530 Connection* connection = ConnectionSlot::getValue(connectionID);
531 if (connection==0) return -1;
532 try {
533 connection->getVersions(*xplaneVersion, *xplmVersion, *xplraVersion);
534 return 0;
535 } catch (...) {
536 connection->handleException();
537 return -1;
538 }
539}
540
541//------------------------------------------------------------------------------
542
543extern "C" int xplra_reload_plugins(int connectionID)
544{
545 Connection* connection = ConnectionSlot::getValue(connectionID);
546 if (connection==0) return -1;
547 try {
548 connection->reloadPlugins();
549 return 0;
550 } catch (...) {
551 connection->handleException();
552 return -1;
553 }
554}
555
556//------------------------------------------------------------------------------
557
558extern "C" int xplra_save_situation(int connectionID, const char* path)
559{
560 Connection* connection = ConnectionSlot::getValue(connectionID);
561 if (connection==0) return -1;
562 try {
563 connection->saveSituation(path);
564 return 0;
565 } catch (...) {
566 connection->handleException();
567 return -1;
568 }
569}
570
571//------------------------------------------------------------------------------
572
573extern "C" int xplra_get_int(int* value, int connectionID, const char* name)
574{
575 Connection* connection = ConnectionSlot::getValue(connectionID);
576 if (connection==0) return -1;
577 try {
578 *value = connection->getInt(name);
579 return 0;
580 } catch (...) {
581 connection->handleException();
582 return -1;
583 }
584}
585
586//------------------------------------------------------------------------------
587
588extern "C" int xplra_get_float(float* value, int connectionID, const char* name)
589{
590 Connection* connection = ConnectionSlot::getValue(connectionID);
591 if (connection==0) return -1;
592 try {
593 *value = connection->getFloat(name);
594 return 0;
595 } catch (...) {
596 connection->handleException();
597 return -1;
598 }
599}
600
601//------------------------------------------------------------------------------
602
603extern "C" int xplra_get_double(double* value,
604 int connectionID, const char* name)
605{
606 Connection* connection = ConnectionSlot::getValue(connectionID);
607 if (connection==0) return -1;
608 try {
609 *value = connection->getDouble(name);
610 return 0;
611 } catch (...) {
612 connection->handleException();
613 return -1;
614 }
615}
616
617//------------------------------------------------------------------------------
618
619extern "C" ssize_t xplra_get_float_array(float* dest, size_t length, size_t offset,
620 int connectionID, const char* name)
621{
622 Connection* connection = ConnectionSlot::getValue(connectionID);
623 if (connection==0) return -1;
624 try {
625 return connection->getFloatArray(name, dest, length, offset);
626 } catch (...) {
627 connection->handleException();
628 return -1;
629 }
630}
631
632/*----------------------------------------------------------------------------*/
633
634extern "C" float* xplra_get_float_array_new(size_t* length, size_t offset,
635 int connectionID, const char* name)
636{
637 Connection* connection = ConnectionSlot::getValue(connectionID);
638 if (connection==0) return 0;
639 try {
640 return connection->getFloatArray(name, *length, offset);
641 } catch (...) {
642 connection->handleException();
643 return 0;
644 }
645}
646
647//------------------------------------------------------------------------------
648
649extern "C" ssize_t xplra_get_int_array(int32_t* dest, size_t length, size_t offset,
650 int connectionID, const char* name)
651{
652 Connection* connection = ConnectionSlot::getValue(connectionID);
653 if (connection==0) return -1;
654 try {
655 return connection->getIntArray(name, dest, length, offset);
656 } catch (...) {
657 connection->handleException();
658 return -1;
659 }
660}
661
662/*----------------------------------------------------------------------------*/
663
664extern "C" int32_t* xplra_get_int_array_new(size_t* length, size_t offset,
665 int connectionID, const char* name)
666{
667 Connection* connection = ConnectionSlot::getValue(connectionID);
668 if (connection==0) return 0;
669 try {
670 return connection->getIntArray(name, *length, offset);
671 } catch (...) {
672 connection->handleException();
673 return 0;
674 }
675}
676
677//------------------------------------------------------------------------------
678
679extern "C" ssize_t xplra_get_byte_array(void* dest, size_t length, size_t offset,
680 int connectionID, const char* name)
681{
682 Connection* connection = ConnectionSlot::getValue(connectionID);
683 if (connection==0) return -1;
684 try {
685 return connection->getByteArray(name, reinterpret_cast<uint8_t*>(dest),
686 length, offset);
687 } catch (...) {
688 connection->handleException();
689 return -1;
690 }
691}
692
693/*----------------------------------------------------------------------------*/
694
695extern "C" uint8_t* xplra_get_byte_array_new(size_t* length, size_t offset,
696 int connectionID, const char* name)
697{
698 Connection* connection = ConnectionSlot::getValue(connectionID);
699 if (connection==0) return 0;
700 try {
701 return connection->getByteArray(name, *length, offset);
702 } catch (...) {
703 connection->handleException();
704 return 0;
705 }
706}
707
708//------------------------------------------------------------------------------
709
710extern "C" int xplra_set_int(int connectionID, const char* name, int value)
711{
712 Connection* connection = ConnectionSlot::getValue(connectionID);
713 if (connection==0) return 0;
714 try {
715 connection->setInt(name, value);
716 return 0;
717 } catch (...) {
718 connection->handleException();
719 return -1;
720 }
721}
722
723//------------------------------------------------------------------------------
724
725extern "C" int xplra_set_float(int connectionID, const char* name, float value)
726{
727 Connection* connection = ConnectionSlot::getValue(connectionID);
728 if (connection==0) return 0;
729 try {
730 connection->setFloat(name, value);
731 return 0;
732 } catch (...) {
733 connection->handleException();
734 return -1;
735 }
736}
737
738//------------------------------------------------------------------------------
739
740extern "C" int xplra_set_double(int connectionID, const char* name,
741 double value)
742{
743 Connection* connection = ConnectionSlot::getValue(connectionID);
744 if (connection==0) return 0;
745 try {
746 connection->setDouble(name, value);
747 return 0;
748 } catch (...) {
749 connection->handleException();
750 return -1;
751 }
752}
753
754/*----------------------------------------------------------------------------*/
755
756extern "C" int xplra_set_float_array(int connectionID, const char* name,
757 const float* values,
758 size_t length, size_t offset)
759{
760 Connection* connection = ConnectionSlot::getValue(connectionID);
761 if (connection==0) return 0;
762 try {
763 connection->setFloatArray(name, values, length, offset);
764 return 0;
765 } catch (...) {
766 connection->handleException();
767 return -1;
768 }
769}
770
771/*----------------------------------------------------------------------------*/
772
773extern "C" int xplra_set_int_array(int connectionID, const char* name,
774 const int32_t* values,
775 size_t length, size_t offset)
776{
777 Connection* connection = ConnectionSlot::getValue(connectionID);
778 if (connection==0) return 0;
779 try {
780 connection->setIntArray(name, values, length, offset);
781 return 0;
782 } catch (...) {
783 connection->handleException();
784 return -1;
785 }
786}
787
788/*----------------------------------------------------------------------------*/
789
790extern "C" int xplra_set_byte_array(int connectionID, const char* name,
791 const void* values,
792 size_t length, size_t offset)
793{
794 Connection* connection = ConnectionSlot::getValue(connectionID);
795 if (connection==0) return 0;
796 try {
797 connection->setByteArray(name, reinterpret_cast<const uint8_t*>(values),
798 length, offset);
799 return 0;
800 } catch (...) {
801 connection->handleException();
802 return -1;
803 }
804}
805
806/*----------------------------------------------------------------------------*/
807
808extern "C" int xplra_set_string(int connectionID, const char* name,
809 const char* value,
810 size_t length, size_t offset)
811{
812 Connection* connection = ConnectionSlot::getValue(connectionID);
813 if (connection==0) return 0;
814 try {
815 connection->setString(name, value, length, offset);
816 return 0;
817 } catch (...) {
818 connection->handleException();
819 return -1;
820 }
821}
822
823//------------------------------------------------------------------------------
824//------------------------------------------------------------------------------
825
826extern "C" int xplra_multi_create_getter(int connectionID)
827{
828 Connection* connection = ConnectionSlot::getValue(connectionID);
829 return (connection==0) ? -1 : connection->createMultiGetter();
830}
831
832//------------------------------------------------------------------------------
833
834extern "C" int xplra_multi_create_setter(int connectionID)
835{
836 Connection* connection = ConnectionSlot::getValue(connectionID);
837 return (connection==0) ? -1 : connection->createMultiSetter();
838}
839
840//------------------------------------------------------------------------------
841
842extern "C" size_t xplra_multi_add_int(int bufferID, const char* name)
843{
844 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
845 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addInt(name);
846}
847
848//------------------------------------------------------------------------------
849
850extern "C" size_t xplra_multi_add_float(int bufferID, const char* name)
851{
852 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
853 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addFloat(name);
854}
855
856//------------------------------------------------------------------------------
857
858extern "C" size_t xplra_multi_add_double(int bufferID, const char* name)
859{
860 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
861 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addDouble(name);
862}
863
864/*----------------------------------------------------------------------------*/
865
866extern "C" size_t xplra_multi_add_float_array(int bufferID, const char* name,
867 size_t length, size_t offset)
868{
869 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
870 return (buffer==0) ?
871 INVALID_DATAREF_ID : buffer->addFloatArray(name, length, offset);
872}
873
874/*----------------------------------------------------------------------------*/
875
876extern "C" size_t xplra_multi_add_int_array(int bufferID, const char* name,
877 size_t length, size_t offset)
878{
879 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
880 return (buffer==0) ?
881 INVALID_DATAREF_ID : buffer->addIntArray(name, length, offset);
882}
883
884/*----------------------------------------------------------------------------*/
885
886extern "C" size_t xplra_multi_add_byte_array(int bufferID, const char* name,
887 size_t length, size_t offset)
888{
889 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
890 return (buffer==0) ?
891 INVALID_DATAREF_ID : buffer->addByteArray(name, length, offset);
892}
893
894/*----------------------------------------------------------------------------*/
895
896extern "C" int xplra_multi_finalize(int bufferID)
897{
898 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
899 return (buffer==0) ? -1 : (buffer->finalize() ? 1 : 0);
900}
901
902/*----------------------------------------------------------------------------*/
903
904extern "C" int xplra_multi_register(int bufferID)
905{
906 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
907 if (buffer==0) return -1;
908 try {
909 buffer->registerInXPlane();
910 return 0;
911 } catch (...) {
912 Connection::get(*buffer).handleException();
913 return -1;
914 }
915}
916
917/*----------------------------------------------------------------------------*/
918
919extern "C" int xplra_multi_unregister(int bufferID)
920{
921 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
922 if (buffer==0) return -1;
923 try {
924 buffer->unregisterFromXPlane();
925 return 0;
926 } catch (...) {
927 Connection::get(*buffer).handleException();
928 return -1;
929 }
930}
931
932/*----------------------------------------------------------------------------*/
933
934extern "C" int xplra_multi_unregister_safely(int bufferID)
935{
936 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
937 return (buffer==0) ? -1 : (buffer->unregisterSafelyFromXPlane() ? 1 : 0);
938}
939
940/*----------------------------------------------------------------------------*/
941
942extern "C" int xplra_multi_execute(int bufferID)
943{
944 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
945 if (buffer==0) return -1;
946 try {
947 buffer->execute();
948 return 0;
949 } catch (...) {
950 Connection::get(*buffer).handleException();
951 return -1;
952 }
953}
954
955//------------------------------------------------------------------------------
956
957extern "C" int xplra_multi_set_int(int bufferID, size_t datarefID, int value)
958{
959 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
960 if (buffer==0) return -1;
961 try {
962 buffer->setInt(datarefID, value);
963 return 0;
964 } catch (...) {
965 Connection::get(*buffer).handleException();
966 return -1;
967 }
968}
969
970/*----------------------------------------------------------------------------*/
971
972extern "C" int xplra_multi_get_int(int* dest, int bufferID, size_t datarefID)
973{
974 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
975 if (buffer==0) return -1;
976 try {
977 *dest = buffer->getInt(datarefID);
978 return 0;
979 } catch (...) {
980 Connection::get(*buffer).handleException();
981 return -1;
982 }
983}
984
985/*----------------------------------------------------------------------------*/
986
987extern "C"
988const int32_t* xplra_multi_get_int_const_ptr(int bufferID, size_t datarefID)
989{
990 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
991 if (buffer==0) return 0;
992 try {
993 return &(buffer->getIntRef(datarefID));
994 } catch (...) {
995 Connection::get(*buffer).handleException();
996 return 0;
997 }
998}
999
1000/*----------------------------------------------------------------------------*/
1001
1002extern "C"
1003int32_t* xplra_multi_get_int_ptr(int bufferID, size_t datarefID)
1004{
1005 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1006 if (buffer==0) return 0;
1007 try {
1008 return &(buffer->getIntRef(datarefID));
1009 } catch (...) {
1010 Connection::get(*buffer).handleException();
1011 return 0;
1012 }
1013}
1014
1015//------------------------------------------------------------------------------
1016
1017extern "C"
1018int xplra_multi_set_float(int bufferID, size_t datarefID, float value)
1019{
1020 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1021 if (buffer==0) return -1;
1022 try {
1023 buffer->setFloat(datarefID, value);
1024 return 0;
1025 } catch (...) {
1026 Connection::get(*buffer).handleException();
1027 return -1;
1028 }
1029}
1030
1031/*----------------------------------------------------------------------------*/
1032
1033extern "C"
1034int xplra_multi_get_float(float* dest, int bufferID, size_t datarefID)
1035{
1036 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1037 if (buffer==0) return -1;
1038 try {
1039 *dest = buffer->getFloat(datarefID);
1040 return 0;
1041 } catch (...) {
1042 Connection::get(*buffer).handleException();
1043 return -1;
1044 }
1045}
1046
1047/*----------------------------------------------------------------------------*/
1048
1049extern "C"
1050const float* xplra_multi_get_float_const_ptr(int bufferID, size_t datarefID)
1051{
1052 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1053 if (buffer==0) return 0;
1054 try {
1055 return &(buffer->getFloatRef(datarefID));
1056 } catch (...) {
1057 Connection::get(*buffer).handleException();
1058 return 0;
1059 }
1060}
1061
1062/*----------------------------------------------------------------------------*/
1063
1064extern "C"
1065float* xplra_multi_get_float_ptr(int bufferID, size_t datarefID)
1066{
1067 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1068 if (buffer==0) return 0;
1069 try {
1070 return &(buffer->getFloatRef(datarefID));
1071 } catch (...) {
1072 Connection::get(*buffer).handleException();
1073 return 0;
1074 }
1075}
1076
1077//------------------------------------------------------------------------------
1078
1079extern "C"
1080int xplra_multi_set_double(int bufferID, size_t datarefID, double value)
1081{
1082 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1083 if (buffer==0) return -1;
1084 try {
1085 buffer->setDouble(datarefID, value);
1086 return 0;
1087 } catch (...) {
1088 Connection::get(*buffer).handleException();
1089 return -1;
1090 }
1091}
1092
1093/*----------------------------------------------------------------------------*/
1094
1095extern "C"
1096int xplra_multi_get_double(double* dest, int bufferID, size_t datarefID)
1097{
1098 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1099 if (buffer==0) return -1;
1100 try {
1101 *dest = buffer->getDouble(datarefID);
1102 return 0;
1103 } catch (...) {
1104 Connection::get(*buffer).handleException();
1105 return -1;
1106 }
1107}
1108
1109/*----------------------------------------------------------------------------*/
1110
1111extern "C"
1112const double* xplra_multi_get_double_const_ptr(int bufferID, size_t datarefID)
1113{
1114 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1115 if (buffer==0) return 0;
1116 try {
1117 return &(buffer->getDoubleRef(datarefID));
1118 } catch (...) {
1119 Connection::get(*buffer).handleException();
1120 return 0;
1121 }
1122}
1123
1124/*----------------------------------------------------------------------------*/
1125
1126extern "C"
1127double* xplra_multi_get_double_ptr(int bufferID, size_t datarefID)
1128{
1129 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1130 if (buffer==0) return 0;
1131 try {
1132 return &(buffer->getDoubleRef(datarefID));
1133 } catch (...) {
1134 Connection::get(*buffer).handleException();
1135 return 0;
1136 }
1137}
1138
1139//------------------------------------------------------------------------------
1140
1141extern "C"
1142ssize_t xplra_multi_set_float_array(int bufferID, size_t datarefID,
1143 const float* value, size_t length,
1144 size_t offset)
1145{
1146 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1147 if (buffer==0) return -1;
1148 try {
1149 return buffer->setFloatArray(datarefID, value, length, offset);
1150 } catch (...) {
1151 Connection::get(*buffer).handleException();
1152 return -1;
1153 }
1154}
1155
1156/*----------------------------------------------------------------------------*/
1157
1158extern "C"
1159ssize_t xplra_multi_get_float_array(float* value,
1160 size_t length, size_t offset,
1161 int bufferID, size_t datarefID)
1162{
1163 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1164 if (buffer==0) return -1;
1165 try {
1166 return buffer->getFloatArray(datarefID, value, length, offset);
1167 } catch (...) {
1168 Connection::get(*buffer).handleException();
1169 return -1;
1170 }
1171}
1172
1173/*----------------------------------------------------------------------------*/
1174
1175extern "C"
1176const float* xplra_multi_get_float_array_ptr(int bufferID, size_t datarefID,
1177 size_t offset)
1178{
1179 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1180 if (buffer==0) return 0;
1181 try {
1182 return buffer->getFloatArray(datarefID, offset);
1183 } catch (...) {
1184 Connection::get(*buffer).handleException();
1185 return 0;
1186 }
1187}
1188
1189//------------------------------------------------------------------------------
1190
1191extern "C"
1192ssize_t xplra_multi_set_int_array(int bufferID, size_t datarefID,
1193 const int32_t* value, size_t length,
1194 size_t offset)
1195{
1196 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1197 if (buffer==0) return -1;
1198 try {
1199 return buffer->setIntArray(datarefID, value, length, offset);
1200 } catch (...) {
1201 Connection::get(*buffer).handleException();
1202 return -1;
1203 }
1204}
1205
1206/*----------------------------------------------------------------------------*/
1207
1208extern "C"
1209ssize_t xplra_multi_get_int_array(int32_t* value,
1210 size_t length, size_t offset,
1211 int bufferID, size_t datarefID)
1212{
1213 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1214 if (buffer==0) return -1;
1215 try {
1216 return buffer->getIntArray(datarefID, value, length, offset);
1217 } catch (...) {
1218 Connection::get(*buffer).handleException();
1219 return -1;
1220 }
1221}
1222
1223/*----------------------------------------------------------------------------*/
1224
1225extern "C"
1226const int32_t* xplra_multi_get_int_array_ptr(int bufferID, size_t datarefID,
1227 size_t offset)
1228{
1229 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1230 if (buffer==0) return 0;
1231 try {
1232 return buffer->getIntArray(datarefID, offset);
1233 } catch (...) {
1234 Connection::get(*buffer).handleException();
1235 return 0;
1236 }
1237}
1238
1239//------------------------------------------------------------------------------
1240
1241extern "C"
1242ssize_t xplra_multi_set_byte_array(int bufferID, size_t datarefID,
1243 const void* value, size_t length,
1244 size_t offset)
1245{
1246 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1247 if (buffer==0) return -1;
1248 try {
1249 return buffer->setByteArray(datarefID,
1250 reinterpret_cast<const uint8_t*>(value),
1251 length, offset);
1252 } catch (...) {
1253 Connection::get(*buffer).handleException();
1254 return -1;
1255 }
1256}
1257
1258/*----------------------------------------------------------------------------*/
1259
1260extern "C"
1261ssize_t xplra_multi_get_byte_array(void* value,
1262 size_t length, size_t offset,
1263 int bufferID, size_t datarefID)
1264{
1265 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1266 if (buffer==0) return -1;
1267 try {
1268 return buffer->getByteArray(datarefID,
1269 reinterpret_cast<uint8_t*>(value),
1270 length, offset);
1271 } catch (...) {
1272 Connection::get(*buffer).handleException();
1273 return -1;
1274 }
1275}
1276
1277/*----------------------------------------------------------------------------*/
1278
1279extern "C"
1280const uint8_t* xplra_multi_get_byte_array_ptr(int bufferID, size_t datarefID,
1281 size_t offset)
1282{
1283 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1284 if (buffer==0) return 0;
1285 try {
1286 return buffer->getByteArray(datarefID, offset);
1287 } catch (...) {
1288 Connection::get(*buffer).handleException();
1289 return 0;
1290 }
1291}
1292
1293//------------------------------------------------------------------------------
1294
1295extern "C" ssize_t xplra_multi_set_string(int bufferID, size_t datarefID,
1296 const char* value, size_t offset)
1297{
1298 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1299 if (buffer==0) return -1;
1300 try {
1301 return buffer->setString(datarefID, value, offset);
1302 } catch (...) {
1303 Connection::get(*buffer).handleException();
1304 return -1;
1305 }
1306}
1307
1308/*----------------------------------------------------------------------------*/
1309
1310extern "C"
1311const char* xplra_multi_get_string_ptr(int bufferID, size_t datarefID,
1312 size_t offset)
1313{
1314 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1315 if (buffer==0) return 0;
1316 try {
1317 return buffer->getStringPtr(datarefID, offset);
1318 } catch (...) {
1319 Connection::get(*buffer).handleException();
1320 return 0;
1321 }
1322}
1323
1324//------------------------------------------------------------------------------
1325
1326extern "C" int xplra_multi_destroy_buffer(int connectionID, int bufferID)
1327{
1328 Connection* connection = ConnectionSlot::getValue(connectionID);
1329 if (connection==0) return -1;
1330
1331 try {
1332 return connection->destroyMultiBuffer(bufferID) ? 0 : -1;
1333 } catch(...) {
1334 connection->handleException();
1335 return -1;
1336 }
1337}
1338
1339//------------------------------------------------------------------------------
1340//------------------------------------------------------------------------------
1341
1342extern "C" int xplra_show_message(int connectionID,
1343 const char* message, float duration)
1344{
1345 Connection* connection = ConnectionSlot::getValue(connectionID);
1346 if (connection==0) return -1;
1347
1348 try {
1349 connection->showMessage(message, duration);
1350 return 0;
1351 } catch(...) {
1352 connection->handleException();
1353 return -1;
1354 }
1355}
1356
1357//------------------------------------------------------------------------------
1358//------------------------------------------------------------------------------
1359
1360extern "C" int xplra_register_hotkeys(int connectionID,
1361 const uint16_t* codes, size_t length)
1362{
1363 Connection* connection = ConnectionSlot::getValue(connectionID);
1364 if (connection==0) return -1;
1365
1366 try {
1367 connection->registerHotkeys(codes, length);
1368 return 0;
1369 } catch(...) {
1370 connection->handleException();
1371 return -1;
1372 }
1373}
1374
1375/*----------------------------------------------------------------------------*/
1376
1377extern "C" int xplra_query_hotkeys(int connectionID,
1378 uint8_t* states, size_t length)
1379{
1380 Connection* connection = ConnectionSlot::getValue(connectionID);
1381 if (connection==0) return -1;
1382
1383 try {
1384 connection->queryHotkeys(states, length);
1385 return 0;
1386 } catch(...) {
1387 connection->handleException();
1388 return -1;
1389 }
1390}
1391
1392/*----------------------------------------------------------------------------*/
1393
1394extern "C" int xplra_unregister_hotkeys(int connectionID)
1395{
1396 Connection* connection = ConnectionSlot::getValue(connectionID);
1397 if (connection==0) return -1;
1398
1399 try {
1400 connection->unregisterHotkeys();
1401 return 0;
1402 } catch(...) {
1403 connection->handleException();
1404 return -1;
1405 }
1406}
1407
1408//------------------------------------------------------------------------------
1409//------------------------------------------------------------------------------
1410
1411extern "C" int xplra_disconnect(int connectionID)
1412{
1413 Connection* connection = ConnectionSlot::getValue(connectionID);
1414 if (connection==0) return -1;
1415
1416 connection->disconnect();
1417
1418 return 0;
1419}
1420
1421//------------------------------------------------------------------------------
1422//------------------------------------------------------------------------------
1423
1424extern "C" int xplra_reconnect(int connectionID)
1425{
1426 Connection* connection = ConnectionSlot::getValue(connectionID);
1427 if (connection==0) return -1;
1428
1429 try {
1430 connection->connect();
1431 return 0;
1432 } catch(...) {
1433 return -1;
1434 }
1435}
1436
1437//------------------------------------------------------------------------------
1438//------------------------------------------------------------------------------
1439
1440extern "C" int xplra_destroy(int connectionID)
1441{
1442 Connection* connection = ConnectionSlot::getValue(connectionID);
1443 if (connection==0) return -1;
1444
1445 ConnectionSlot::clearValue(connectionID);
1446 delete connection;
1447
1448 return 0;
1449}
1450
1451//------------------------------------------------------------------------------
1452//------------------------------------------------------------------------------
1453
1454// Local Variables:
1455// mode: C++
1456// c-basic-offset: 4
1457// indent-tabs-mode: nil
1458// End:
Note: See TracBrowser for help on using the repository browser.