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 bool decode(HLADecodeStream& stream);
37 virtual bool encode(HLAEncodeStream& stream) const;
39 virtual const HLAArrayDataType* getDataType() const;
40 virtual bool setDataType(const HLADataType* dataType);
42 const HLADataType* getElementDataType() const;
44 virtual bool setNumElements(unsigned count) = 0;
45 virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
47 virtual unsigned getNumElements() const = 0;
48 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
51 SGSharedPtr<const HLAArrayDataType> _dataType;
54 class HLAArrayDataElement : public HLAAbstractArrayDataElement {
56 HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
57 virtual ~HLAArrayDataElement();
59 virtual bool setNumElements(unsigned size);
60 virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
61 virtual unsigned getNumElements() const;
62 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
64 const HLADataElement* getElement(unsigned index) const;
65 HLADataElement* getElement(unsigned index);
66 HLADataElement* getOrCreateElement(unsigned index);
67 void setElement(unsigned i, HLADataElement* value);
69 class DataElementFactory : public SGReferenced {
71 virtual ~DataElementFactory();
72 virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
75 void setDataElementFactory(DataElementFactory* dataElementFactory);
76 DataElementFactory* getDataElementFactory();
79 HLADataElement* newElement(unsigned index);
81 typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
82 ElementVector _elementVector;
84 SGSharedPtr<DataElementFactory> _dataElementFactory;
87 // Holds an array of variants.
88 // Factors out common code for that use case.
89 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
91 HLAVariantArrayDataElement();
92 virtual ~HLAVariantArrayDataElement();
94 // Overwrite this from the abstract class, need some more checks here
95 virtual bool setDataType(const HLADataType* dataType);
97 virtual bool setNumElements(unsigned size);
98 virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
99 virtual unsigned getNumElements() const;
100 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
102 const HLAVariantDataElement* getElement(unsigned index) const;
103 HLAVariantDataElement* getElement(unsigned index);
104 HLAVariantDataElement* getOrCreateElement(unsigned index);
105 void setElement(unsigned index, HLAVariantDataElement* value);
107 typedef HLAVariantDataElement::DataElementFactory AlternativeDataElementFactory;
109 void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
110 AlternativeDataElementFactory* getAlternativeDataElementFactory();
113 HLAVariantDataElement* newElement();
115 typedef std::vector<SGSharedPtr<HLAVariantDataElement> > ElementVector;
116 ElementVector _elementVector;
118 SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
121 class HLAStringDataElement : public HLAAbstractArrayDataElement {
123 HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
124 HLAAbstractArrayDataElement(dataType)
126 HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
127 HLAAbstractArrayDataElement(dataType),
130 const std::string& getValue() const
132 void setValue(const std::string& value)
135 virtual bool setNumElements(unsigned count)
137 _value.resize(count);
140 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
142 HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
143 getElementDataType()->accept(visitor);
144 _value[i] = visitor.getValue();
148 virtual unsigned getNumElements() const
150 return _value.size();
152 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
154 HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
155 getElementDataType()->accept(visitor);
163 class HLAStringData {
166 _value(new HLAStringDataElement(0))
168 HLAStringData(const std::string& value) :
169 _value(new HLAStringDataElement(0))
170 { _value->setValue(value); }
172 operator const std::string&() const
173 { return _value->getValue(); }
174 HLAStringData& operator=(const std::string& value)
175 { _value->setValue(value); return *this; }
177 const std::string& getValue() const
178 { return _value->getValue(); }
179 void setValue(const std::string& value)
180 { _value->setValue(value); }
182 const HLAStringDataElement* getDataElement() const
183 { return _value.get(); }
184 HLAStringDataElement* getDataElement()
185 { return _value.get(); }
187 const HLAArrayDataType* getDataType() const
188 { return _value->getDataType(); }
189 void setDataType(const HLAArrayDataType* dataType)
190 { _value->setDataType(dataType); }
193 SGSharedPtr<HLAStringDataElement> _value;
197 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
199 HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
200 HLAAbstractArrayDataElement(dataType),
201 _value(SGVec2<T>::zeros())
203 HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
204 HLAAbstractArrayDataElement(dataType),
207 const SGVec2<T>& getValue() const
209 void setValue(const SGVec2<T>& value)
212 virtual bool setNumElements(unsigned count)
214 for (unsigned i = 2; i < count; ++i)
218 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
221 HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
222 getElementDataType()->accept(visitor);
223 _value[i] = visitor.getValue();
225 HLADataTypeDecodeVisitor visitor(stream);
226 getElementDataType()->accept(visitor);
231 virtual unsigned getNumElements() const
235 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
238 HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
239 getElementDataType()->accept(visitor);
241 HLADataTypeEncodeVisitor visitor(stream);
242 getElementDataType()->accept(visitor);
255 _value(new HLAVec2DataElement<T>(0))
257 HLAVec2Data(const SGVec2<T>& value) :
258 _value(new HLAVec2DataElement<T>(0, value))
261 operator const SGVec2<T>&() const
262 { return _value->getValue(); }
263 HLAVec2Data& operator=(const SGVec2<T>& value)
264 { _value->setValue(value); return *this; }
266 const SGVec2<T>& getValue() const
267 { return _value->getValue(); }
268 void setValue(const SGVec2<T>& value)
269 { _value->setValue(value); }
271 const HLAVec2DataElement<T>* getDataElement() const
272 { return _value.get(); }
273 HLAVec2DataElement<T>* getDataElement()
274 { return _value.get(); }
276 const HLAArrayDataType* getDataType() const
277 { return _value->getDataType(); }
278 void setDataType(const HLAArrayDataType* dataType)
279 { _value->setDataType(dataType); }
282 SGSharedPtr<HLAVec2DataElement<T> > _value;
285 typedef HLAVec2Data<float> HLAVec2fData;
286 typedef HLAVec2Data<double> HLAVec2dData;
289 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
291 HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
292 HLAAbstractArrayDataElement(dataType),
293 _value(SGVec3<T>::zeros())
295 HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
296 HLAAbstractArrayDataElement(dataType),
299 const SGVec3<T>& getValue() const
301 void setValue(const SGVec3<T>& value)
304 virtual bool setNumElements(unsigned count)
306 for (unsigned i = 3; i < count; ++i)
310 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
313 HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
314 getElementDataType()->accept(visitor);
315 _value[i] = visitor.getValue();
317 HLADataTypeDecodeVisitor visitor(stream);
318 getElementDataType()->accept(visitor);
323 virtual unsigned getNumElements() const
327 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
330 HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
331 getElementDataType()->accept(visitor);
333 HLADataTypeEncodeVisitor visitor(stream);
334 getElementDataType()->accept(visitor);
347 _value(new HLAVec3DataElement<T>(0))
349 HLAVec3Data(const SGVec3<T>& value) :
350 _value(new HLAVec3DataElement<T>(0, value))
353 operator const SGVec3<T>&() const
354 { return _value->getValue(); }
355 HLAVec3Data& operator=(const SGVec3<T>& value)
356 { _value->setValue(value); return *this; }
358 const SGVec3<T>& getValue() const
359 { return _value->getValue(); }
360 void setValue(const SGVec3<T>& value)
361 { _value->setValue(value); }
363 const HLAVec3DataElement<T>* getDataElement() const
364 { return _value.get(); }
365 HLAVec3DataElement<T>* getDataElement()
366 { return _value.get(); }
368 const HLAArrayDataType* getDataType() const
369 { return _value->getDataType(); }
370 void setDataType(const HLAArrayDataType* dataType)
371 { _value->setDataType(dataType); }
374 SGSharedPtr<HLAVec3DataElement<T> > _value;
377 typedef HLAVec3Data<float> HLAVec3fData;
378 typedef HLAVec3Data<double> HLAVec3dData;
381 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
383 HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
384 HLAAbstractArrayDataElement(dataType),
385 _value(SGVec4<T>::zeros())
387 HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
388 HLAAbstractArrayDataElement(dataType),
391 const SGVec4<T>& getValue() const
393 void setValue(const SGVec4<T>& value)
396 virtual bool setNumElements(unsigned count)
398 for (unsigned i = 4; i < count; ++i)
402 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
405 HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
406 getElementDataType()->accept(visitor);
407 _value[i] = visitor.getValue();
409 HLADataTypeDecodeVisitor visitor(stream);
410 getElementDataType()->accept(visitor);
415 virtual unsigned getNumElements() const
419 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
422 HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
423 getElementDataType()->accept(visitor);
425 HLADataTypeEncodeVisitor visitor(stream);
426 getElementDataType()->accept(visitor);
439 _value(new HLAVec4DataElement<T>(0))
441 HLAVec4Data(const SGVec4<T>& value) :
442 _value(new HLAVec4DataElement<T>(0, value))
445 operator const SGVec4<T>&() const
446 { return _value->getValue(); }
447 HLAVec4Data& operator=(const SGVec4<T>& value)
448 { _value->setValue(value); return *this; }
450 const SGVec4<T>& getValue() const
451 { return _value->getValue(); }
452 void setValue(const SGVec4<T>& value)
453 { _value->setValue(value); }
455 const HLAVec4DataElement<T>* getDataElement() const
456 { return _value.get(); }
457 HLAVec4DataElement<T>* getDataElement()
458 { return _value.get(); }
460 const HLAArrayDataType* getDataType() const
461 { return _value->getDataType(); }
462 void setDataType(const HLAArrayDataType* dataType)
463 { _value->setDataType(dataType); }
466 SGSharedPtr<HLAVec4DataElement<T> > _value;
469 typedef HLAVec4Data<float> HLAVec4fData;
470 typedef HLAVec4Data<double> HLAVec4dData;
473 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
475 HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
476 HLAAbstractArrayDataElement(dataType),
477 _value(SGQuat<T>::zeros())
479 HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
480 HLAAbstractArrayDataElement(dataType),
483 const SGQuat<T>& getValue() const
485 void setValue(const SGQuat<T>& value)
488 virtual bool setNumElements(unsigned count)
490 for (unsigned i = 4; i < count; ++i)
494 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
497 HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
498 getElementDataType()->accept(visitor);
499 _value[i] = visitor.getValue();
501 HLADataTypeDecodeVisitor visitor(stream);
502 getElementDataType()->accept(visitor);
507 virtual unsigned getNumElements() const
511 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
514 HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
515 getElementDataType()->accept(visitor);
517 HLADataTypeEncodeVisitor visitor(stream);
518 getElementDataType()->accept(visitor);