source: xplra/src/xplra/SetDataRefTask.h@ 7:bafe58db1509

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

Added support for setting values

File size: 19.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#ifndef XPLRA_SETDATAREFTASK_H
30#define XPLRA_SETDATAREFTASK_H
31//------------------------------------------------------------------------------
32
33#include "DataRefTask.h"
34
35#include <xplcommon/DataStream.h>
36
37//------------------------------------------------------------------------------
38
39namespace xplra {
40
41//------------------------------------------------------------------------------
42
43/**
44 * Base class for dataref tasks that set the value of some data
45 * referenced by a dataref.
46 *
47 * Since XPLM provides no feedback on whether the setting is
48 * successful, we detect only if the dataref is valid or not. So the
49 * isValid() function provides the only feedback if the task executed
50 * successfully or not. (We could use XPLMCanWriteDataRef, but for
51 * efficiency reasons we refrain from it. A separate task may be
52 * created for this purpose.)
53 */
54class SetDataRefTask : public DataRefTask
55{
56public:
57 /**
58 * Read a dataref setting specification and create the appropriate
59 * SetDataRefTask instance.
60 *
61 * @param result will contain the result of the operation. It
62 * signifies an error only, if some wrong data is read. If the
63 * stream fails, it will indicate RESULT_OK.
64 *
65 * @return the new instance or 0 on error.
66 */
67 static SetDataRefTask* create(uint8_t& result, xplcommon::DataStream& stream);
68
69 /**
70 * Construct the task for the dataref with the given name.
71 */
72 SetDataRefTask(const std::string& name);
73
74 /**
75 * Construct the task for the given dataref.
76 */
77 SetDataRefTask(XPLMDataRef dataRef);
78
79 /**
80 * Read and set the value to update from the given stream
81 */
82 virtual void readValue(xplcommon::DataStream& stream) = 0;
83};
84
85//------------------------------------------------------------------------------
86//------------------------------------------------------------------------------
87
88/**
89 * Base class for dataref setting tasks that set a single scalar
90 * value.
91 *
92 * ConcreteClass is the actual child class. It should have a function
93 * name setData() which performs the actual setting.
94 */
95template <typename T, class ConcreteClass>
96class SetScalarDataRefTask : public SetDataRefTask
97{
98protected:
99 /**
100 * The value to set.
101 */
102 T value;
103
104public:
105 /**
106 * Construct the task for setting the data referenced by the
107 * dataref with the given name.
108 */
109 SetScalarDataRefTask(const std::string& name, T value);
110
111 /**
112 * Construct the task for setting the data referenced by the given
113 * dataref.
114 */
115 SetScalarDataRefTask(XPLMDataRef dataRef, T value);
116
117protected:
118 /**
119 * Perform the actual operation.
120 */
121 virtual void process();
122};
123
124//------------------------------------------------------------------------------
125//------------------------------------------------------------------------------
126
127/**
128 * Task to set the value of an integer data.
129 */
130class SetIntDataRefTask :
131 public SetScalarDataRefTask<int, SetIntDataRefTask>
132{
133public:
134 /**
135 * Set the given dataref's value to the given value.
136 */
137 static void setData(XPLMDataRef dataRef, int value);
138
139 /**
140 * Construct the task for the dataref with the given name.
141 */
142 SetIntDataRefTask(const std::string& name, int value);
143
144 /**
145 * Construct the task for the given dataref.
146 */
147 SetIntDataRefTask(XPLMDataRef dataRef, int value);
148
149 /**
150 * Read and set the value to update from the given stream
151 */
152 virtual void readValue(xplcommon::DataStream& stream);
153};
154
155//------------------------------------------------------------------------------
156//------------------------------------------------------------------------------
157
158/**
159 * Task to set the value of a single-precision floating point data.
160 */
161class SetFloatDataRefTask :
162 public SetScalarDataRefTask<float, SetFloatDataRefTask>
163{
164public:
165 /**
166 * Set the given dataref's value to the given value.
167 */
168 static void setData(XPLMDataRef dataRef, float value);
169
170 /**
171 * Construct the task for the dataref with the given name.
172 */
173 SetFloatDataRefTask(const std::string& name, float value);
174
175 /**
176 * Construct the task for the given dataref.
177 */
178 SetFloatDataRefTask(XPLMDataRef dataRef, float value);
179
180 /**
181 * Read and set the value to update from the given stream
182 */
183 virtual void readValue(xplcommon::DataStream& stream);
184};
185
186//------------------------------------------------------------------------------
187//------------------------------------------------------------------------------
188
189/**
190 * Task to set the value of a double-precision floating point data.
191 */
192class SetDoubleDataRefTask :
193 public SetScalarDataRefTask<double, SetDoubleDataRefTask>
194{
195public:
196 /**
197 * Set the given dataref's value to the given value.
198 */
199 static void setData(XPLMDataRef dataRef, double value);
200
201 /**
202 * Construct the task for the dataref with the given name.
203 */
204 SetDoubleDataRefTask(const std::string& name, double value);
205
206 /**
207 * Construct the task for the given dataref.
208 */
209 SetDoubleDataRefTask(XPLMDataRef dataRef, double value);
210
211 /**
212 * Read and set the value to update from the given stream
213 */
214 virtual void readValue(xplcommon::DataStream& stream);
215};
216
217//------------------------------------------------------------------------------
218//------------------------------------------------------------------------------
219
220/**
221 * Base class for dataref setting tasks that set the values of an
222 * array.
223 *
224 * ConcreteClass is the actual child class. It should have a function
225 * name setData() which performs the actual setting.
226 */
227template <typename T, class ConcreteClass>
228class SetArrayDataRefTask : public SetDataRefTask
229{
230private:
231 /**
232 * The number of data items in the value.
233 */
234 int count;
235
236 /**
237 * The offset starting with which the data should be set.
238 */
239 int offset;
240
241 /**
242 * The value to set.
243 */
244 T* value;
245
246public:
247 /**
248 * Construct the data setting task for the dataref with the given
249 * name.
250 *
251 * The value array will be allocated, but not filled with
252 * data. Thus count should be positive!
253 */
254 SetArrayDataRefTask(const std::string& name, int count, int offset = 0);
255
256 /**
257 * Construct the data setting task for the given dataref.
258 *
259 * The value array will be allocated, but not filled with
260 * data. Thus count should be positive!
261 */
262 SetArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
263
264 /**
265 * Destroy the task.
266 */
267 virtual ~SetArrayDataRefTask();
268
269 /**
270 * Read and set the value to update from the given stream
271 */
272 virtual void readValue(xplcommon::DataStream& stream);
273
274protected:
275 /**
276 * Perform the actual operation.
277 */
278 virtual void process();
279};
280
281//------------------------------------------------------------------------------
282//------------------------------------------------------------------------------
283
284/**
285 * A dataref setting task which sets an array of integers.
286 */
287class SetIntArrayDataRefTask :
288 public SetArrayDataRefTask<int, SetIntArrayDataRefTask>
289{
290public:
291 /**
292 * Perform the actual setting.
293 */
294 static void setData(XPLMDataRef dataRef, int* value, int count, int offset);
295
296 /**
297 * Construct the task for the dataref with the given name.
298 */
299 SetIntArrayDataRefTask(const std::string& name, int count, int offset = 0);
300
301 /**
302 * Construct the task for the given dataref.
303 */
304 SetIntArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
305};
306
307//------------------------------------------------------------------------------
308//------------------------------------------------------------------------------
309
310/**
311 * A dataref setting task which sets an array of single-precision
312 * floating-point values.
313 */
314class SetFloatArrayDataRefTask :
315 public SetArrayDataRefTask<float, SetFloatArrayDataRefTask>
316{
317public:
318 /**
319 * Perform the actual setting.
320 */
321 static void setData(XPLMDataRef dataRef, float* value, int count, int offset);
322
323 /**
324 * Construct the task for the dataref with the given name.
325 */
326 SetFloatArrayDataRefTask(const std::string& name, int count, int offset = 0);
327
328 /**
329 * Construct the task for the given dataref.
330 */
331 SetFloatArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
332};
333
334//------------------------------------------------------------------------------
335//------------------------------------------------------------------------------
336
337/**
338 * A dataref setting task which sets an array of bytes.
339 */
340class SetByteArrayDataRefTask :
341 public SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>
342{
343public:
344 /**
345 * Perform the actual setting.
346 */
347 static void setData(XPLMDataRef dataRef, unsigned char* value,
348 int count, int offset);
349
350 /**
351 * Construct the task for the dataref with the given name.
352 */
353 SetByteArrayDataRefTask(const std::string& name, int count, int offset = 0);
354
355 /**
356 * Construct the task for the given dataref.
357 */
358 SetByteArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
359};
360
361//------------------------------------------------------------------------------
362// Template definitions
363//------------------------------------------------------------------------------
364
365template <typename T, class ConcreteClass>
366inline SetScalarDataRefTask<T, ConcreteClass>::
367SetScalarDataRefTask(const std::string& name, T value) :
368 SetDataRefTask(name),
369 value(value)
370{
371}
372
373//------------------------------------------------------------------------------
374
375template <typename T, class ConcreteClass>
376inline SetScalarDataRefTask<T, ConcreteClass>::
377SetScalarDataRefTask(XPLMDataRef dataRef, T value) :
378 SetDataRefTask(dataRef),
379 value(value)
380{
381}
382
383//------------------------------------------------------------------------------
384
385template <typename T, class ConcreteClass>
386void SetScalarDataRefTask<T, ConcreteClass>::process()
387{
388 ConcreteClass::setData(getDataRef(), value);
389}
390
391//------------------------------------------------------------------------------
392//------------------------------------------------------------------------------
393
394template <typename T, class ConcreteClass>
395inline SetArrayDataRefTask<T, ConcreteClass>::
396SetArrayDataRefTask(const std::string& name, int count, int offset) :
397 SetDataRefTask(name),
398 count(count),
399 offset(offset),
400 value(new T[count])
401{
402}
403
404//------------------------------------------------------------------------------
405
406template <typename T, class ConcreteClass>
407inline SetArrayDataRefTask<T, ConcreteClass>::
408SetArrayDataRefTask(XPLMDataRef dataRef, int count, int offset) :
409 SetDataRefTask(dataRef),
410 count(count),
411 offset(offset),
412 value(new T[count])
413{
414}
415
416//------------------------------------------------------------------------------
417
418template <typename T, class ConcreteClass>
419inline SetArrayDataRefTask<T, ConcreteClass>::~SetArrayDataRefTask()
420{
421 delete [] value;
422}
423
424//------------------------------------------------------------------------------
425
426template <typename T, class ConcreteClass>
427void SetArrayDataRefTask<T, ConcreteClass>::
428readValue(xplcommon::DataStream& stream)
429{
430 stream.read(value, count * sizeof(T));
431}
432
433//------------------------------------------------------------------------------
434
435template <typename T, class ConcreteClass>
436void SetArrayDataRefTask<T, ConcreteClass>::process()
437{
438 ConcreteClass::setData(getDataRef(), value, count, offset);
439}
440
441//------------------------------------------------------------------------------
442// Inline definitions
443//------------------------------------------------------------------------------
444
445inline SetDataRefTask::SetDataRefTask(const std::string& name) :
446 DataRefTask(name)
447{
448}
449
450//------------------------------------------------------------------------------
451
452inline SetDataRefTask::SetDataRefTask(XPLMDataRef dataRef) :
453 DataRefTask(dataRef)
454{
455}
456
457//------------------------------------------------------------------------------
458//------------------------------------------------------------------------------
459
460inline void SetIntDataRefTask::setData(XPLMDataRef dataRef, int value)
461{
462 XPLMSetDatai(dataRef, value);
463}
464
465//------------------------------------------------------------------------------
466
467inline SetIntDataRefTask::SetIntDataRefTask(const std::string& name, int value) :
468 SetScalarDataRefTask<int, SetIntDataRefTask>(name, value)
469{
470}
471
472//------------------------------------------------------------------------------
473
474inline SetIntDataRefTask::SetIntDataRefTask(XPLMDataRef dataRef, int value) :
475 SetScalarDataRefTask<int, SetIntDataRefTask>(dataRef, value)
476{
477}
478
479//------------------------------------------------------------------------------
480//------------------------------------------------------------------------------
481
482inline void SetFloatDataRefTask::setData(XPLMDataRef dataRef, float value)
483{
484 XPLMSetDatai(dataRef, value);
485}
486
487//------------------------------------------------------------------------------
488
489inline SetFloatDataRefTask::SetFloatDataRefTask(const std::string& name,
490 float value) :
491 SetScalarDataRefTask<float, SetFloatDataRefTask>(name, value)
492{
493}
494
495//------------------------------------------------------------------------------
496
497inline SetFloatDataRefTask::SetFloatDataRefTask(XPLMDataRef dataRef,
498 float value) :
499 SetScalarDataRefTask<float, SetFloatDataRefTask>(dataRef, value)
500{
501}
502
503//------------------------------------------------------------------------------
504//------------------------------------------------------------------------------
505
506inline void SetDoubleDataRefTask::setData(XPLMDataRef dataRef, double value)
507{
508 XPLMSetDatai(dataRef, value);
509}
510
511//------------------------------------------------------------------------------
512
513inline SetDoubleDataRefTask::SetDoubleDataRefTask(const std::string& name,
514 double value) :
515 SetScalarDataRefTask<double, SetDoubleDataRefTask>(name, value)
516{
517}
518
519//------------------------------------------------------------------------------
520
521inline SetDoubleDataRefTask::SetDoubleDataRefTask(XPLMDataRef dataRef,
522 double value) :
523 SetScalarDataRefTask<double, SetDoubleDataRefTask>(dataRef, value)
524{
525}
526
527//------------------------------------------------------------------------------
528//------------------------------------------------------------------------------
529
530inline void SetIntArrayDataRefTask::setData(XPLMDataRef dataRef, int* value,
531 int count, int offset)
532{
533 XPLMSetDatavi(dataRef, value, offset, count);
534}
535
536//------------------------------------------------------------------------------
537
538inline SetIntArrayDataRefTask::SetIntArrayDataRefTask(const std::string& name,
539 int count, int offset) :
540 SetArrayDataRefTask<int, SetIntArrayDataRefTask>(name, count, offset)
541{
542}
543
544//------------------------------------------------------------------------------
545
546inline SetIntArrayDataRefTask::SetIntArrayDataRefTask(XPLMDataRef dataRef,
547 int count, int offset) :
548 SetArrayDataRefTask<int, SetIntArrayDataRefTask>(dataRef, count, offset)
549{
550}
551
552//------------------------------------------------------------------------------
553//------------------------------------------------------------------------------
554
555inline void SetFloatArrayDataRefTask::setData(XPLMDataRef dataRef,
556 float* value,
557 int count, int offset)
558{
559 XPLMSetDatavf(dataRef, value, offset, count);
560}
561
562//------------------------------------------------------------------------------
563
564inline
565SetFloatArrayDataRefTask::SetFloatArrayDataRefTask(const std::string& name,
566 int count, int offset) :
567 SetArrayDataRefTask<float, SetFloatArrayDataRefTask>(name, count, offset)
568{
569}
570
571//------------------------------------------------------------------------------
572
573inline
574SetFloatArrayDataRefTask::SetFloatArrayDataRefTask(XPLMDataRef dataRef,
575 int count, int offset) :
576 SetArrayDataRefTask<float, SetFloatArrayDataRefTask>(dataRef, count, offset)
577{
578}
579
580//------------------------------------------------------------------------------
581//------------------------------------------------------------------------------
582
583inline void SetByteArrayDataRefTask::setData(XPLMDataRef dataRef,
584 unsigned char* value,
585 int count, int offset)
586{
587 XPLMSetDatab(dataRef, value, offset, count);
588}
589
590//------------------------------------------------------------------------------
591
592inline
593SetByteArrayDataRefTask::SetByteArrayDataRefTask(const std::string& name,
594 int count, int offset) :
595 SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>(name,
596 count, offset)
597{
598}
599
600//------------------------------------------------------------------------------
601
602inline
603SetByteArrayDataRefTask::SetByteArrayDataRefTask(XPLMDataRef dataRef,
604 int count, int offset) :
605 SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>(dataRef,
606 count, offset)
607{
608}
609
610//------------------------------------------------------------------------------
611
612} /* namespace xplra */
613
614//------------------------------------------------------------------------------
615#endif // XPLRA_SETDATAREFTASK_H
616
617// Local Variables:
618// mode: C++
619// c-basic-offset: 4
620// indent-tabs-mode: nil
621// End:
Note: See TracBrowser for help on using the repository browser.