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 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 virtual void _setStamp(Stamp* stamp);
85 HLADataElement* newElement(unsigned index);
87 typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
88 ElementVector _elementVector;
90 SGSharedPtr<DataElementFactory> _dataElementFactory;
93 // Holds an array of variants.
94 // Factors out common code for that use case.
95 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
97 HLAVariantArrayDataElement();
98 virtual ~HLAVariantArrayDataElement();
100 // Overwrite this from the abstract class, need some more checks here
101 virtual bool setDataType(const HLADataType* dataType);
103 virtual bool setNumElements(unsigned size);
104 virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
105 virtual unsigned getNumElements() const;
106 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const;
108 const HLAVariantRecordDataElement* getElement(unsigned index) const;
109 HLAVariantRecordDataElement* getElement(unsigned index);
110 HLAVariantRecordDataElement* getOrCreateElement(unsigned index);
111 void setElement(unsigned index, HLAVariantRecordDataElement* value);
113 typedef HLAVariantRecordDataElement::DataElementFactory AlternativeDataElementFactory;
115 void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
116 AlternativeDataElementFactory* getAlternativeDataElementFactory();
119 virtual void _setStamp(Stamp* stamp);
122 HLAVariantRecordDataElement* newElement();
124 typedef std::vector<SGSharedPtr<HLAVariantRecordDataElement> > ElementVector;
125 ElementVector _elementVector;
127 SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
130 class HLAStringDataElement : public HLAAbstractArrayDataElement {
132 HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
133 HLAAbstractArrayDataElement(dataType)
135 HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
136 HLAAbstractArrayDataElement(dataType),
139 const std::string& getValue() const
141 void setValue(const std::string& value)
142 { _value = value; setDirty(true); }
144 virtual bool setNumElements(unsigned count)
146 _value.resize(count);
149 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
151 HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
152 getElementDataType()->accept(visitor);
153 _value[i] = visitor.getValue();
157 virtual unsigned getNumElements() const
159 return _value.size();
161 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
163 HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
164 getElementDataType()->accept(visitor);
172 class HLAStringData {
175 _value(new HLAStringDataElement(0))
177 HLAStringData(const std::string& value) :
178 _value(new HLAStringDataElement(0))
179 { _value->setValue(value); }
181 operator const std::string&() const
182 { return _value->getValue(); }
183 HLAStringData& operator=(const std::string& value)
184 { _value->setValue(value); return *this; }
186 const std::string& getValue() const
187 { return _value->getValue(); }
188 void setValue(const std::string& value)
189 { _value->setValue(value); }
191 const HLAStringDataElement* getDataElement() const
192 { return _value.get(); }
193 HLAStringDataElement* getDataElement()
194 { return _value.get(); }
196 const HLAArrayDataType* getDataType() const
197 { return _value->getDataType(); }
198 void setDataType(const HLAArrayDataType* dataType)
199 { _value->setDataType(dataType); }
202 SGSharedPtr<HLAStringDataElement> _value;
206 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
208 HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
209 HLAAbstractArrayDataElement(dataType),
210 _value(SGVec2<T>::zeros())
212 HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
213 HLAAbstractArrayDataElement(dataType),
216 const SGVec2<T>& getValue() const
218 void setValue(const SGVec2<T>& value)
219 { _value = value; setDirty(true); }
221 virtual bool setNumElements(unsigned count)
223 for (unsigned i = count; i < 2; ++i)
227 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
230 HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
231 getElementDataType()->accept(visitor);
232 _value[i] = visitor.getValue();
234 HLADataTypeDecodeVisitor visitor(stream);
235 getElementDataType()->accept(visitor);
240 virtual unsigned getNumElements() const
244 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
247 HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
248 getElementDataType()->accept(visitor);
250 HLADataTypeEncodeVisitor visitor(stream);
251 getElementDataType()->accept(visitor);
264 _value(new HLAVec2DataElement<T>(0))
266 HLAVec2Data(const SGVec2<T>& value) :
267 _value(new HLAVec2DataElement<T>(0, value))
270 operator const SGVec2<T>&() const
271 { return _value->getValue(); }
272 HLAVec2Data& operator=(const SGVec2<T>& value)
273 { _value->setValue(value); return *this; }
275 const SGVec2<T>& getValue() const
276 { return _value->getValue(); }
277 void setValue(const SGVec2<T>& value)
278 { _value->setValue(value); }
280 const HLAVec2DataElement<T>* getDataElement() const
281 { return _value.get(); }
282 HLAVec2DataElement<T>* getDataElement()
283 { return _value.get(); }
285 const HLAArrayDataType* getDataType() const
286 { return _value->getDataType(); }
287 void setDataType(const HLAArrayDataType* dataType)
288 { _value->setDataType(dataType); }
291 SGSharedPtr<HLAVec2DataElement<T> > _value;
294 typedef HLAVec2Data<float> HLAVec2fData;
295 typedef HLAVec2Data<double> HLAVec2dData;
298 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
300 HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
301 HLAAbstractArrayDataElement(dataType),
302 _value(SGVec3<T>::zeros())
304 HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
305 HLAAbstractArrayDataElement(dataType),
308 const SGVec3<T>& getValue() const
310 void setValue(const SGVec3<T>& value)
311 { _value = value; setDirty(true); }
313 virtual bool setNumElements(unsigned count)
315 for (unsigned i = count; i < 3; ++i)
319 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
322 HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
323 getElementDataType()->accept(visitor);
324 _value[i] = visitor.getValue();
326 HLADataTypeDecodeVisitor visitor(stream);
327 getElementDataType()->accept(visitor);
332 virtual unsigned getNumElements() const
336 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
339 HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
340 getElementDataType()->accept(visitor);
342 HLADataTypeEncodeVisitor visitor(stream);
343 getElementDataType()->accept(visitor);
356 _value(new HLAVec3DataElement<T>(0))
358 HLAVec3Data(const SGVec3<T>& value) :
359 _value(new HLAVec3DataElement<T>(0, value))
362 operator const SGVec3<T>&() const
363 { return _value->getValue(); }
364 HLAVec3Data& operator=(const SGVec3<T>& value)
365 { _value->setValue(value); return *this; }
367 const SGVec3<T>& getValue() const
368 { return _value->getValue(); }
369 void setValue(const SGVec3<T>& value)
370 { _value->setValue(value); }
372 const HLAVec3DataElement<T>* getDataElement() const
373 { return _value.get(); }
374 HLAVec3DataElement<T>* getDataElement()
375 { return _value.get(); }
377 const HLAArrayDataType* getDataType() const
378 { return _value->getDataType(); }
379 void setDataType(const HLAArrayDataType* dataType)
380 { _value->setDataType(dataType); }
383 SGSharedPtr<HLAVec3DataElement<T> > _value;
386 typedef HLAVec3Data<float> HLAVec3fData;
387 typedef HLAVec3Data<double> HLAVec3dData;
390 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
392 HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
393 HLAAbstractArrayDataElement(dataType),
394 _value(SGVec4<T>::zeros())
396 HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
397 HLAAbstractArrayDataElement(dataType),
400 const SGVec4<T>& getValue() const
402 void setValue(const SGVec4<T>& value)
403 { _value = value; setDirty(true); }
405 virtual bool setNumElements(unsigned count)
407 for (unsigned i = count; i < 4; ++i)
411 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
414 HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
415 getElementDataType()->accept(visitor);
416 _value[i] = visitor.getValue();
418 HLADataTypeDecodeVisitor visitor(stream);
419 getElementDataType()->accept(visitor);
424 virtual unsigned getNumElements() const
428 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
431 HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
432 getElementDataType()->accept(visitor);
434 HLADataTypeEncodeVisitor visitor(stream);
435 getElementDataType()->accept(visitor);
448 _value(new HLAVec4DataElement<T>(0))
450 HLAVec4Data(const SGVec4<T>& value) :
451 _value(new HLAVec4DataElement<T>(0, value))
454 operator const SGVec4<T>&() const
455 { return _value->getValue(); }
456 HLAVec4Data& operator=(const SGVec4<T>& value)
457 { _value->setValue(value); return *this; }
459 const SGVec4<T>& getValue() const
460 { return _value->getValue(); }
461 void setValue(const SGVec4<T>& value)
462 { _value->setValue(value); }
464 const HLAVec4DataElement<T>* getDataElement() const
465 { return _value.get(); }
466 HLAVec4DataElement<T>* getDataElement()
467 { return _value.get(); }
469 const HLAArrayDataType* getDataType() const
470 { return _value->getDataType(); }
471 void setDataType(const HLAArrayDataType* dataType)
472 { _value->setDataType(dataType); }
475 SGSharedPtr<HLAVec4DataElement<T> > _value;
478 typedef HLAVec4Data<float> HLAVec4fData;
479 typedef HLAVec4Data<double> HLAVec4dData;
482 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
484 HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
485 HLAAbstractArrayDataElement(dataType),
486 _value(SGQuat<T>::zeros())
488 HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
489 HLAAbstractArrayDataElement(dataType),
492 const SGQuat<T>& getValue() const
494 void setValue(const SGQuat<T>& value)
495 { _value = value; setDirty(true); }
497 virtual bool setNumElements(unsigned count)
499 for (unsigned i = count; i < 4; ++i)
503 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
506 HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
507 getElementDataType()->accept(visitor);
508 _value[i] = visitor.getValue();
510 HLADataTypeDecodeVisitor visitor(stream);
511 getElementDataType()->accept(visitor);
516 virtual unsigned getNumElements() const
520 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
523 HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
524 getElementDataType()->accept(visitor);
526 HLADataTypeEncodeVisitor visitor(stream);
527 getElementDataType()->accept(visitor);