1 // Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
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.
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.
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.
18 #ifndef HLAArrayDataElement_hxx
19 #define HLAArrayDataElement_hxx
23 #include <simgear/math/SGMath.hxx>
24 #include "HLAArrayDataType.hxx"
25 #include "HLADataElement.hxx"
26 #include "HLAVariantRecordDataElement.hxx"
27 #include "HLADataTypeVisitor.hxx"
31 class HLAAbstractArrayDataElement : public HLADataElement {
33 HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
34 virtual ~HLAAbstractArrayDataElement();
36 virtual void accept(HLADataElementVisitor& visitor);
37 virtual void accept(HLAConstDataElementVisitor& visitor) const;
39 virtual bool decode(HLADecodeStream& stream);
40 virtual bool encode(HLAEncodeStream& stream) const;
42 virtual const HLAArrayDataType* getDataType() const;
43 virtual bool setDataType(const HLADataType* dataType);
45 const HLADataType* getElementDataType() const;
47 virtual bool setNumElements(unsigned count) = 0;
48 virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
50 virtual unsigned getNumElements() const = 0;
51 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
54 SGSharedPtr<const HLAArrayDataType> _dataType;
57 class HLAArrayDataElement : public HLAAbstractArrayDataElement {
59 HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
60 virtual ~HLAArrayDataElement();
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;
66 virtual bool setDataType(const HLADataType* dataType);
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;
73 const HLADataElement* getElement(unsigned index) const;
74 HLADataElement* getElement(unsigned index);
75 HLADataElement* getOrCreateElement(unsigned index);
76 void setElement(unsigned i, HLADataElement* value);
78 class DataElementFactory : public SGReferenced {
80 virtual ~DataElementFactory();
81 virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
84 void setDataElementFactory(DataElementFactory* dataElementFactory);
85 DataElementFactory* getDataElementFactory();
88 virtual void _setStamp(Stamp* stamp);
91 HLADataElement* newElement(unsigned index);
93 typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
94 ElementVector _elementVector;
96 SGSharedPtr<DataElementFactory> _dataElementFactory;
99 // Holds an array of variants.
100 // Factors out common code for that use case.
101 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
103 HLAVariantArrayDataElement();
104 virtual ~HLAVariantArrayDataElement();
106 // Overwrite this from the abstract class, need some more checks here
107 virtual bool setDataType(const HLADataType* dataType);
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;
114 const HLAVariantRecordDataElement* getElement(unsigned index) const;
115 HLAVariantRecordDataElement* getElement(unsigned index);
116 HLAVariantRecordDataElement* getOrCreateElement(unsigned index);
117 void setElement(unsigned index, HLAVariantRecordDataElement* value);
119 typedef HLAVariantRecordDataElement::DataElementFactory AlternativeDataElementFactory;
121 void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
122 AlternativeDataElementFactory* getAlternativeDataElementFactory();
125 virtual void _setStamp(Stamp* stamp);
128 HLAVariantRecordDataElement* newElement();
130 typedef std::vector<SGSharedPtr<HLAVariantRecordDataElement> > ElementVector;
131 ElementVector _elementVector;
133 SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
136 class HLAStringDataElement : public HLAAbstractArrayDataElement {
138 HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
139 HLAAbstractArrayDataElement(dataType)
141 HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
142 HLAAbstractArrayDataElement(dataType),
145 const std::string& getValue() const
147 void setValue(const std::string& value)
148 { _value = value; setDirty(true); }
150 virtual bool setNumElements(unsigned count)
152 _value.resize(count);
155 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
157 HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
158 getElementDataType()->accept(visitor);
159 _value[i] = visitor.getValue();
163 virtual unsigned getNumElements() const
165 return _value.size();
167 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
169 HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
170 getElementDataType()->accept(visitor);
178 class HLAStringData {
181 _value(new HLAStringDataElement(0))
183 HLAStringData(const std::string& value) :
184 _value(new HLAStringDataElement(0))
185 { _value->setValue(value); }
187 operator const std::string&() const
188 { return _value->getValue(); }
189 HLAStringData& operator=(const std::string& value)
190 { _value->setValue(value); return *this; }
192 const std::string& getValue() const
193 { return _value->getValue(); }
194 void setValue(const std::string& value)
195 { _value->setValue(value); }
197 const HLAStringDataElement* getDataElement() const
198 { return _value.get(); }
199 HLAStringDataElement* getDataElement()
200 { return _value.get(); }
202 const HLAArrayDataType* getDataType() const
203 { return _value->getDataType(); }
204 void setDataType(const HLAArrayDataType* dataType)
205 { _value->setDataType(dataType); }
208 SGSharedPtr<HLAStringDataElement> _value;
212 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
214 HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
215 HLAAbstractArrayDataElement(dataType),
216 _value(SGVec2<T>::zeros())
218 HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
219 HLAAbstractArrayDataElement(dataType),
222 const SGVec2<T>& getValue() const
224 void setValue(const SGVec2<T>& value)
225 { _value = value; setDirty(true); }
227 virtual bool setNumElements(unsigned count)
229 for (unsigned i = count; i < 2; ++i)
233 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
236 HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
237 getElementDataType()->accept(visitor);
238 _value[i] = visitor.getValue();
240 HLADataTypeDecodeVisitor visitor(stream);
241 getElementDataType()->accept(visitor);
246 virtual unsigned getNumElements() const
250 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
253 HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
254 getElementDataType()->accept(visitor);
256 HLADataTypeEncodeVisitor visitor(stream);
257 getElementDataType()->accept(visitor);
270 _value(new HLAVec2DataElement<T>(0))
272 HLAVec2Data(const SGVec2<T>& value) :
273 _value(new HLAVec2DataElement<T>(0, value))
276 operator const SGVec2<T>&() const
277 { return _value->getValue(); }
278 HLAVec2Data& operator=(const SGVec2<T>& value)
279 { _value->setValue(value); return *this; }
281 const SGVec2<T>& getValue() const
282 { return _value->getValue(); }
283 void setValue(const SGVec2<T>& value)
284 { _value->setValue(value); }
286 const HLAVec2DataElement<T>* getDataElement() const
287 { return _value.get(); }
288 HLAVec2DataElement<T>* getDataElement()
289 { return _value.get(); }
291 const HLAArrayDataType* getDataType() const
292 { return _value->getDataType(); }
293 void setDataType(const HLAArrayDataType* dataType)
294 { _value->setDataType(dataType); }
297 SGSharedPtr<HLAVec2DataElement<T> > _value;
300 typedef HLAVec2Data<float> HLAVec2fData;
301 typedef HLAVec2Data<double> HLAVec2dData;
302 typedef HLAVec2Data<int> HLAVec2iData;
305 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
307 HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
308 HLAAbstractArrayDataElement(dataType),
309 _value(SGVec3<T>::zeros())
311 HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
312 HLAAbstractArrayDataElement(dataType),
315 const SGVec3<T>& getValue() const
317 void setValue(const SGVec3<T>& value)
318 { _value = value; setDirty(true); }
320 virtual bool setNumElements(unsigned count)
322 for (unsigned i = count; i < 3; ++i)
326 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
329 HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
330 getElementDataType()->accept(visitor);
331 _value[i] = visitor.getValue();
333 HLADataTypeDecodeVisitor visitor(stream);
334 getElementDataType()->accept(visitor);
339 virtual unsigned getNumElements() const
343 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
346 HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
347 getElementDataType()->accept(visitor);
349 HLADataTypeEncodeVisitor visitor(stream);
350 getElementDataType()->accept(visitor);
363 _value(new HLAVec3DataElement<T>(0))
365 HLAVec3Data(const SGVec3<T>& value) :
366 _value(new HLAVec3DataElement<T>(0, value))
369 operator const SGVec3<T>&() const
370 { return _value->getValue(); }
371 HLAVec3Data& operator=(const SGVec3<T>& value)
372 { _value->setValue(value); return *this; }
374 const SGVec3<T>& getValue() const
375 { return _value->getValue(); }
376 void setValue(const SGVec3<T>& value)
377 { _value->setValue(value); }
379 const HLAVec3DataElement<T>* getDataElement() const
380 { return _value.get(); }
381 HLAVec3DataElement<T>* getDataElement()
382 { return _value.get(); }
384 const HLAArrayDataType* getDataType() const
385 { return _value->getDataType(); }
386 void setDataType(const HLAArrayDataType* dataType)
387 { _value->setDataType(dataType); }
390 SGSharedPtr<HLAVec3DataElement<T> > _value;
393 typedef HLAVec3Data<float> HLAVec3fData;
394 typedef HLAVec3Data<double> HLAVec3dData;
395 typedef HLAVec3Data<int> HLAVec3iData;
398 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
400 HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
401 HLAAbstractArrayDataElement(dataType),
402 _value(SGVec4<T>::zeros())
404 HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
405 HLAAbstractArrayDataElement(dataType),
408 const SGVec4<T>& getValue() const
410 void setValue(const SGVec4<T>& value)
411 { _value = value; setDirty(true); }
413 virtual bool setNumElements(unsigned count)
415 for (unsigned i = count; i < 4; ++i)
419 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
422 HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
423 getElementDataType()->accept(visitor);
424 _value[i] = visitor.getValue();
426 HLADataTypeDecodeVisitor visitor(stream);
427 getElementDataType()->accept(visitor);
432 virtual unsigned getNumElements() const
436 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
439 HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
440 getElementDataType()->accept(visitor);
442 HLADataTypeEncodeVisitor visitor(stream);
443 getElementDataType()->accept(visitor);
456 _value(new HLAVec4DataElement<T>(0))
458 HLAVec4Data(const SGVec4<T>& value) :
459 _value(new HLAVec4DataElement<T>(0, value))
462 operator const SGVec4<T>&() const
463 { return _value->getValue(); }
464 HLAVec4Data& operator=(const SGVec4<T>& value)
465 { _value->setValue(value); return *this; }
467 const SGVec4<T>& getValue() const
468 { return _value->getValue(); }
469 void setValue(const SGVec4<T>& value)
470 { _value->setValue(value); }
472 const HLAVec4DataElement<T>* getDataElement() const
473 { return _value.get(); }
474 HLAVec4DataElement<T>* getDataElement()
475 { return _value.get(); }
477 const HLAArrayDataType* getDataType() const
478 { return _value->getDataType(); }
479 void setDataType(const HLAArrayDataType* dataType)
480 { _value->setDataType(dataType); }
483 SGSharedPtr<HLAVec4DataElement<T> > _value;
486 typedef HLAVec4Data<float> HLAVec4fData;
487 typedef HLAVec4Data<double> HLAVec4dData;
488 typedef HLAVec4Data<int> HLAVec4iData;
491 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
493 HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
494 HLAAbstractArrayDataElement(dataType),
495 _value(SGQuat<T>::unit())
497 HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
498 HLAAbstractArrayDataElement(dataType),
502 const SGQuat<T>& getValue() const
504 void setValue(const SGQuat<T>& value)
505 { _value = value; setDirty(true); }
507 virtual bool setNumElements(unsigned count)
509 for (unsigned i = count; i < 4; ++i)
513 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
516 HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
517 getElementDataType()->accept(visitor);
518 _value[i] = visitor.getValue();
520 HLADataTypeDecodeVisitor visitor(stream);
521 getElementDataType()->accept(visitor);
526 virtual unsigned getNumElements() const
530 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
533 HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
534 getElementDataType()->accept(visitor);
536 HLADataTypeEncodeVisitor visitor(stream);
537 getElementDataType()->accept(visitor);
550 _value(new HLAQuatDataElement<T>(0))
552 HLAQuatData(const SGQuat<T>& value) :
553 _value(new HLAQuatDataElement<T>(0, value))
556 operator const SGQuat<T>&() const
557 { return _value->getValue(); }
558 HLAQuatData& operator=(const SGQuat<T>& value)
559 { _value->setValue(value); return *this; }
561 const SGQuat<T>& getValue() const
562 { return _value->getValue(); }
563 void setValue(const SGQuat<T>& value)
564 { _value->setValue(value); }
566 const HLAQuatDataElement<T>* getDataElement() const
567 { return _value.get(); }
568 HLAQuatDataElement<T>* getDataElement()
569 { return _value.get(); }
571 const HLAArrayDataType* getDataType() const
572 { return _value->getDataType(); }
573 void setDataType(const HLAArrayDataType* dataType)
574 { _value->setDataType(dataType); }
577 SGSharedPtr<HLAQuatDataElement<T> > _value;
580 typedef HLAQuatData<float> HLAQuatfData;
581 typedef HLAQuatData<double> HLAQuatdData;
584 class HLAQuat3DataElement : public HLAAbstractArrayDataElement {
586 HLAQuat3DataElement(const HLAArrayDataType* dataType = 0) :
587 HLAAbstractArrayDataElement(dataType),
588 _value(SGQuat<T>::unit()),
589 _imag(SGQuat<T>::unit().getPositiveRealImag())
591 HLAQuat3DataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
592 HLAAbstractArrayDataElement(dataType),
594 _imag(value.getPositiveRealImag())
597 const SGQuat<T>& getValue() const
599 void setValue(const SGQuat<T>& value)
600 { _value = value; _imag = _value.getPositiveRealImag(); setDirty(true); }
602 virtual bool encode(HLAEncodeStream& stream) const
604 return HLAAbstractArrayDataElement::encode(stream);
606 virtual bool decode(HLADecodeStream& stream)
608 if (!HLAAbstractArrayDataElement::decode(stream))
610 _value = SGQuat<T>::fromPositiveRealImag(_imag);
614 virtual bool setNumElements(unsigned count)
616 for (unsigned i = count; i < 3; ++i)
620 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
623 HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
624 getElementDataType()->accept(visitor);
625 _imag[i] = visitor.getValue();
627 HLADataTypeDecodeVisitor visitor(stream);
628 getElementDataType()->accept(visitor);
633 virtual unsigned getNumElements() const
637 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
640 HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _imag[i]);
641 getElementDataType()->accept(visitor);
643 HLADataTypeEncodeVisitor visitor(stream);
644 getElementDataType()->accept(visitor);
658 _value(new HLAQuat3DataElement<T>(0))
660 HLAQuat3Data(const SGQuat<T>& value) :
661 _value(new HLAQuat3DataElement<T>(0, value))
664 operator const SGQuat<T>&() const
665 { return _value->getValue(); }
666 HLAQuat3Data& operator=(const SGQuat<T>& value)
667 { _value->setValue(value); return *this; }
669 const SGQuat<T>& getValue() const
670 { return _value->getValue(); }
671 void setValue(const SGQuat<T>& value)
672 { _value->setValue(value); }
674 const HLAQuat3DataElement<T>* getDataElement() const
675 { return _value.get(); }
676 HLAQuat3DataElement<T>* getDataElement()
677 { return _value.get(); }
679 const HLAArrayDataType* getDataType() const
680 { return _value->getDataType(); }
681 void setDataType(const HLAArrayDataType* dataType)
682 { _value->setDataType(dataType); }
685 SGSharedPtr<HLAQuat3DataElement<T> > _value;
688 typedef HLAQuat3Data<float> HLAQuat3fData;
689 typedef HLAQuat3Data<double> HLAQuat3dData;