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 setNumElements(unsigned size);
67 virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
68 virtual unsigned getNumElements() const;
69 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
71 const HLADataElement* getElement(unsigned index) const;
72 HLADataElement* getElement(unsigned index);
73 HLADataElement* getOrCreateElement(unsigned index);
74 void setElement(unsigned i, HLADataElement* value);
76 class DataElementFactory : public SGReferenced {
78 virtual ~DataElementFactory();
79 virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
82 void setDataElementFactory(DataElementFactory* dataElementFactory);
83 DataElementFactory* getDataElementFactory();
86 virtual void _setStamp(Stamp* stamp);
89 HLADataElement* newElement(unsigned index);
91 typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
92 ElementVector _elementVector;
94 SGSharedPtr<DataElementFactory> _dataElementFactory;
97 // Holds an array of variants.
98 // Factors out common code for that use case.
99 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
101 HLAVariantArrayDataElement();
102 virtual ~HLAVariantArrayDataElement();
104 // Overwrite this from the abstract class, need some more checks here
105 virtual bool setDataType(const HLADataType* dataType);
107 virtual bool setNumElements(unsigned size);
108 virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
109 virtual unsigned getNumElements() const;
110 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
112 const HLAVariantRecordDataElement* getElement(unsigned index) const;
113 HLAVariantRecordDataElement* getElement(unsigned index);
114 HLAVariantRecordDataElement* getOrCreateElement(unsigned index);
115 void setElement(unsigned index, HLAVariantRecordDataElement* value);
117 typedef HLAVariantRecordDataElement::DataElementFactory AlternativeDataElementFactory;
119 void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
120 AlternativeDataElementFactory* getAlternativeDataElementFactory();
123 virtual void _setStamp(Stamp* stamp);
126 HLAVariantRecordDataElement* newElement();
128 typedef std::vector<SGSharedPtr<HLAVariantRecordDataElement> > ElementVector;
129 ElementVector _elementVector;
131 SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
134 class HLAStringDataElement : public HLAAbstractArrayDataElement {
136 HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
137 HLAAbstractArrayDataElement(dataType)
139 HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
140 HLAAbstractArrayDataElement(dataType),
143 const std::string& getValue() const
145 void setValue(const std::string& value)
146 { _value = value; setDirty(true); }
148 virtual bool setNumElements(unsigned count)
150 _value.resize(count);
153 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
155 HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
156 getElementDataType()->accept(visitor);
157 _value[i] = visitor.getValue();
161 virtual unsigned getNumElements() const
163 return _value.size();
165 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
167 HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
168 getElementDataType()->accept(visitor);
176 class HLAStringData {
179 _value(new HLAStringDataElement(0))
181 HLAStringData(const std::string& value) :
182 _value(new HLAStringDataElement(0))
183 { _value->setValue(value); }
185 operator const std::string&() const
186 { return _value->getValue(); }
187 HLAStringData& operator=(const std::string& value)
188 { _value->setValue(value); return *this; }
190 const std::string& getValue() const
191 { return _value->getValue(); }
192 void setValue(const std::string& value)
193 { _value->setValue(value); }
195 const HLAStringDataElement* getDataElement() const
196 { return _value.get(); }
197 HLAStringDataElement* getDataElement()
198 { return _value.get(); }
200 const HLAArrayDataType* getDataType() const
201 { return _value->getDataType(); }
202 void setDataType(const HLAArrayDataType* dataType)
203 { _value->setDataType(dataType); }
206 SGSharedPtr<HLAStringDataElement> _value;
210 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
212 HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
213 HLAAbstractArrayDataElement(dataType),
214 _value(SGVec2<T>::zeros())
216 HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
217 HLAAbstractArrayDataElement(dataType),
220 const SGVec2<T>& getValue() const
222 void setValue(const SGVec2<T>& value)
223 { _value = value; setDirty(true); }
225 virtual bool setNumElements(unsigned count)
227 for (unsigned i = count; i < 2; ++i)
231 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
234 HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
235 getElementDataType()->accept(visitor);
236 _value[i] = visitor.getValue();
238 HLADataTypeDecodeVisitor visitor(stream);
239 getElementDataType()->accept(visitor);
244 virtual unsigned getNumElements() const
248 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
251 HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
252 getElementDataType()->accept(visitor);
254 HLADataTypeEncodeVisitor visitor(stream);
255 getElementDataType()->accept(visitor);
268 _value(new HLAVec2DataElement<T>(0))
270 HLAVec2Data(const SGVec2<T>& value) :
271 _value(new HLAVec2DataElement<T>(0, value))
274 operator const SGVec2<T>&() const
275 { return _value->getValue(); }
276 HLAVec2Data& operator=(const SGVec2<T>& value)
277 { _value->setValue(value); return *this; }
279 const SGVec2<T>& getValue() const
280 { return _value->getValue(); }
281 void setValue(const SGVec2<T>& value)
282 { _value->setValue(value); }
284 const HLAVec2DataElement<T>* getDataElement() const
285 { return _value.get(); }
286 HLAVec2DataElement<T>* getDataElement()
287 { return _value.get(); }
289 const HLAArrayDataType* getDataType() const
290 { return _value->getDataType(); }
291 void setDataType(const HLAArrayDataType* dataType)
292 { _value->setDataType(dataType); }
295 SGSharedPtr<HLAVec2DataElement<T> > _value;
298 typedef HLAVec2Data<float> HLAVec2fData;
299 typedef HLAVec2Data<double> HLAVec2dData;
302 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
304 HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
305 HLAAbstractArrayDataElement(dataType),
306 _value(SGVec3<T>::zeros())
308 HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
309 HLAAbstractArrayDataElement(dataType),
312 const SGVec3<T>& getValue() const
314 void setValue(const SGVec3<T>& value)
315 { _value = value; setDirty(true); }
317 virtual bool setNumElements(unsigned count)
319 for (unsigned i = count; i < 3; ++i)
323 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
326 HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
327 getElementDataType()->accept(visitor);
328 _value[i] = visitor.getValue();
330 HLADataTypeDecodeVisitor visitor(stream);
331 getElementDataType()->accept(visitor);
336 virtual unsigned getNumElements() const
340 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
343 HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
344 getElementDataType()->accept(visitor);
346 HLADataTypeEncodeVisitor visitor(stream);
347 getElementDataType()->accept(visitor);
360 _value(new HLAVec3DataElement<T>(0))
362 HLAVec3Data(const SGVec3<T>& value) :
363 _value(new HLAVec3DataElement<T>(0, value))
366 operator const SGVec3<T>&() const
367 { return _value->getValue(); }
368 HLAVec3Data& operator=(const SGVec3<T>& value)
369 { _value->setValue(value); return *this; }
371 const SGVec3<T>& getValue() const
372 { return _value->getValue(); }
373 void setValue(const SGVec3<T>& value)
374 { _value->setValue(value); }
376 const HLAVec3DataElement<T>* getDataElement() const
377 { return _value.get(); }
378 HLAVec3DataElement<T>* getDataElement()
379 { return _value.get(); }
381 const HLAArrayDataType* getDataType() const
382 { return _value->getDataType(); }
383 void setDataType(const HLAArrayDataType* dataType)
384 { _value->setDataType(dataType); }
387 SGSharedPtr<HLAVec3DataElement<T> > _value;
390 typedef HLAVec3Data<float> HLAVec3fData;
391 typedef HLAVec3Data<double> HLAVec3dData;
394 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
396 HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
397 HLAAbstractArrayDataElement(dataType),
398 _value(SGVec4<T>::zeros())
400 HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
401 HLAAbstractArrayDataElement(dataType),
404 const SGVec4<T>& getValue() const
406 void setValue(const SGVec4<T>& value)
407 { _value = value; setDirty(true); }
409 virtual bool setNumElements(unsigned count)
411 for (unsigned i = count; i < 4; ++i)
415 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
418 HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
419 getElementDataType()->accept(visitor);
420 _value[i] = visitor.getValue();
422 HLADataTypeDecodeVisitor visitor(stream);
423 getElementDataType()->accept(visitor);
428 virtual unsigned getNumElements() const
432 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
435 HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
436 getElementDataType()->accept(visitor);
438 HLADataTypeEncodeVisitor visitor(stream);
439 getElementDataType()->accept(visitor);
452 _value(new HLAVec4DataElement<T>(0))
454 HLAVec4Data(const SGVec4<T>& value) :
455 _value(new HLAVec4DataElement<T>(0, value))
458 operator const SGVec4<T>&() const
459 { return _value->getValue(); }
460 HLAVec4Data& operator=(const SGVec4<T>& value)
461 { _value->setValue(value); return *this; }
463 const SGVec4<T>& getValue() const
464 { return _value->getValue(); }
465 void setValue(const SGVec4<T>& value)
466 { _value->setValue(value); }
468 const HLAVec4DataElement<T>* getDataElement() const
469 { return _value.get(); }
470 HLAVec4DataElement<T>* getDataElement()
471 { return _value.get(); }
473 const HLAArrayDataType* getDataType() const
474 { return _value->getDataType(); }
475 void setDataType(const HLAArrayDataType* dataType)
476 { _value->setDataType(dataType); }
479 SGSharedPtr<HLAVec4DataElement<T> > _value;
482 typedef HLAVec4Data<float> HLAVec4fData;
483 typedef HLAVec4Data<double> HLAVec4dData;
486 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
488 HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
489 HLAAbstractArrayDataElement(dataType),
490 _value(SGQuat<T>::zeros())
492 HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
493 HLAAbstractArrayDataElement(dataType),
496 const SGQuat<T>& getValue() const
498 void setValue(const SGQuat<T>& value)
499 { _value = value; setDirty(true); }
501 virtual bool setNumElements(unsigned count)
503 for (unsigned i = count; i < 4; ++i)
507 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
510 HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
511 getElementDataType()->accept(visitor);
512 _value[i] = visitor.getValue();
514 HLADataTypeDecodeVisitor visitor(stream);
515 getElementDataType()->accept(visitor);
520 virtual unsigned getNumElements() const
524 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
527 HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
528 getElementDataType()->accept(visitor);
530 HLADataTypeEncodeVisitor visitor(stream);
531 getElementDataType()->accept(visitor);