source: xplra/src/client/c/hu/varadiistvan/xplra/xplra.cc@ 58:f0fa93354e15

Last change on this file since 58:f0fa93354e15 was 58:f0fa93354e15, checked in by István Váradi <ivaradi@…>, 11 years ago

Added the safe unregistration support to the C client interface

File size: 40.4 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::auto_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) throw();
93
94 /**
95 * Get the value with the given ID.
96 */
97 static Value getValue(int valueID) throw();
98
99 /**
100 * Clear the value with the given ID.
101 */
102 static void clearValue(int valueID) throw();
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) throw();
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) throw();
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 throw();
134
135 /**
136 * Clear the value and set the given next free index.
137 */
138 void clear(int nextFreeIndex) throw();
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) throw() :
153 valid(true)
154{
155 this->value = value;
156}
157
158//------------------------------------------------------------------------------
159
160template <class Value>
161inline int Slot<Value>::setValue(Value value) throw()
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 throw()
174{
175 return valid ? value : static_cast<Value>(0);
176}
177
178//------------------------------------------------------------------------------
179
180template <class Value>
181inline void Slot<Value>::clear(int nextFreeIndex) throw()
182{
183 assert(valid);
184 valid = false;
185 this->nextFreeIndex = nextFreeIndex;
186}
187
188//------------------------------------------------------------------------------
189
190template <class Value>
191int Slot<Value>::addValue(Value value) throw()
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) throw()
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) throw()
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) throw();
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() throw();
278
279 /**
280 * Destroy the connection.
281 */
282 ~Connection() throw();
283
284 /**
285 * Handle the currently pending exception.
286 */
287 void handleException() throw();
288
289 /**
290 * Get the last error code.
291 */
292 int getLastError(unsigned long* lastErrorSubCode) const throw();
293
294 /**
295 * Get the string representation of the last error code.
296 */
297 const char* getLastErrorString() const throw();
298
299 /**
300 * Clear the last error code.
301 */
302 void clearLastError() throw();
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() throw();
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() throw();
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) throw(Exception);
327};
328
329//------------------------------------------------------------------------------
330
331inline Connection& Connection::get(const MultiBuffer& buffer) throw()
332{
333 return static_cast<Connection&>(buffer.getXPlane());
334}
335
336//------------------------------------------------------------------------------
337
338inline Connection::Connection() throw() :
339 lastErrorCode(0),
340 lastErrorSubCode(0)
341{
342}
343
344//------------------------------------------------------------------------------
345
346Connection::~Connection() throw()
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() throw()
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 throw()
396{
397 if (lastErrorSubCode!=0) *lastErrorSubCode = this->lastErrorSubCode;
398 return lastErrorCode;
399}
400
401//------------------------------------------------------------------------------
402
403inline const char* Connection::getLastErrorString() const throw()
404{
405 return (lastErrorCode==ERROR_NONE) ? 0 : lastErrorString.c_str();
406}
407
408//------------------------------------------------------------------------------
409
410inline void Connection::clearLastError() throw()
411{
412 lastErrorCode = ERROR_NONE;
413 lastErrorSubCode = 0;
414 lastErrorString.clear();
415}
416
417//------------------------------------------------------------------------------
418
419inline int Connection::createMultiGetter() throw()
420{
421 MultiGetter& getter = XPlane::createMultiGetter();
422 return MultiBufferSlot::addValue(&getter);
423}
424
425//------------------------------------------------------------------------------
426
427inline int Connection::createMultiSetter() throw()
428{
429 MultiSetter& setter = XPlane::createMultiSetter();
430 return MultiBufferSlot::addValue(&setter);
431}
432
433//------------------------------------------------------------------------------
434
435bool Connection::destroyMultiBuffer(int bufferID) throw(Exception)
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 auto_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_get_versions(int connectionID,
501 int* xplaneVersion, int* xplmVersion,
502 int* xplraVersion)
503{
504 Connection* connection = ConnectionSlot::getValue(connectionID);
505 if (connection==0) return -1;
506 try {
507 connection->getVersions(*xplaneVersion, *xplmVersion, *xplraVersion);
508 return 0;
509 } catch (...) {
510 connection->handleException();
511 return -1;
512 }
513}
514
515//------------------------------------------------------------------------------
516
517extern "C" int xplra_reload_plugins(int connectionID)
518{
519 Connection* connection = ConnectionSlot::getValue(connectionID);
520 if (connection==0) return -1;
521 try {
522 connection->reloadPlugins();
523 return 0;
524 } catch (...) {
525 connection->handleException();
526 return -1;
527 }
528}
529
530//------------------------------------------------------------------------------
531
532extern "C" int xplra_get_int(int* value, int connectionID, const char* name)
533{
534 Connection* connection = ConnectionSlot::getValue(connectionID);
535 if (connection==0) return -1;
536 try {
537 *value = connection->getInt(name);
538 return 0;
539 } catch (...) {
540 connection->handleException();
541 return -1;
542 }
543}
544
545//------------------------------------------------------------------------------
546
547extern "C" int xplra_get_float(float* value, int connectionID, const char* name)
548{
549 Connection* connection = ConnectionSlot::getValue(connectionID);
550 if (connection==0) return -1;
551 try {
552 *value = connection->getFloat(name);
553 return 0;
554 } catch (...) {
555 connection->handleException();
556 return -1;
557 }
558}
559
560//------------------------------------------------------------------------------
561
562extern "C" int xplra_get_double(double* value,
563 int connectionID, const char* name)
564{
565 Connection* connection = ConnectionSlot::getValue(connectionID);
566 if (connection==0) return -1;
567 try {
568 *value = connection->getDouble(name);
569 return 0;
570 } catch (...) {
571 connection->handleException();
572 return -1;
573 }
574}
575
576//------------------------------------------------------------------------------
577
578extern "C" ssize_t xplra_get_float_array(float* dest, size_t length, size_t offset,
579 int connectionID, const char* name)
580{
581 Connection* connection = ConnectionSlot::getValue(connectionID);
582 if (connection==0) return -1;
583 try {
584 return connection->getFloatArray(name, dest, length, offset);
585 } catch (...) {
586 connection->handleException();
587 return -1;
588 }
589}
590
591/*----------------------------------------------------------------------------*/
592
593extern "C" float* xplra_get_float_array_new(size_t* length, size_t offset,
594 int connectionID, const char* name)
595{
596 Connection* connection = ConnectionSlot::getValue(connectionID);
597 if (connection==0) return 0;
598 try {
599 return connection->getFloatArray(name, *length, offset);
600 } catch (...) {
601 connection->handleException();
602 return 0;
603 }
604}
605
606//------------------------------------------------------------------------------
607
608extern "C" ssize_t xplra_get_int_array(int32_t* dest, size_t length, size_t offset,
609 int connectionID, const char* name)
610{
611 Connection* connection = ConnectionSlot::getValue(connectionID);
612 if (connection==0) return -1;
613 try {
614 return connection->getIntArray(name, dest, length, offset);
615 } catch (...) {
616 connection->handleException();
617 return -1;
618 }
619}
620
621/*----------------------------------------------------------------------------*/
622
623extern "C" int32_t* xplra_get_int_array_new(size_t* length, size_t offset,
624 int connectionID, const char* name)
625{
626 Connection* connection = ConnectionSlot::getValue(connectionID);
627 if (connection==0) return 0;
628 try {
629 return connection->getIntArray(name, *length, offset);
630 } catch (...) {
631 connection->handleException();
632 return 0;
633 }
634}
635
636//------------------------------------------------------------------------------
637
638extern "C" ssize_t xplra_get_byte_array(void* dest, size_t length, size_t offset,
639 int connectionID, const char* name)
640{
641 Connection* connection = ConnectionSlot::getValue(connectionID);
642 if (connection==0) return -1;
643 try {
644 return connection->getByteArray(name, reinterpret_cast<uint8_t*>(dest),
645 length, offset);
646 } catch (...) {
647 connection->handleException();
648 return -1;
649 }
650}
651
652/*----------------------------------------------------------------------------*/
653
654extern "C" uint8_t* xplra_get_byte_array_new(size_t* length, size_t offset,
655 int connectionID, const char* name)
656{
657 Connection* connection = ConnectionSlot::getValue(connectionID);
658 if (connection==0) return 0;
659 try {
660 return connection->getByteArray(name, *length, offset);
661 } catch (...) {
662 connection->handleException();
663 return 0;
664 }
665}
666
667//------------------------------------------------------------------------------
668
669extern "C" int xplra_set_int(int connectionID, const char* name, int value)
670{
671 Connection* connection = ConnectionSlot::getValue(connectionID);
672 if (connection==0) return 0;
673 try {
674 connection->setInt(name, value);
675 return 0;
676 } catch (...) {
677 connection->handleException();
678 return -1;
679 }
680}
681
682//------------------------------------------------------------------------------
683
684extern "C" int xplra_set_float(int connectionID, const char* name, float value)
685{
686 Connection* connection = ConnectionSlot::getValue(connectionID);
687 if (connection==0) return 0;
688 try {
689 connection->setFloat(name, value);
690 return 0;
691 } catch (...) {
692 connection->handleException();
693 return -1;
694 }
695}
696
697//------------------------------------------------------------------------------
698
699extern "C" int xplra_set_double(int connectionID, const char* name,
700 double value)
701{
702 Connection* connection = ConnectionSlot::getValue(connectionID);
703 if (connection==0) return 0;
704 try {
705 connection->setDouble(name, value);
706 return 0;
707 } catch (...) {
708 connection->handleException();
709 return -1;
710 }
711}
712
713/*----------------------------------------------------------------------------*/
714
715extern "C" int xplra_set_float_array(int connectionID, const char* name,
716 const float* values,
717 size_t length, size_t offset)
718{
719 Connection* connection = ConnectionSlot::getValue(connectionID);
720 if (connection==0) return 0;
721 try {
722 connection->setFloatArray(name, values, length, offset);
723 return 0;
724 } catch (...) {
725 connection->handleException();
726 return -1;
727 }
728}
729
730/*----------------------------------------------------------------------------*/
731
732extern "C" int xplra_set_int_array(int connectionID, const char* name,
733 const int32_t* values,
734 size_t length, size_t offset)
735{
736 Connection* connection = ConnectionSlot::getValue(connectionID);
737 if (connection==0) return 0;
738 try {
739 connection->setIntArray(name, values, length, offset);
740 return 0;
741 } catch (...) {
742 connection->handleException();
743 return -1;
744 }
745}
746
747/*----------------------------------------------------------------------------*/
748
749extern "C" int xplra_set_byte_array(int connectionID, const char* name,
750 const void* values,
751 size_t length, size_t offset)
752{
753 Connection* connection = ConnectionSlot::getValue(connectionID);
754 if (connection==0) return 0;
755 try {
756 connection->setByteArray(name, reinterpret_cast<const uint8_t*>(values),
757 length, offset);
758 return 0;
759 } catch (...) {
760 connection->handleException();
761 return -1;
762 }
763}
764
765/*----------------------------------------------------------------------------*/
766
767extern "C" int xplra_set_string(int connectionID, const char* name,
768 const char* value,
769 size_t length, size_t offset)
770{
771 Connection* connection = ConnectionSlot::getValue(connectionID);
772 if (connection==0) return 0;
773 try {
774 connection->setString(name, value, length, offset);
775 return 0;
776 } catch (...) {
777 connection->handleException();
778 return -1;
779 }
780}
781
782//------------------------------------------------------------------------------
783//------------------------------------------------------------------------------
784
785extern "C" int xplra_multi_create_getter(int connectionID)
786{
787 Connection* connection = ConnectionSlot::getValue(connectionID);
788 return (connection==0) ? -1 : connection->createMultiGetter();
789}
790
791//------------------------------------------------------------------------------
792
793extern "C" int xplra_multi_create_setter(int connectionID)
794{
795 Connection* connection = ConnectionSlot::getValue(connectionID);
796 return (connection==0) ? -1 : connection->createMultiSetter();
797}
798
799//------------------------------------------------------------------------------
800
801extern "C" size_t xplra_multi_add_int(int bufferID, const char* name)
802{
803 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
804 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addInt(name);
805}
806
807//------------------------------------------------------------------------------
808
809extern "C" size_t xplra_multi_add_float(int bufferID, const char* name)
810{
811 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
812 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addFloat(name);
813}
814
815//------------------------------------------------------------------------------
816
817extern "C" size_t xplra_multi_add_double(int bufferID, const char* name)
818{
819 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
820 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addDouble(name);
821}
822
823/*----------------------------------------------------------------------------*/
824
825extern "C" size_t xplra_multi_add_float_array(int bufferID, const char* name,
826 size_t length, size_t offset)
827{
828 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
829 return (buffer==0) ?
830 INVALID_DATAREF_ID : buffer->addFloatArray(name, length, offset);
831}
832
833/*----------------------------------------------------------------------------*/
834
835extern "C" size_t xplra_multi_add_int_array(int bufferID, const char* name,
836 size_t length, size_t offset)
837{
838 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
839 return (buffer==0) ?
840 INVALID_DATAREF_ID : buffer->addIntArray(name, length, offset);
841}
842
843/*----------------------------------------------------------------------------*/
844
845extern "C" size_t xplra_multi_add_byte_array(int bufferID, const char* name,
846 size_t length, size_t offset)
847{
848 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
849 return (buffer==0) ?
850 INVALID_DATAREF_ID : buffer->addByteArray(name, length, offset);
851}
852
853/*----------------------------------------------------------------------------*/
854
855extern "C" int xplra_multi_finalize(int bufferID)
856{
857 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
858 return (buffer==0) ? -1 : (buffer->finalize() ? 1 : 0);
859}
860
861/*----------------------------------------------------------------------------*/
862
863extern "C" int xplra_multi_register(int bufferID)
864{
865 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
866 if (buffer==0) return -1;
867 try {
868 buffer->registerInXPlane();
869 return 0;
870 } catch (...) {
871 Connection::get(*buffer).handleException();
872 return -1;
873 }
874}
875
876/*----------------------------------------------------------------------------*/
877
878extern "C" int xplra_multi_unregister(int bufferID)
879{
880 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
881 if (buffer==0) return -1;
882 try {
883 buffer->unregisterFromXPlane();
884 return 0;
885 } catch (...) {
886 Connection::get(*buffer).handleException();
887 return -1;
888 }
889}
890
891/*----------------------------------------------------------------------------*/
892
893extern "C" int xplra_multi_unregister_safely(int bufferID)
894{
895 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
896 return (buffer==0) ? -1 : (buffer->unregisterSafelyFromXPlane() ? 1 : 0);
897}
898
899/*----------------------------------------------------------------------------*/
900
901extern "C" int xplra_multi_execute(int bufferID)
902{
903 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
904 if (buffer==0) return -1;
905 try {
906 buffer->execute();
907 return 0;
908 } catch (...) {
909 Connection::get(*buffer).handleException();
910 return -1;
911 }
912}
913
914//------------------------------------------------------------------------------
915
916extern "C" int xplra_multi_set_int(int bufferID, size_t datarefID, int value)
917{
918 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
919 if (buffer==0) return -1;
920 try {
921 buffer->setInt(datarefID, value);
922 return 0;
923 } catch (...) {
924 Connection::get(*buffer).handleException();
925 return -1;
926 }
927}
928
929/*----------------------------------------------------------------------------*/
930
931extern "C" int xplra_multi_get_int(int* dest, int bufferID, size_t datarefID)
932{
933 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
934 if (buffer==0) return -1;
935 try {
936 *dest = buffer->getInt(datarefID);
937 return 0;
938 } catch (...) {
939 Connection::get(*buffer).handleException();
940 return -1;
941 }
942}
943
944/*----------------------------------------------------------------------------*/
945
946extern "C"
947const int32_t* xplra_multi_get_int_const_ptr(int bufferID, size_t datarefID)
948{
949 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
950 if (buffer==0) return 0;
951 try {
952 return &(buffer->getIntRef(datarefID));
953 } catch (...) {
954 Connection::get(*buffer).handleException();
955 return 0;
956 }
957}
958
959/*----------------------------------------------------------------------------*/
960
961extern "C"
962int32_t* xplra_multi_get_int_ptr(int bufferID, size_t datarefID)
963{
964 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
965 if (buffer==0) return 0;
966 try {
967 return &(buffer->getIntRef(datarefID));
968 } catch (...) {
969 Connection::get(*buffer).handleException();
970 return 0;
971 }
972}
973
974//------------------------------------------------------------------------------
975
976extern "C"
977int xplra_multi_set_float(int bufferID, size_t datarefID, float value)
978{
979 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
980 if (buffer==0) return -1;
981 try {
982 buffer->setFloat(datarefID, value);
983 return 0;
984 } catch (...) {
985 Connection::get(*buffer).handleException();
986 return -1;
987 }
988}
989
990/*----------------------------------------------------------------------------*/
991
992extern "C"
993int xplra_multi_get_float(float* dest, int bufferID, size_t datarefID)
994{
995 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
996 if (buffer==0) return -1;
997 try {
998 *dest = buffer->getFloat(datarefID);
999 return 0;
1000 } catch (...) {
1001 Connection::get(*buffer).handleException();
1002 return -1;
1003 }
1004}
1005
1006/*----------------------------------------------------------------------------*/
1007
1008extern "C"
1009const float* xplra_multi_get_float_const_ptr(int bufferID, size_t datarefID)
1010{
1011 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1012 if (buffer==0) return 0;
1013 try {
1014 return &(buffer->getFloatRef(datarefID));
1015 } catch (...) {
1016 Connection::get(*buffer).handleException();
1017 return 0;
1018 }
1019}
1020
1021/*----------------------------------------------------------------------------*/
1022
1023extern "C"
1024float* xplra_multi_get_float_ptr(int bufferID, size_t datarefID)
1025{
1026 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1027 if (buffer==0) return 0;
1028 try {
1029 return &(buffer->getFloatRef(datarefID));
1030 } catch (...) {
1031 Connection::get(*buffer).handleException();
1032 return 0;
1033 }
1034}
1035
1036//------------------------------------------------------------------------------
1037
1038extern "C"
1039int xplra_multi_set_double(int bufferID, size_t datarefID, double value)
1040{
1041 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1042 if (buffer==0) return -1;
1043 try {
1044 buffer->setDouble(datarefID, value);
1045 return 0;
1046 } catch (...) {
1047 Connection::get(*buffer).handleException();
1048 return -1;
1049 }
1050}
1051
1052/*----------------------------------------------------------------------------*/
1053
1054extern "C"
1055int xplra_multi_get_double(double* dest, int bufferID, size_t datarefID)
1056{
1057 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1058 if (buffer==0) return -1;
1059 try {
1060 *dest = buffer->getDouble(datarefID);
1061 return 0;
1062 } catch (...) {
1063 Connection::get(*buffer).handleException();
1064 return -1;
1065 }
1066}
1067
1068/*----------------------------------------------------------------------------*/
1069
1070extern "C"
1071const double* xplra_multi_get_double_const_ptr(int bufferID, size_t datarefID)
1072{
1073 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1074 if (buffer==0) return 0;
1075 try {
1076 return &(buffer->getDoubleRef(datarefID));
1077 } catch (...) {
1078 Connection::get(*buffer).handleException();
1079 return 0;
1080 }
1081}
1082
1083/*----------------------------------------------------------------------------*/
1084
1085extern "C"
1086double* xplra_multi_get_double_ptr(int bufferID, size_t datarefID)
1087{
1088 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1089 if (buffer==0) return 0;
1090 try {
1091 return &(buffer->getDoubleRef(datarefID));
1092 } catch (...) {
1093 Connection::get(*buffer).handleException();
1094 return 0;
1095 }
1096}
1097
1098//------------------------------------------------------------------------------
1099
1100extern "C"
1101ssize_t xplra_multi_set_float_array(int bufferID, size_t datarefID,
1102 const float* value, size_t length,
1103 size_t offset)
1104{
1105 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1106 if (buffer==0) return -1;
1107 try {
1108 return buffer->setFloatArray(datarefID, value, length, offset);
1109 } catch (...) {
1110 Connection::get(*buffer).handleException();
1111 return -1;
1112 }
1113}
1114
1115/*----------------------------------------------------------------------------*/
1116
1117extern "C"
1118ssize_t xplra_multi_get_float_array(float* value,
1119 size_t length, size_t offset,
1120 int bufferID, size_t datarefID)
1121{
1122 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1123 if (buffer==0) return -1;
1124 try {
1125 return buffer->getFloatArray(datarefID, value, length, offset);
1126 } catch (...) {
1127 Connection::get(*buffer).handleException();
1128 return -1;
1129 }
1130}
1131
1132/*----------------------------------------------------------------------------*/
1133
1134extern "C"
1135const float* xplra_multi_get_float_array_ptr(int bufferID, size_t datarefID,
1136 size_t offset)
1137{
1138 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1139 if (buffer==0) return 0;
1140 try {
1141 return buffer->getFloatArray(datarefID, offset);
1142 } catch (...) {
1143 Connection::get(*buffer).handleException();
1144 return 0;
1145 }
1146}
1147
1148//------------------------------------------------------------------------------
1149
1150extern "C"
1151ssize_t xplra_multi_set_int_array(int bufferID, size_t datarefID,
1152 const int32_t* value, size_t length,
1153 size_t offset)
1154{
1155 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1156 if (buffer==0) return -1;
1157 try {
1158 return buffer->setIntArray(datarefID, value, length, offset);
1159 } catch (...) {
1160 Connection::get(*buffer).handleException();
1161 return -1;
1162 }
1163}
1164
1165/*----------------------------------------------------------------------------*/
1166
1167extern "C"
1168ssize_t xplra_multi_get_int_array(int32_t* value,
1169 size_t length, size_t offset,
1170 int bufferID, size_t datarefID)
1171{
1172 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1173 if (buffer==0) return -1;
1174 try {
1175 return buffer->getIntArray(datarefID, value, length, offset);
1176 } catch (...) {
1177 Connection::get(*buffer).handleException();
1178 return -1;
1179 }
1180}
1181
1182/*----------------------------------------------------------------------------*/
1183
1184extern "C"
1185const int32_t* xplra_multi_get_int_array_ptr(int bufferID, size_t datarefID,
1186 size_t offset)
1187{
1188 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1189 if (buffer==0) return 0;
1190 try {
1191 return buffer->getIntArray(datarefID, offset);
1192 } catch (...) {
1193 Connection::get(*buffer).handleException();
1194 return 0;
1195 }
1196}
1197
1198//------------------------------------------------------------------------------
1199
1200extern "C"
1201ssize_t xplra_multi_set_byte_array(int bufferID, size_t datarefID,
1202 const void* value, size_t length,
1203 size_t offset)
1204{
1205 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1206 if (buffer==0) return -1;
1207 try {
1208 return buffer->setByteArray(datarefID,
1209 reinterpret_cast<const uint8_t*>(value),
1210 length, offset);
1211 } catch (...) {
1212 Connection::get(*buffer).handleException();
1213 return -1;
1214 }
1215}
1216
1217/*----------------------------------------------------------------------------*/
1218
1219extern "C"
1220ssize_t xplra_multi_get_byte_array(void* value,
1221 size_t length, size_t offset,
1222 int bufferID, size_t datarefID)
1223{
1224 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1225 if (buffer==0) return -1;
1226 try {
1227 return buffer->getByteArray(datarefID,
1228 reinterpret_cast<uint8_t*>(value),
1229 length, offset);
1230 } catch (...) {
1231 Connection::get(*buffer).handleException();
1232 return -1;
1233 }
1234}
1235
1236/*----------------------------------------------------------------------------*/
1237
1238extern "C"
1239const uint8_t* xplra_multi_get_byte_array_ptr(int bufferID, size_t datarefID,
1240 size_t offset)
1241{
1242 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1243 if (buffer==0) return 0;
1244 try {
1245 return buffer->getByteArray(datarefID, offset);
1246 } catch (...) {
1247 Connection::get(*buffer).handleException();
1248 return 0;
1249 }
1250}
1251
1252//------------------------------------------------------------------------------
1253
1254extern "C" ssize_t xplra_multi_set_string(int bufferID, size_t datarefID,
1255 const char* value, size_t offset)
1256{
1257 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1258 if (buffer==0) return -1;
1259 try {
1260 return buffer->setString(datarefID, value, offset);
1261 } catch (...) {
1262 Connection::get(*buffer).handleException();
1263 return -1;
1264 }
1265}
1266
1267/*----------------------------------------------------------------------------*/
1268
1269extern "C"
1270const char* xplra_multi_get_string_ptr(int bufferID, size_t datarefID,
1271 size_t offset)
1272{
1273 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1274 if (buffer==0) return 0;
1275 try {
1276 return buffer->getStringPtr(datarefID, offset);
1277 } catch (...) {
1278 Connection::get(*buffer).handleException();
1279 return 0;
1280 }
1281}
1282
1283//------------------------------------------------------------------------------
1284
1285extern "C" int xplra_multi_destroy_buffer(int connectionID, int bufferID)
1286{
1287 Connection* connection = ConnectionSlot::getValue(connectionID);
1288 if (connection==0) return -1;
1289
1290 try {
1291 return connection->destroyMultiBuffer(bufferID) ? 0 : -1;
1292 } catch(...) {
1293 connection->handleException();
1294 return -1;
1295 }
1296}
1297
1298//------------------------------------------------------------------------------
1299//------------------------------------------------------------------------------
1300
1301extern "C" int xplra_show_message(int connectionID,
1302 const char* message, float duration)
1303{
1304 Connection* connection = ConnectionSlot::getValue(connectionID);
1305 if (connection==0) return -1;
1306
1307 try {
1308 connection->showMessage(message, duration);
1309 return 0;
1310 } catch(...) {
1311 connection->handleException();
1312 return -1;
1313 }
1314}
1315
1316//------------------------------------------------------------------------------
1317//------------------------------------------------------------------------------
1318
1319extern "C" int xplra_register_hotkeys(int connectionID,
1320 const uint16_t* codes, size_t length)
1321{
1322 Connection* connection = ConnectionSlot::getValue(connectionID);
1323 if (connection==0) return -1;
1324
1325 try {
1326 connection->registerHotkeys(codes, length);
1327 return 0;
1328 } catch(...) {
1329 connection->handleException();
1330 return -1;
1331 }
1332}
1333
1334/*----------------------------------------------------------------------------*/
1335
1336extern "C" int xplra_query_hotkeys(int connectionID,
1337 uint8_t* states, size_t length)
1338{
1339 Connection* connection = ConnectionSlot::getValue(connectionID);
1340 if (connection==0) return -1;
1341
1342 try {
1343 connection->queryHotkeys(states, length);
1344 return 0;
1345 } catch(...) {
1346 connection->handleException();
1347 return -1;
1348 }
1349}
1350
1351/*----------------------------------------------------------------------------*/
1352
1353extern "C" int xplra_unregister_hotkeys(int connectionID)
1354{
1355 Connection* connection = ConnectionSlot::getValue(connectionID);
1356 if (connection==0) return -1;
1357
1358 try {
1359 connection->unregisterHotkeys();
1360 return 0;
1361 } catch(...) {
1362 connection->handleException();
1363 return -1;
1364 }
1365}
1366
1367//------------------------------------------------------------------------------
1368//------------------------------------------------------------------------------
1369
1370extern "C" int xplra_disconnect(int connectionID)
1371{
1372 Connection* connection = ConnectionSlot::getValue(connectionID);
1373 if (connection==0) return -1;
1374
1375 ConnectionSlot::clearValue(connectionID);
1376 connection->disconnect();
1377 delete connection;
1378
1379 return 0;
1380}
1381
1382//------------------------------------------------------------------------------
1383//------------------------------------------------------------------------------
1384
1385// Local Variables:
1386// mode: C++
1387// c-basic-offset: 4
1388// indent-tabs-mode: nil
1389// End:
Note: See TracBrowser for help on using the repository browser.