]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAArrayDataElement.hxx
Windows versionhelpers.h support.
[simgear.git] / simgear / hla / HLAArrayDataElement.hxx
1 // Copyright (C) 2009 - 2012  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifndef HLAArrayDataElement_hxx
19 #define HLAArrayDataElement_hxx
20
21 #include <string>
22 #include <vector>
23 #include <simgear/math/SGMath.hxx>
24 #include "HLAArrayDataType.hxx"
25 #include "HLADataElement.hxx"
26 #include "HLAVariantRecordDataElement.hxx"
27 #include "HLADataTypeVisitor.hxx"
28
29 namespace simgear {
30
31 class HLAAbstractArrayDataElement : public HLADataElement {
32 public:
33     HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
34     virtual ~HLAAbstractArrayDataElement();
35
36     virtual void accept(HLADataElementVisitor& visitor);
37     virtual void accept(HLAConstDataElementVisitor& visitor) const;
38
39     virtual bool decode(HLADecodeStream& stream);
40     virtual bool encode(HLAEncodeStream& stream) const;
41
42     virtual const HLAArrayDataType* getDataType() const;
43     virtual bool setDataType(const HLADataType* dataType);
44
45     const HLADataType* getElementDataType() const;
46
47     virtual bool setNumElements(unsigned count) = 0;
48     virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
49
50     virtual unsigned getNumElements() const = 0;
51     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
52
53 protected:
54     SGSharedPtr<const HLAArrayDataType> _dataType;
55 };
56
57 class HLAArrayDataElement : public HLAAbstractArrayDataElement {
58 public:
59     HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
60     virtual ~HLAArrayDataElement();
61
62     virtual bool setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement);
63     virtual HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end);
64     virtual const HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const;
65
66     virtual bool setDataType(const HLADataType* dataType);
67
68     virtual bool setNumElements(unsigned size);
69     virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
70     virtual unsigned getNumElements() const;
71     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
72
73     const HLADataElement* getElement(unsigned index) const;
74     HLADataElement* getElement(unsigned index);
75     HLADataElement* getOrCreateElement(unsigned index);
76     void setElement(unsigned i, HLADataElement* value);
77
78     class DataElementFactory : public SGReferenced {
79     public:
80         virtual ~DataElementFactory();
81         virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
82     };
83
84     void setDataElementFactory(DataElementFactory* dataElementFactory);
85     DataElementFactory* getDataElementFactory();
86
87 protected:
88     virtual void _setStamp(Stamp* stamp);
89
90 private:
91     HLADataElement* newElement(unsigned index);
92
93     typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
94     ElementVector _elementVector;
95
96     SGSharedPtr<DataElementFactory> _dataElementFactory;
97 };
98
99 // Holds an array of variants.
100 // Factors out common code for that use case.
101 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
102 public:
103     HLAVariantArrayDataElement();
104     virtual ~HLAVariantArrayDataElement();
105
106     // Overwrite this from the abstract class, need some more checks here
107     virtual bool setDataType(const HLADataType* dataType);
108
109     virtual bool setNumElements(unsigned size);
110     virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
111     virtual unsigned getNumElements() const;
112     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
113
114     const HLAVariantRecordDataElement* getElement(unsigned index) const;
115     HLAVariantRecordDataElement* getElement(unsigned index);
116     HLAVariantRecordDataElement* getOrCreateElement(unsigned index);
117     void setElement(unsigned index, HLAVariantRecordDataElement* value);
118
119     typedef HLAVariantRecordDataElement::DataElementFactory AlternativeDataElementFactory;
120
121     void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
122     AlternativeDataElementFactory* getAlternativeDataElementFactory();
123
124 protected:
125     virtual void _setStamp(Stamp* stamp);
126
127 private:
128     HLAVariantRecordDataElement* newElement();
129
130     typedef std::vector<SGSharedPtr<HLAVariantRecordDataElement> > ElementVector;
131     ElementVector _elementVector;
132
133     SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
134 };
135
136 class HLAStringDataElement : public HLAAbstractArrayDataElement {
137 public:
138     HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
139         HLAAbstractArrayDataElement(dataType)
140     {}
141     HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
142         HLAAbstractArrayDataElement(dataType),
143         _value(value)
144     {}
145     const std::string& getValue() const
146     { return _value; }
147     void setValue(const std::string& value)
148     { _value = value; setDirty(true); }
149
150     virtual bool setNumElements(unsigned count)
151     {
152         _value.resize(count);
153         return true;
154     }
155     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
156     {
157         HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
158         getElementDataType()->accept(visitor);
159         _value[i] = visitor.getValue();
160         return true;
161     }
162
163     virtual unsigned getNumElements() const
164     {
165         return _value.size();
166     }
167     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
168     {
169         HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
170         getElementDataType()->accept(visitor);
171         return true;
172     }
173
174 private:
175     std::string _value;
176 };
177
178 class HLAStringData {
179 public:
180     HLAStringData() :
181         _value(new HLAStringDataElement(0))
182     { }
183     HLAStringData(const std::string& value) :
184         _value(new HLAStringDataElement(0))
185     { _value->setValue(value); }
186
187     operator const std::string&() const
188     { return _value->getValue(); }
189     HLAStringData& operator=(const std::string& value)
190     { _value->setValue(value); return *this; }
191
192     const std::string& getValue() const
193     { return _value->getValue(); }
194     void setValue(const std::string& value)
195     { _value->setValue(value); }
196
197     const HLAStringDataElement* getDataElement() const
198     { return _value.get(); }
199     HLAStringDataElement* getDataElement()
200     { return _value.get(); }
201
202     const HLAArrayDataType* getDataType() const
203     { return _value->getDataType(); }
204     void setDataType(const HLAArrayDataType* dataType)
205     { _value->setDataType(dataType); }
206
207 private:
208     SGSharedPtr<HLAStringDataElement> _value;
209 };
210
211 template<typename T>
212 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
213 public:
214     HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
215         HLAAbstractArrayDataElement(dataType),
216         _value(SGVec2<T>::zeros())
217     {}
218     HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
219         HLAAbstractArrayDataElement(dataType),
220         _value(value)
221     {}
222     const SGVec2<T>& getValue() const
223     { return _value; }
224     void setValue(const SGVec2<T>& value)
225     { _value = value; setDirty(true); }
226
227     virtual bool setNumElements(unsigned count)
228     {
229         for (unsigned i = count; i < 2; ++i)
230             _value[i] = 0;
231         return true;
232     }
233     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
234     {
235         if (i < 2) {
236             HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
237             getElementDataType()->accept(visitor);
238             _value[i] = visitor.getValue();
239         } else {
240             HLADataTypeDecodeVisitor visitor(stream);
241             getElementDataType()->accept(visitor);
242         }
243         return true;
244     }
245
246     virtual unsigned getNumElements() const
247     {
248         return 2;
249     }
250     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
251     {
252         if (i < 2) {
253             HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
254             getElementDataType()->accept(visitor);
255         } else {
256             HLADataTypeEncodeVisitor visitor(stream);
257             getElementDataType()->accept(visitor);
258         }
259         return true;
260     }
261
262 private:
263     SGVec2<T> _value;
264 };
265
266 template<typename T>
267 class HLAVec2Data {
268 public:
269     HLAVec2Data() :
270         _value(new HLAVec2DataElement<T>(0))
271     { }
272     HLAVec2Data(const SGVec2<T>& value) :
273         _value(new HLAVec2DataElement<T>(0, value))
274     { }
275
276     operator const SGVec2<T>&() const
277     { return _value->getValue(); }
278     HLAVec2Data& operator=(const SGVec2<T>& value)
279     { _value->setValue(value); return *this; }
280
281     const SGVec2<T>& getValue() const
282     { return _value->getValue(); }
283     void setValue(const SGVec2<T>& value)
284     { _value->setValue(value); }
285
286     const HLAVec2DataElement<T>* getDataElement() const
287     { return _value.get(); }
288     HLAVec2DataElement<T>* getDataElement()
289     { return _value.get(); }
290
291     const HLAArrayDataType* getDataType() const
292     { return _value->getDataType(); }
293     void setDataType(const HLAArrayDataType* dataType)
294     { _value->setDataType(dataType); }
295
296 private:
297     SGSharedPtr<HLAVec2DataElement<T> > _value;
298 };
299
300 typedef HLAVec2Data<float> HLAVec2fData;
301 typedef HLAVec2Data<double> HLAVec2dData;
302 typedef HLAVec2Data<int> HLAVec2iData;
303
304 template<typename T>
305 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
306 public:
307     HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
308         HLAAbstractArrayDataElement(dataType),
309         _value(SGVec3<T>::zeros())
310     {}
311     HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
312         HLAAbstractArrayDataElement(dataType),
313         _value(value)
314     {}
315     const SGVec3<T>& getValue() const
316     { return _value; }
317     void setValue(const SGVec3<T>& value)
318     { _value = value; setDirty(true); }
319
320     virtual bool setNumElements(unsigned count)
321     {
322         for (unsigned i = count; i < 3; ++i)
323             _value[i] = 0;
324         return true;
325     }
326     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
327     {
328         if (i < 3) {
329             HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
330             getElementDataType()->accept(visitor);
331             _value[i] = visitor.getValue();
332         } else {
333             HLADataTypeDecodeVisitor visitor(stream);
334             getElementDataType()->accept(visitor);
335         }
336         return true;
337     }
338
339     virtual unsigned getNumElements() const
340     {
341         return 3;
342     }
343     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
344     {
345         if (i < 3) {
346             HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
347             getElementDataType()->accept(visitor);
348         } else {
349             HLADataTypeEncodeVisitor visitor(stream);
350             getElementDataType()->accept(visitor);
351         }
352         return true;
353     }
354
355 private:
356     SGVec3<T> _value;
357 };
358
359 template<typename T>
360 class HLAVec3Data {
361 public:
362     HLAVec3Data() :
363         _value(new HLAVec3DataElement<T>(0))
364     { }
365     HLAVec3Data(const SGVec3<T>& value) :
366         _value(new HLAVec3DataElement<T>(0, value))
367     { }
368
369     operator const SGVec3<T>&() const
370     { return _value->getValue(); }
371     HLAVec3Data& operator=(const SGVec3<T>& value)
372     { _value->setValue(value); return *this; }
373
374     const SGVec3<T>& getValue() const
375     { return _value->getValue(); }
376     void setValue(const SGVec3<T>& value)
377     { _value->setValue(value); }
378
379     const HLAVec3DataElement<T>* getDataElement() const
380     { return _value.get(); }
381     HLAVec3DataElement<T>* getDataElement()
382     { return _value.get(); }
383
384     const HLAArrayDataType* getDataType() const
385     { return _value->getDataType(); }
386     void setDataType(const HLAArrayDataType* dataType)
387     { _value->setDataType(dataType); }
388
389 private:
390     SGSharedPtr<HLAVec3DataElement<T> > _value;
391 };
392
393 typedef HLAVec3Data<float> HLAVec3fData;
394 typedef HLAVec3Data<double> HLAVec3dData;
395 typedef HLAVec3Data<int> HLAVec3iData;
396
397 template<typename T>
398 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
399 public:
400     HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
401         HLAAbstractArrayDataElement(dataType),
402         _value(SGVec4<T>::zeros())
403     {}
404     HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
405         HLAAbstractArrayDataElement(dataType),
406         _value(value)
407     {}
408     const SGVec4<T>& getValue() const
409     { return _value; }
410     void setValue(const SGVec4<T>& value)
411     { _value = value; setDirty(true); }
412
413     virtual bool setNumElements(unsigned count)
414     {
415         for (unsigned i = count; i < 4; ++i)
416             _value[i] = 0;
417         return true;
418     }
419     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
420     {
421         if (i < 4) {
422             HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
423             getElementDataType()->accept(visitor);
424             _value[i] = visitor.getValue();
425         } else {
426             HLADataTypeDecodeVisitor visitor(stream);
427             getElementDataType()->accept(visitor);
428         }
429         return true;
430     }
431
432     virtual unsigned getNumElements() const
433     {
434         return 4;
435     }
436     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
437     {
438         if (i < 4) {
439             HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
440             getElementDataType()->accept(visitor);
441         } else {
442             HLADataTypeEncodeVisitor visitor(stream);
443             getElementDataType()->accept(visitor);
444         }
445         return true;
446     }
447
448 private:
449     SGVec4<T> _value;
450 };
451
452 template<typename T>
453 class HLAVec4Data {
454 public:
455     HLAVec4Data() :
456         _value(new HLAVec4DataElement<T>(0))
457     { }
458     HLAVec4Data(const SGVec4<T>& value) :
459         _value(new HLAVec4DataElement<T>(0, value))
460     { }
461
462     operator const SGVec4<T>&() const
463     { return _value->getValue(); }
464     HLAVec4Data& operator=(const SGVec4<T>& value)
465     { _value->setValue(value); return *this; }
466
467     const SGVec4<T>& getValue() const
468     { return _value->getValue(); }
469     void setValue(const SGVec4<T>& value)
470     { _value->setValue(value); }
471
472     const HLAVec4DataElement<T>* getDataElement() const
473     { return _value.get(); }
474     HLAVec4DataElement<T>* getDataElement()
475     { return _value.get(); }
476
477     const HLAArrayDataType* getDataType() const
478     { return _value->getDataType(); }
479     void setDataType(const HLAArrayDataType* dataType)
480     { _value->setDataType(dataType); }
481
482 private:
483     SGSharedPtr<HLAVec4DataElement<T> > _value;
484 };
485
486 typedef HLAVec4Data<float> HLAVec4fData;
487 typedef HLAVec4Data<double> HLAVec4dData;
488 typedef HLAVec4Data<int> HLAVec4iData;
489
490 template<typename T>
491 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
492 public:
493     HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
494         HLAAbstractArrayDataElement(dataType),
495         _value(SGQuat<T>::unit())
496     {}
497     HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
498         HLAAbstractArrayDataElement(dataType),
499         _value(value)
500     {}
501
502     const SGQuat<T>& getValue() const
503     { return _value; }
504     void setValue(const SGQuat<T>& value)
505     { _value = value; setDirty(true); }
506
507     virtual bool setNumElements(unsigned count)
508     {
509         for (unsigned i = count; i < 4; ++i)
510             _value[i] = 0;
511         return true;
512     }
513     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
514     {
515         if (i < 4) {
516             HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
517             getElementDataType()->accept(visitor);
518             _value[i] = visitor.getValue();
519         } else {
520             HLADataTypeDecodeVisitor visitor(stream);
521             getElementDataType()->accept(visitor);
522         }
523         return true;
524     }
525
526     virtual unsigned getNumElements() const
527     {
528         return 4;
529     }
530     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
531     {
532         if (i < 4) {
533             HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
534             getElementDataType()->accept(visitor);
535         } else {
536             HLADataTypeEncodeVisitor visitor(stream);
537             getElementDataType()->accept(visitor);
538         }
539         return true;
540     }
541
542 private:
543     SGQuat<T> _value;
544 };
545
546 template<typename T>
547 class HLAQuatData {
548 public:
549     HLAQuatData() :
550         _value(new HLAQuatDataElement<T>(0))
551     { }
552     HLAQuatData(const SGQuat<T>& value) :
553         _value(new HLAQuatDataElement<T>(0, value))
554     { }
555
556     operator const SGQuat<T>&() const
557     { return _value->getValue(); }
558     HLAQuatData& operator=(const SGQuat<T>& value)
559     { _value->setValue(value); return *this; }
560
561     const SGQuat<T>& getValue() const
562     { return _value->getValue(); }
563     void setValue(const SGQuat<T>& value)
564     { _value->setValue(value); }
565
566     const HLAQuatDataElement<T>* getDataElement() const
567     { return _value.get(); }
568     HLAQuatDataElement<T>* getDataElement()
569     { return _value.get(); }
570
571     const HLAArrayDataType* getDataType() const
572     { return _value->getDataType(); }
573     void setDataType(const HLAArrayDataType* dataType)
574     { _value->setDataType(dataType); }
575
576 private:
577     SGSharedPtr<HLAQuatDataElement<T> > _value;
578 };
579
580 typedef HLAQuatData<float> HLAQuatfData;
581 typedef HLAQuatData<double> HLAQuatdData;
582
583 template<typename T>
584 class HLAQuat3DataElement : public HLAAbstractArrayDataElement {
585 public:
586     HLAQuat3DataElement(const HLAArrayDataType* dataType = 0) :
587         HLAAbstractArrayDataElement(dataType),
588         _value(SGQuat<T>::unit()),
589         _imag(SGQuat<T>::unit().getPositiveRealImag())
590     {}
591     HLAQuat3DataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
592         HLAAbstractArrayDataElement(dataType),
593         _value(value),
594         _imag(value.getPositiveRealImag())
595     {}
596
597     const SGQuat<T>& getValue() const
598     { return _value; }
599     void setValue(const SGQuat<T>& value)
600     { _value = value; _imag = _value.getPositiveRealImag(); setDirty(true); }
601
602     virtual bool encode(HLAEncodeStream& stream) const
603     {
604         return HLAAbstractArrayDataElement::encode(stream);
605     }
606     virtual bool decode(HLADecodeStream& stream)
607     {
608         if (!HLAAbstractArrayDataElement::decode(stream))
609             return false;
610         _value = SGQuat<T>::fromPositiveRealImag(_imag);
611         return true;
612     }
613
614     virtual bool setNumElements(unsigned count)
615     {
616         for (unsigned i = count; i < 3; ++i)
617             _imag[i] = 0;
618         return true;
619     }
620     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
621     {
622         if (i < 3) {
623             HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
624             getElementDataType()->accept(visitor);
625             _imag[i] = visitor.getValue();
626         } else {
627             HLADataTypeDecodeVisitor visitor(stream);
628             getElementDataType()->accept(visitor);
629         }
630         return true;
631     }
632
633     virtual unsigned getNumElements() const
634     {
635         return 3;
636     }
637     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
638     {
639         if (i < 3) {
640             HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _imag[i]);
641             getElementDataType()->accept(visitor);
642         } else {
643             HLADataTypeEncodeVisitor visitor(stream);
644             getElementDataType()->accept(visitor);
645         }
646         return true;
647     }
648
649 private:
650     SGQuat<T> _value;
651     SGVec3<T> _imag;
652 };
653
654 template<typename T>
655 class HLAQuat3Data {
656 public:
657     HLAQuat3Data() :
658         _value(new HLAQuat3DataElement<T>(0))
659     { }
660     HLAQuat3Data(const SGQuat<T>& value) :
661         _value(new HLAQuat3DataElement<T>(0, value))
662     { }
663
664     operator const SGQuat<T>&() const
665     { return _value->getValue(); }
666     HLAQuat3Data& operator=(const SGQuat<T>& value)
667     { _value->setValue(value); return *this; }
668
669     const SGQuat<T>& getValue() const
670     { return _value->getValue(); }
671     void setValue(const SGQuat<T>& value)
672     { _value->setValue(value); }
673
674     const HLAQuat3DataElement<T>* getDataElement() const
675     { return _value.get(); }
676     HLAQuat3DataElement<T>* getDataElement()
677     { return _value.get(); }
678
679     const HLAArrayDataType* getDataType() const
680     { return _value->getDataType(); }
681     void setDataType(const HLAArrayDataType* dataType)
682     { _value->setDataType(dataType); }
683
684 private:
685     SGSharedPtr<HLAQuat3DataElement<T> > _value;
686 };
687
688 typedef HLAQuat3Data<float> HLAQuat3fData;
689 typedef HLAQuat3Data<double> HLAQuat3dData;
690
691 }
692
693 #endif