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);
252 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
254 HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
255 HLAAbstractArrayDataElement(dataType),
256 _value(SGVec3<T>::zeros())
258 HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
259 HLAAbstractArrayDataElement(dataType),
262 const SGVec3<T>& getValue() const
264 void setValue(const SGVec3<T>& value)
267 virtual bool setNumElements(unsigned count)
269 for (unsigned i = 3; i < count; ++i)
273 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
276 HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
277 getElementDataType()->accept(visitor);
278 _value[i] = visitor.getValue();
280 HLADataTypeDecodeVisitor visitor(stream);
281 getElementDataType()->accept(visitor);
286 virtual unsigned getNumElements() const
290 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
293 HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
294 getElementDataType()->accept(visitor);
296 HLADataTypeEncodeVisitor visitor(stream);
297 getElementDataType()->accept(visitor);
307 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
309 HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
310 HLAAbstractArrayDataElement(dataType),
311 _value(SGVec4<T>::zeros())
313 HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
314 HLAAbstractArrayDataElement(dataType),
317 const SGVec4<T>& getValue() const
319 void setValue(const SGVec4<T>& value)
322 virtual bool setNumElements(unsigned count)
324 for (unsigned i = 4; i < count; ++i)
328 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
331 HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
332 getElementDataType()->accept(visitor);
333 _value[i] = visitor.getValue();
335 HLADataTypeDecodeVisitor visitor(stream);
336 getElementDataType()->accept(visitor);
341 virtual unsigned getNumElements() const
345 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
348 HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
349 getElementDataType()->accept(visitor);
351 HLADataTypeEncodeVisitor visitor(stream);
352 getElementDataType()->accept(visitor);
362 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
364 HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
365 HLAAbstractArrayDataElement(dataType),
366 _value(SGQuat<T>::zeros())
368 HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
369 HLAAbstractArrayDataElement(dataType),
372 const SGQuat<T>& getValue() const
374 void setValue(const SGQuat<T>& value)
377 virtual bool setNumElements(unsigned count)
379 for (unsigned i = 4; i < count; ++i)
383 virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
386 HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
387 getElementDataType()->accept(visitor);
388 _value[i] = visitor.getValue();
390 HLADataTypeDecodeVisitor visitor(stream);
391 getElementDataType()->accept(visitor);
396 virtual unsigned getNumElements() const
400 virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
403 HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
404 getElementDataType()->accept(visitor);
406 HLADataTypeEncodeVisitor visitor(stream);
407 getElementDataType()->accept(visitor);