1 // Copyright (C) 2009 - 2010 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 "HLAVariantDataElement.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 setNumElements(unsigned size);
63 virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
64 virtual unsigned getNumElements() const;
65 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
67 const HLADataElement* getElement(unsigned index) const;
68 HLADataElement* getElement(unsigned index);
69 HLADataElement* getOrCreateElement(unsigned index);
70 void setElement(unsigned i, HLADataElement* value);
72 class DataElementFactory : public SGReferenced {
74 virtual ~DataElementFactory();
75 virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
78 void setDataElementFactory(DataElementFactory* dataElementFactory);
79 DataElementFactory* getDataElementFactory();
82 HLADataElement* newElement(unsigned index);
84 typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
85 ElementVector _elementVector;
87 SGSharedPtr<DataElementFactory> _dataElementFactory;
90 // Holds an array of variants.
91 // Factors out common code for that use case.
92 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
94 HLAVariantArrayDataElement();
95 virtual ~HLAVariantArrayDataElement();
97 // Overwrite this from the abstract class, need some more checks here
98 virtual bool setDataType(const HLADataType* dataType);
100 virtual bool setNumElements(unsigned size);
101 virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
102 virtual unsigned getNumElements() const;
103 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
105 const HLAVariantDataElement* getElement(unsigned index) const;
106 HLAVariantDataElement* getElement(unsigned index);
107 HLAVariantDataElement* getOrCreateElement(unsigned index);
108 void setElement(unsigned index, HLAVariantDataElement* value);
110 typedef HLAVariantDataElement::DataElementFactory AlternativeDataElementFactory;
112 void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
113 AlternativeDataElementFactory* getAlternativeDataElementFactory();
116 HLAVariantDataElement* newElement();
118 typedef std::vector<SGSharedPtr<HLAVariantDataElement> > ElementVector;
119 ElementVector _elementVector;
121 SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
124 class HLAStringDataElement : public HLAAbstractArrayDataElement {
126 HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
127 HLAAbstractArrayDataElement(dataType)
129 HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
130 HLAAbstractArrayDataElement(dataType),
133 const std::string& getValue() const
135 void setValue(const std::string& value)
138 virtual bool setNumElements(unsigned count)
140 _value.resize(count);
143 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
145 HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
146 getElementDataType()->accept(visitor);
147 _value[i] = visitor.getValue();
151 virtual unsigned getNumElements() const
153 return _value.size();
155 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
157 HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
158 getElementDataType()->accept(visitor);
166 class HLAStringData {
169 _value(new HLAStringDataElement(0))
171 HLAStringData(const std::string& value) :
172 _value(new HLAStringDataElement(0))
173 { _value->setValue(value); }
175 operator const std::string&() const
176 { return _value->getValue(); }
177 HLAStringData& operator=(const std::string& value)
178 { _value->setValue(value); return *this; }
180 const std::string& getValue() const
181 { return _value->getValue(); }
182 void setValue(const std::string& value)
183 { _value->setValue(value); }
185 const HLAStringDataElement* getDataElement() const
186 { return _value.get(); }
187 HLAStringDataElement* getDataElement()
188 { return _value.get(); }
190 const HLAArrayDataType* getDataType() const
191 { return _value->getDataType(); }
192 void setDataType(const HLAArrayDataType* dataType)
193 { _value->setDataType(dataType); }
196 SGSharedPtr<HLAStringDataElement> _value;
200 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
202 HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
203 HLAAbstractArrayDataElement(dataType),
204 _value(SGVec2<T>::zeros())
206 HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
207 HLAAbstractArrayDataElement(dataType),
210 const SGVec2<T>& getValue() const
212 void setValue(const SGVec2<T>& value)
215 virtual bool setNumElements(unsigned count)
217 for (unsigned i = 2; i < count; ++i)
221 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
224 HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
225 getElementDataType()->accept(visitor);
226 _value[i] = visitor.getValue();
228 HLADataTypeDecodeVisitor visitor(stream);
229 getElementDataType()->accept(visitor);
234 virtual unsigned getNumElements() const
238 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
241 HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
242 getElementDataType()->accept(visitor);
244 HLADataTypeEncodeVisitor visitor(stream);
245 getElementDataType()->accept(visitor);
258 _value(new HLAVec2DataElement<T>(0))
260 HLAVec2Data(const SGVec2<T>& value) :
261 _value(new HLAVec2DataElement<T>(0, value))
264 operator const SGVec2<T>&() const
265 { return _value->getValue(); }
266 HLAVec2Data& operator=(const SGVec2<T>& value)
267 { _value->setValue(value); return *this; }
269 const SGVec2<T>& getValue() const
270 { return _value->getValue(); }
271 void setValue(const SGVec2<T>& value)
272 { _value->setValue(value); }
274 const HLAVec2DataElement<T>* getDataElement() const
275 { return _value.get(); }
276 HLAVec2DataElement<T>* getDataElement()
277 { return _value.get(); }
279 const HLAArrayDataType* getDataType() const
280 { return _value->getDataType(); }
281 void setDataType(const HLAArrayDataType* dataType)
282 { _value->setDataType(dataType); }
285 SGSharedPtr<HLAVec2DataElement<T> > _value;
288 typedef HLAVec2Data<float> HLAVec2fData;
289 typedef HLAVec2Data<double> HLAVec2dData;
292 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
294 HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
295 HLAAbstractArrayDataElement(dataType),
296 _value(SGVec3<T>::zeros())
298 HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
299 HLAAbstractArrayDataElement(dataType),
302 const SGVec3<T>& getValue() const
304 void setValue(const SGVec3<T>& value)
307 virtual bool setNumElements(unsigned count)
309 for (unsigned i = 3; i < count; ++i)
313 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
316 HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
317 getElementDataType()->accept(visitor);
318 _value[i] = visitor.getValue();
320 HLADataTypeDecodeVisitor visitor(stream);
321 getElementDataType()->accept(visitor);
326 virtual unsigned getNumElements() const
330 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
333 HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
334 getElementDataType()->accept(visitor);
336 HLADataTypeEncodeVisitor visitor(stream);
337 getElementDataType()->accept(visitor);
350 _value(new HLAVec3DataElement<T>(0))
352 HLAVec3Data(const SGVec3<T>& value) :
353 _value(new HLAVec3DataElement<T>(0, value))
356 operator const SGVec3<T>&() const
357 { return _value->getValue(); }
358 HLAVec3Data& operator=(const SGVec3<T>& value)
359 { _value->setValue(value); return *this; }
361 const SGVec3<T>& getValue() const
362 { return _value->getValue(); }
363 void setValue(const SGVec3<T>& value)
364 { _value->setValue(value); }
366 const HLAVec3DataElement<T>* getDataElement() const
367 { return _value.get(); }
368 HLAVec3DataElement<T>* getDataElement()
369 { return _value.get(); }
371 const HLAArrayDataType* getDataType() const
372 { return _value->getDataType(); }
373 void setDataType(const HLAArrayDataType* dataType)
374 { _value->setDataType(dataType); }
377 SGSharedPtr<HLAVec3DataElement<T> > _value;
380 typedef HLAVec3Data<float> HLAVec3fData;
381 typedef HLAVec3Data<double> HLAVec3dData;
384 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
386 HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
387 HLAAbstractArrayDataElement(dataType),
388 _value(SGVec4<T>::zeros())
390 HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
391 HLAAbstractArrayDataElement(dataType),
394 const SGVec4<T>& getValue() const
396 void setValue(const SGVec4<T>& value)
399 virtual bool setNumElements(unsigned count)
401 for (unsigned i = 4; i < count; ++i)
405 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
408 HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
409 getElementDataType()->accept(visitor);
410 _value[i] = visitor.getValue();
412 HLADataTypeDecodeVisitor visitor(stream);
413 getElementDataType()->accept(visitor);
418 virtual unsigned getNumElements() const
422 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
425 HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
426 getElementDataType()->accept(visitor);
428 HLADataTypeEncodeVisitor visitor(stream);
429 getElementDataType()->accept(visitor);
442 _value(new HLAVec4DataElement<T>(0))
444 HLAVec4Data(const SGVec4<T>& value) :
445 _value(new HLAVec4DataElement<T>(0, value))
448 operator const SGVec4<T>&() const
449 { return _value->getValue(); }
450 HLAVec4Data& operator=(const SGVec4<T>& value)
451 { _value->setValue(value); return *this; }
453 const SGVec4<T>& getValue() const
454 { return _value->getValue(); }
455 void setValue(const SGVec4<T>& value)
456 { _value->setValue(value); }
458 const HLAVec4DataElement<T>* getDataElement() const
459 { return _value.get(); }
460 HLAVec4DataElement<T>* getDataElement()
461 { return _value.get(); }
463 const HLAArrayDataType* getDataType() const
464 { return _value->getDataType(); }
465 void setDataType(const HLAArrayDataType* dataType)
466 { _value->setDataType(dataType); }
469 SGSharedPtr<HLAVec4DataElement<T> > _value;
472 typedef HLAVec4Data<float> HLAVec4fData;
473 typedef HLAVec4Data<double> HLAVec4dData;
476 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
478 HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
479 HLAAbstractArrayDataElement(dataType),
480 _value(SGQuat<T>::zeros())
482 HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
483 HLAAbstractArrayDataElement(dataType),
486 const SGQuat<T>& getValue() const
488 void setValue(const SGQuat<T>& value)
491 virtual bool setNumElements(unsigned count)
493 for (unsigned i = 4; i < count; ++i)
497 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
500 HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
501 getElementDataType()->accept(visitor);
502 _value[i] = visitor.getValue();
504 HLADataTypeDecodeVisitor visitor(stream);
505 getElementDataType()->accept(visitor);
510 virtual unsigned getNumElements() const
514 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
517 HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
518 getElementDataType()->accept(visitor);
520 HLADataTypeEncodeVisitor visitor(stream);
521 getElementDataType()->accept(visitor);