source: xplra/src/xplra/GetDataRefTask.h@ 6:8dd4ca9966d0

Last change on this file since 6:8dd4ca9966d0 was 6:8dd4ca9966d0, checked in by István Váradi <ivaradi@…>, 12 years ago

Made all the single query operation work for all types

File size: 21.9 KB
RevLine 
[3]1// Copyright (c) 2013 by István Váradi
2
3// This file is part of XPLRA, a remote-access plugin for X-Plane
4
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7
8// 1. Redistributions of source code must retain the above copyright notice, this
9// list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25// The views and conclusions contained in the software and documentation are those
26// of the authors and should not be interpreted as representing official policies,
27// either expressed or implied, of the FreeBSD Project.
28
29#ifndef XPLRA_GETDATAREFTASK_H
30#define XPLRA_GETDATAREFTASK_H
31//------------------------------------------------------------------------------
32
33#include "DataRefTask.h"
34
[6]35#include <xplcommon/DataStream.h>
36
[3]37//------------------------------------------------------------------------------
38
39namespace xplra {
40
41//------------------------------------------------------------------------------
42
43/**
[4]44 * Base class for tasks that query the value of some dataref.
[3]45 */
[4]46class GetDataRefTask : public DataRefTask
47{
48public:
49 /**
[6]50 * Read a dataref query specification and create the appropriate
51 * GetDataRefTask instance.
52 *
53 * @return the new instance, or 0 on error. In that case the given
54 * result reference variable will be filled with the error code,
55 * unless the stream failed, in which case it remains RESULT_OK.
56 */
57 static GetDataRefTask* create(uint8_t& result, xplcommon::DataStream& stream);
58
59 /**
[4]60 * Construct the task for the dataref with the given name.
61 */
62 GetDataRefTask(const std::string& name);
63
64 /**
65 * Construct the task for the given dataref.
66 */
67 GetDataRefTask(XPLMDataRef dataRef);
[6]68
69 /**
70 * Write the value into the given stream.
71 */
72 virtual void writeValue(xplcommon::DataStream& stream) = 0;
[4]73};
74
75//------------------------------------------------------------------------------
76
77/**
78 * Base class for dataref querying tasks that query some scalar value.
79 *
80 * ConcreteClass is the actual child class. It should have a function
81 * called queryData, which wraps the corresponding function in XPLM.
82 */
83template <typename T, class ConcreteClass>
84class GetScalarDataRefTask : public GetDataRefTask
[3]85{
86private:
87 /**
[4]88 * The value retrieved.
89 */
90 T value;
91
92public:
93 /**
94 * Construct the task for the dataref with the given name.
95 */
96 GetScalarDataRefTask(const std::string& name);
97
98 /**
99 * Construct the task for the given dataref.
100 */
101 GetScalarDataRefTask(XPLMDataRef dataRef);
102
103 /**
104 * Get the value
[3]105 */
[4]106 T getValue() const;
107
108protected:
109 /**
110 * Perform the actual operation.
111 */
112 virtual void process();
113};
114
115//------------------------------------------------------------------------------
116//------------------------------------------------------------------------------
117
118/**
119 * A dataref task which retrieves the value of an integer.
120 */
121class GetIntDataRefTask :
122 public GetScalarDataRefTask<int, GetIntDataRefTask>
123{
124public:
125 /**
126 * Query the value from XPLM
127 */
128 static int queryData(XPLMDataRef dataRef);
129
130 /**
131 * Construct the task for the dataref with the given name.
132 */
133 GetIntDataRefTask(const std::string& name);
[3]134
135 /**
[4]136 * Construct the task for the given dataref.
137 */
138 GetIntDataRefTask(XPLMDataRef dataRef);
[6]139
140 /**
141 * Write the value into the given stream.
142 */
143 virtual void writeValue(xplcommon::DataStream& stream);
[4]144};
145
146//------------------------------------------------------------------------------
147//------------------------------------------------------------------------------
148
149/**
150 * A dataref task which retrieves the value of a single-precision
151 * floating point data.
152 */
153class GetFloatDataRefTask :
154 public GetScalarDataRefTask<float, GetFloatDataRefTask>
155{
156public:
157 /**
158 * Query the value from XPLM
159 */
160 static float queryData(XPLMDataRef dataRef);
161
162 /**
163 * Construct the task for the dataref with the given name.
164 */
165 GetFloatDataRefTask(const std::string& name);
166
167 /**
168 * Construct the task for the given dataref.
169 */
170 GetFloatDataRefTask(XPLMDataRef dataRef);
[6]171
172 /**
173 * Write the value into the given stream.
174 */
175 virtual void writeValue(xplcommon::DataStream& stream);
[4]176};
177
178//------------------------------------------------------------------------------
179//------------------------------------------------------------------------------
180
181/**
182 * A dataref task which retrieves the value of a double-precision
183 * floating point data.
184 */
185class GetDoubleDataRefTask :
186 public GetScalarDataRefTask<double, GetDoubleDataRefTask>
187{
188public:
189 /**
190 * Query the value from XPLM
191 */
192 static double queryData(XPLMDataRef dataRef);
193
194 /**
195 * Construct the task for the dataref with the given name.
196 */
197 GetDoubleDataRefTask(const std::string& name);
198
199 /**
200 * Construct the task for the given dataref.
201 */
202 GetDoubleDataRefTask(XPLMDataRef dataRef);
[6]203
204 /**
205 * Write the value into the given stream.
206 */
207 virtual void writeValue(xplcommon::DataStream& stream);
[4]208};
209
210//------------------------------------------------------------------------------
211//------------------------------------------------------------------------------
212
213/**
214 * Base class for dataref querying tasks that query some array.
215 *
216 * ConcreteClass is the actual child class. It should have a function
217 * called queryData, which wraps the corresponding function in XPLM.
218 */
219template <typename T, class ConcreteClass>
220class GetArrayDataRefTask : public GetDataRefTask
221{
222private:
223 /**
224 * The maximal number of data items returned.
225 */
226 int maxCount;
227
228 /**
229 * The offset within the dataref's value to start the query from.
[3]230 */
231 int offset;
232
233 /**
[4]234 * The data.
[3]235 */
[4]236 T* data;
[3]237
238 /**
239 * The actual length of the data retrieved.
240 */
241 int length;
242
[4]243protected:
244 /**
245 * Construct the task for the dataref with the given name.
246 *
247 * @param maxCount the maximal number of items to retrieve. If <0,
248 * the function will perform an extra query to retrieve the size of
249 * of the dataref's data, which it will store in the task, so
250 * later on it can be reused.
251 */
252 GetArrayDataRefTask(const std::string& name,
253 int maxCount = -1, int offset = 0);
254
255 /**
256 * Construct the task for the given dataref
257 *
258 * @param maxCount the maximal number of items to retrieve. If <0,
259 * the function will perform an extra query to retrieve the size
260 * of the dataref's data, which it will store in the task, so
261 * later on it can be reused.
262 */
263 GetArrayDataRefTask(XPLMDataRef dataRef,
264 int maxCount = -1, int offset = 0);
265
266public:
267 /**
268 * Destroy the object.
269 */
270 virtual ~GetArrayDataRefTask();
271
272 /**
273 * Get the data.
274 */
275 const T* getData() const;
276
277 /**
278 * Get the length of the data.
279 */
280 int getLength() const;
281
282protected:
283 /**
284 * Process the dataref by querying its value.
285 */
286 virtual void process();
[6]287
288 /**
289 * Write the value into the given stream.
290 */
291 virtual void writeValue(xplcommon::DataStream& stream);
[4]292};
293
294//------------------------------------------------------------------------------
295//------------------------------------------------------------------------------
296
297/**
298 * A dataref task which retrieves the value of a float array.
299 */
300class GetFloatArrayDataRefTask :
301 public GetArrayDataRefTask<float, GetFloatArrayDataRefTask>
302{
303public:
304 /**
305 * Get the data via XPLM
306 */
307 static int queryData(XPLMDataRef dataRef, float* dest,
308 int offset, int count);
309
310public:
311 /**
312 * Construct the task for the dataref with the given name.
313 *
314 * @param maxCount the maximal number of data items to
315 * retrieve. If <0, the function will perform an extra query to
316 * retrieve the size of the dataref's data, which it will store in
317 * the task, so later on it can be reused.
318 */
319 GetFloatArrayDataRefTask(const std::string& name,
320 int maxCount = -1, int offset = 0);
321
322 /**
323 * Construct the task for the given dataref
324 *
325 * @param maxBytes the maximal number of data items to
326 * retrieve. If <0, the function will perform an extra query to
327 * retrieve the size of the dataref's data, which it will store in
328 * the task, so later on it can be reused.
329 */
330 GetFloatArrayDataRefTask(XPLMDataRef dataRef,
331 int maxCount = -1, int offset = 0);
332};
333
334//------------------------------------------------------------------------------
335//------------------------------------------------------------------------------
336
337/**
338 * A dataref task which retrieves the value of an integer array.
339 */
340class GetIntArrayDataRefTask :
341 public GetArrayDataRefTask<int, GetIntArrayDataRefTask>
342{
343public:
344 /**
345 * Get the data via XPLM
346 */
347 static int queryData(XPLMDataRef dataRef, int* dest,
348 int offset, int count);
349
350public:
351 /**
352 * Construct the task for the dataref with the given name.
353 *
354 * @param maxCount the maximal number of data items to
355 * retrieve. If <0, the function will perform an extra query to
356 * retrieve the size of the dataref's data, which it will store in
357 * the task, so later on it can be reused.
358 */
359 GetIntArrayDataRefTask(const std::string& name,
360 int maxCount = -1, int offset = 0);
361
362 /**
363 * Construct the task for the given dataref
364 *
365 * @param maxBytes the maximal number of data items to
366 * retrieve. If <0, the function will perform an extra query to
367 * retrieve the size of the dataref's data, which it will store in
368 * the task, so later on it can be reused.
369 */
370 GetIntArrayDataRefTask(XPLMDataRef dataRef,
371 int maxCount = -1, int offset = 0);
372};
373
374//------------------------------------------------------------------------------
375//------------------------------------------------------------------------------
376
377/**
378 * A dataref task which retrieves the value of a byte array.
379 */
380class GetByteArrayDataRefTask :
381 public GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>
382{
383public:
384 /**
385 * Get the data via XPLM
386 */
387 static int queryData(XPLMDataRef dataRef, void* dest,
388 int offset, int count);
389
[3]390public:
391 /**
392 * Construct the task for the dataref with the given name.
393 *
394 * @param maxBytes the maximal number of bytes to retrieve. If <0,
395 * the function will perform an extra query to retrieve the size
396 * of the dataref's data, which it will store in the task, so
397 * later on it can be reused.
398 */
399 GetByteArrayDataRefTask(const std::string& name,
400 int maxBytes = -1, int offset = 0);
401
402 /**
403 * Construct the task for the given dataref
404 *
405 * @param maxBytes the maximal number of bytes to retrieve. If <0,
406 * the function will perform an extra query to retrieve the size
407 * of the dataref's data, which it will store in the task, so
408 * later on it can be reused.
409 */
410 GetByteArrayDataRefTask(XPLMDataRef dataRef,
411 int maxBytes = -1, int offset = 0);
412};
413
414//------------------------------------------------------------------------------
[4]415// Template definitions
416//------------------------------------------------------------------------------
417
418template <typename T, class ConcreteClass>
419inline GetScalarDataRefTask<T, ConcreteClass>::
420GetScalarDataRefTask(const std::string& name) :
421 GetDataRefTask(name),
422 value(0)
423{
424}
425
426//------------------------------------------------------------------------------
427
428template <typename T, class ConcreteClass>
429inline GetScalarDataRefTask<T, ConcreteClass>::
430GetScalarDataRefTask(XPLMDataRef dataRef) :
431 GetDataRefTask(dataRef),
432 value(0)
433{
434}
435
436//------------------------------------------------------------------------------
437
438template <typename T, class ConcreteClass>
439inline T GetScalarDataRefTask<T, ConcreteClass>::getValue() const
440{
441 return value;
442}
443
[3]444//------------------------------------------------------------------------------
445
[4]446template <typename T, class ConcreteClass>
447void GetScalarDataRefTask<T, ConcreteClass>::process()
448{
449 value = ConcreteClass::queryData(getDataRef());
450}
451
452//------------------------------------------------------------------------------
453//------------------------------------------------------------------------------
454
455template <typename T, class ConcreteClass>
456inline GetArrayDataRefTask<T, ConcreteClass>::
457GetArrayDataRefTask(const std::string& name, int maxCount, int offset) :
458 GetDataRefTask(name),
459 maxCount(maxCount),
460 offset(offset),
461 data( (maxCount>0) ? new T[maxCount] : 0 ),
462 length(-1)
463{
464}
465
466//------------------------------------------------------------------------------
467
468template <typename T, class ConcreteClass>
469inline GetArrayDataRefTask<T, ConcreteClass>::
470GetArrayDataRefTask(XPLMDataRef dataRef, int maxCount, int offset) :
471 GetDataRefTask(dataRef),
472 maxCount(maxCount),
473 offset(offset),
474 data( (maxCount>0) ? new T[maxCount] : 0),
475 length(-1)
476{
477}
478
479//------------------------------------------------------------------------------
480
481template <typename T, class ConcreteClass>
482inline GetArrayDataRefTask<T, ConcreteClass>::~GetArrayDataRefTask()
483{
484 delete [] data;
485}
486
487//------------------------------------------------------------------------------
488
489template <typename T, class ConcreteClass>
490inline const T* GetArrayDataRefTask<T, ConcreteClass>::getData() const
[3]491{
492 return data;
493}
494
495//------------------------------------------------------------------------------
496
[4]497template <typename T, class ConcreteClass>
498inline int GetArrayDataRefTask<T, ConcreteClass>::getLength() const
[3]499{
500 return length;
501}
502
503//------------------------------------------------------------------------------
504
[4]505template <typename T, class ConcreteClass>
506void GetArrayDataRefTask<T, ConcreteClass>::process()
507{
508 if (maxCount<0) {
509 maxCount = ConcreteClass::queryData(getDataRef(), 0, 0, 0);
510
511 if (maxCount>0) {
512 maxCount -= offset;
513 }
514
515 if (maxCount>0) {
516 data = new T[maxCount];
517 } else {
518 maxCount = 0;
519 }
520 }
521
522 // Util::debug("GetByteArrayDataRefTask::process: dataRef=%p, maxBytes=%d, data=%p, offset\n",
523 // getDataRef(), maxBytes, data, offset);
524 if (maxCount>0) {
525 length = ConcreteClass::queryData(getDataRef(), data, offset, maxCount);
526 } else {
527 length = maxCount;
528 }
529}
530
531//------------------------------------------------------------------------------
[6]532
533template <typename T, class ConcreteClass>
534void GetArrayDataRefTask<T, ConcreteClass>::
535writeValue(xplcommon::DataStream& stream)
536{
537 stream.writeS32(length);
538 if (length>0) {
539 stream.write(data, length * sizeof(T));
540 }
541}
542
543//------------------------------------------------------------------------------
[4]544// Inline definitions
545//------------------------------------------------------------------------------
546
547inline GetDataRefTask::GetDataRefTask(const std::string& name) :
548 DataRefTask(name)
549{
550}
551
552//------------------------------------------------------------------------------
553
554inline GetDataRefTask::GetDataRefTask(XPLMDataRef dataRef) :
555 DataRefTask(dataRef)
556{
557}
558
559//------------------------------------------------------------------------------
560//------------------------------------------------------------------------------
561
562inline int GetIntDataRefTask::queryData(XPLMDataRef dataRef)
563{
564 return XPLMGetDatai(dataRef);
565}
566
567//------------------------------------------------------------------------------
568
569inline GetIntDataRefTask::GetIntDataRefTask(const std::string& name) :
570 GetScalarDataRefTask<int, GetIntDataRefTask>(name)
571{
572}
573
574//------------------------------------------------------------------------------
575
576inline GetIntDataRefTask::GetIntDataRefTask(XPLMDataRef dataRef) :
577 GetScalarDataRefTask<int, GetIntDataRefTask>(dataRef)
578{
579}
580
581//------------------------------------------------------------------------------
582//------------------------------------------------------------------------------
583
584inline float GetFloatDataRefTask::queryData(XPLMDataRef dataRef)
585{
586 return XPLMGetDataf(dataRef);
587}
588
589//------------------------------------------------------------------------------
590
591inline GetFloatDataRefTask::GetFloatDataRefTask(const std::string& name) :
592 GetScalarDataRefTask<float, GetFloatDataRefTask>(name)
593{
594}
595
596//------------------------------------------------------------------------------
597
598inline GetFloatDataRefTask::GetFloatDataRefTask(XPLMDataRef dataRef) :
599 GetScalarDataRefTask<float, GetFloatDataRefTask>(dataRef)
600{
601}
602
603//------------------------------------------------------------------------------
604//------------------------------------------------------------------------------
605
606inline double GetDoubleDataRefTask::queryData(XPLMDataRef dataRef)
607{
608 return XPLMGetDatad(dataRef);
609}
610
611//------------------------------------------------------------------------------
612
613inline GetDoubleDataRefTask::GetDoubleDataRefTask(const std::string& name) :
614 GetScalarDataRefTask<double, GetDoubleDataRefTask>(name)
615{
616}
617
618//------------------------------------------------------------------------------
619
620inline GetDoubleDataRefTask::GetDoubleDataRefTask(XPLMDataRef dataRef) :
621 GetScalarDataRefTask<double, GetDoubleDataRefTask>(dataRef)
622{
623}
624
625//------------------------------------------------------------------------------
626//------------------------------------------------------------------------------
627
628inline int GetFloatArrayDataRefTask::queryData(XPLMDataRef dataRef, float* dest,
629 int offset, int count)
630{
631 return XPLMGetDatavf(dataRef, dest, offset, count);
632}
633
634//------------------------------------------------------------------------------
635
636inline
637GetFloatArrayDataRefTask::GetFloatArrayDataRefTask(const std::string& name,
638 int maxCount, int offset) :
639 GetArrayDataRefTask<float, GetFloatArrayDataRefTask>(name, maxCount, offset)
640{
641}
642
643//------------------------------------------------------------------------------
644
645inline
646GetFloatArrayDataRefTask::GetFloatArrayDataRefTask(XPLMDataRef dataRef,
647 int maxCount, int offset) :
648 GetArrayDataRefTask<float, GetFloatArrayDataRefTask>(dataRef,
649 maxCount, offset)
650{
651}
652
653//------------------------------------------------------------------------------
654//------------------------------------------------------------------------------
655
656inline int GetIntArrayDataRefTask::queryData(XPLMDataRef dataRef, int* dest,
657 int offset, int count)
658{
659 return XPLMGetDatavi(dataRef, dest, offset, count);
660}
661
662//------------------------------------------------------------------------------
663
664inline
665GetIntArrayDataRefTask::GetIntArrayDataRefTask(const std::string& name,
666 int maxCount, int offset) :
667 GetArrayDataRefTask<int, GetIntArrayDataRefTask>(name, maxCount, offset)
668{
669}
670
671//------------------------------------------------------------------------------
672
673inline
674GetIntArrayDataRefTask::GetIntArrayDataRefTask(XPLMDataRef dataRef,
675 int maxCount, int offset) :
676 GetArrayDataRefTask<int, GetIntArrayDataRefTask>(dataRef,
677 maxCount, offset)
678{
679}
680
681//------------------------------------------------------------------------------
682//------------------------------------------------------------------------------
683
684inline int GetByteArrayDataRefTask::queryData(XPLMDataRef dataRef, void* dest,
685 int offset, int count)
686{
687 return XPLMGetDatab(dataRef, dest, offset, count);
688}
689
690//------------------------------------------------------------------------------
691
692inline
693GetByteArrayDataRefTask::GetByteArrayDataRefTask(const std::string& name,
694 int maxBytes, int offset) :
695 GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>(name, maxBytes,
696 offset)
697{
698}
699
700//------------------------------------------------------------------------------
701
702inline
703GetByteArrayDataRefTask::GetByteArrayDataRefTask(XPLMDataRef dataRef,
704 int maxBytes, int offset) :
705 GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>(dataRef,
706 maxBytes,
707 offset)
708{
709}
710
711//------------------------------------------------------------------------------
712
[3]713} /* namespace xplra */
714
715//------------------------------------------------------------------------------
716#endif // XPLRA_GETDATAREFTASK_H
717
718// Local Variables:
719// mode: C++
720// c-basic-offset: 4
721// indent-tabs-mode: nil
722// End:
Note: See TracBrowser for help on using the repository browser.