]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAArrayDataElement.hxx
Merge remote branch 'origin/releases/2.2.0' into next
[simgear.git] / simgear / hla / HLAArrayDataElement.hxx
1 // Copyright (C) 2009 - 2010  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
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.
7 //
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.
12 //
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.
16 //
17
18 #ifndef HLAArrayDataElement_hxx
19 #define HLAArrayDataElement_hxx
20
21 #include <string>
22 #include <vector>
23 #include <simgear/math/SGMath.hxx>
24 #include "HLAArrayDataType.hxx"
25 #include "HLADataElement.hxx"
26 #include "HLAVariantDataElement.hxx"
27 #include "HLADataTypeVisitor.hxx"
28
29 namespace simgear {
30
31 class HLAAbstractArrayDataElement : public HLADataElement {
32 public:
33     HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
34     virtual ~HLAAbstractArrayDataElement();
35
36     virtual bool decode(HLADecodeStream& stream);
37     virtual bool encode(HLAEncodeStream& stream) const;
38
39     virtual const HLAArrayDataType* getDataType() const;
40     virtual bool setDataType(const HLADataType* dataType);
41
42     const HLADataType* getElementDataType() const;
43
44     virtual bool setNumElements(unsigned count) = 0;
45     virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
46
47     virtual unsigned getNumElements() const = 0;
48     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
49
50 protected:
51     SGSharedPtr<const HLAArrayDataType> _dataType;
52 };
53
54 class HLAArrayDataElement : public HLAAbstractArrayDataElement {
55 public:
56     HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
57     virtual ~HLAArrayDataElement();
58
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;
63
64     const HLADataElement* getElement(unsigned index) const;
65     HLADataElement* getElement(unsigned index);
66     HLADataElement* getOrCreateElement(unsigned index);
67     void setElement(unsigned i, HLADataElement* value);
68
69     class DataElementFactory : public SGReferenced {
70     public:
71         virtual ~DataElementFactory();
72         virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
73     };
74
75     void setDataElementFactory(DataElementFactory* dataElementFactory);
76     DataElementFactory* getDataElementFactory();
77
78 private:
79     HLADataElement* newElement(unsigned index);
80
81     typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
82     ElementVector _elementVector;
83
84     SGSharedPtr<DataElementFactory> _dataElementFactory;
85 };
86
87 // Holds an array of variants.
88 // Factors out common code for that use case.
89 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
90 public:
91     HLAVariantArrayDataElement();
92     virtual ~HLAVariantArrayDataElement();
93
94     // Overwrite this from the abstract class, need some more checks here
95     virtual bool setDataType(const HLADataType* dataType);
96
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;
101
102     const HLAVariantDataElement* getElement(unsigned index) const;
103     HLAVariantDataElement* getElement(unsigned index);
104     HLAVariantDataElement* getOrCreateElement(unsigned index);
105     void setElement(unsigned index, HLAVariantDataElement* value);
106
107     typedef HLAVariantDataElement::DataElementFactory AlternativeDataElementFactory;
108
109     void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
110     AlternativeDataElementFactory* getAlternativeDataElementFactory();
111
112 private:
113     HLAVariantDataElement* newElement();
114
115     typedef std::vector<SGSharedPtr<HLAVariantDataElement> > ElementVector;
116     ElementVector _elementVector;
117
118     SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
119 };
120
121 class HLAStringDataElement : public HLAAbstractArrayDataElement {
122 public:
123     HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
124         HLAAbstractArrayDataElement(dataType)
125     {}
126     HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
127         HLAAbstractArrayDataElement(dataType),
128         _value(value)
129     {}
130     const std::string& getValue() const
131     { return _value; }
132     void setValue(const std::string& value)
133     { _value = value; }
134
135     virtual bool setNumElements(unsigned count)
136     {
137         _value.resize(count);
138         return true;
139     }
140     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
141     {
142         HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
143         getElementDataType()->accept(visitor);
144         _value[i] = visitor.getValue();
145         return true;
146     }
147
148     virtual unsigned getNumElements() const
149     {
150         return _value.size();
151     }
152     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
153     {
154         HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
155         getElementDataType()->accept(visitor);
156         return true;
157     }
158
159 private:
160     std::string _value;
161 };
162
163 class HLAStringData {
164 public:
165     HLAStringData() :
166         _value(new HLAStringDataElement(0))
167     { }
168     HLAStringData(const std::string& value) :
169         _value(new HLAStringDataElement(0))
170     { _value->setValue(value); }
171
172     operator const std::string&() const
173     { return _value->getValue(); }
174     HLAStringData& operator=(const std::string& value)
175     { _value->setValue(value); return *this; }
176
177     const std::string& getValue() const
178     { return _value->getValue(); }
179     void setValue(const std::string& value)
180     { _value->setValue(value); }
181
182     const HLAStringDataElement* getDataElement() const
183     { return _value.get(); }
184     HLAStringDataElement* getDataElement()
185     { return _value.get(); }
186
187     const HLAArrayDataType* getDataType() const
188     { return _value->getDataType(); }
189     void setDataType(const HLAArrayDataType* dataType)
190     { _value->setDataType(dataType); }
191
192 private:
193     SGSharedPtr<HLAStringDataElement> _value;
194 };
195
196 template<typename T>
197 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
198 public:
199     HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
200         HLAAbstractArrayDataElement(dataType),
201         _value(SGVec2<T>::zeros())
202     {}
203     HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
204         HLAAbstractArrayDataElement(dataType),
205         _value(value)
206     {}
207     const SGVec2<T>& getValue() const
208     { return _value; }
209     void setValue(const SGVec2<T>& value)
210     { _value = value; }
211
212     virtual bool setNumElements(unsigned count)
213     {
214         for (unsigned i = 2; i < count; ++i)
215             _value[i] = 0;
216         return true;
217     }
218     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
219     {
220         if (i < 2) {
221             HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
222             getElementDataType()->accept(visitor);
223             _value[i] = visitor.getValue();
224         } else {
225             HLADataTypeDecodeVisitor visitor(stream);
226             getElementDataType()->accept(visitor);
227         }
228         return true;
229     }
230
231     virtual unsigned getNumElements() const
232     {
233         return 2;
234     }
235     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
236     {
237         if (i < 2) {
238             HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
239             getElementDataType()->accept(visitor);
240         } else {
241             HLADataTypeEncodeVisitor visitor(stream);
242             getElementDataType()->accept(visitor);
243         }
244         return true;
245     }
246
247 private:
248     SGVec2<T> _value;
249 };
250
251 template<typename T>
252 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
253 public:
254     HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
255         HLAAbstractArrayDataElement(dataType),
256         _value(SGVec3<T>::zeros())
257     {}
258     HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
259         HLAAbstractArrayDataElement(dataType),
260         _value(value)
261     {}
262     const SGVec3<T>& getValue() const
263     { return _value; }
264     void setValue(const SGVec3<T>& value)
265     { _value = value; }
266
267     virtual bool setNumElements(unsigned count)
268     {
269         for (unsigned i = 3; i < count; ++i)
270             _value[i] = 0;
271         return true;
272     }
273     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
274     {
275         if (i < 3) {
276             HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
277             getElementDataType()->accept(visitor);
278             _value[i] = visitor.getValue();
279         } else {
280             HLADataTypeDecodeVisitor visitor(stream);
281             getElementDataType()->accept(visitor);
282         }
283         return true;
284     }
285
286     virtual unsigned getNumElements() const
287     {
288         return 3;
289     }
290     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
291     {
292         if (i < 3) {
293             HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
294             getElementDataType()->accept(visitor);
295         } else {
296             HLADataTypeEncodeVisitor visitor(stream);
297             getElementDataType()->accept(visitor);
298         }
299         return true;
300     }
301
302 private:
303     SGVec3<T> _value;
304 };
305
306 template<typename T>
307 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
308 public:
309     HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
310         HLAAbstractArrayDataElement(dataType),
311         _value(SGVec4<T>::zeros())
312     {}
313     HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
314         HLAAbstractArrayDataElement(dataType),
315         _value(value)
316     {}
317     const SGVec4<T>& getValue() const
318     { return _value; }
319     void setValue(const SGVec4<T>& value)
320     { _value = value; }
321
322     virtual bool setNumElements(unsigned count)
323     {
324         for (unsigned i = 4; i < count; ++i)
325             _value[i] = 0;
326         return true;
327     }
328     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
329     {
330         if (i < 4) {
331             HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
332             getElementDataType()->accept(visitor);
333             _value[i] = visitor.getValue();
334         } else {
335             HLADataTypeDecodeVisitor visitor(stream);
336             getElementDataType()->accept(visitor);
337         }
338         return true;
339     }
340
341     virtual unsigned getNumElements() const
342     {
343         return 4;
344     }
345     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
346     {
347         if (i < 4) {
348             HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
349             getElementDataType()->accept(visitor);
350         } else {
351             HLADataTypeEncodeVisitor visitor(stream);
352             getElementDataType()->accept(visitor);
353         }
354         return true;
355     }
356
357 private:
358     SGVec4<T> _value;
359 };
360
361 template<typename T>
362 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
363 public:
364     HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
365         HLAAbstractArrayDataElement(dataType),
366         _value(SGQuat<T>::zeros())
367     {}
368     HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
369         HLAAbstractArrayDataElement(dataType),
370         _value(value)
371     {}
372     const SGQuat<T>& getValue() const
373     { return _value; }
374     void setValue(const SGQuat<T>& value)
375     { _value = value; }
376
377     virtual bool setNumElements(unsigned count)
378     {
379         for (unsigned i = 4; i < count; ++i)
380             _value[i] = 0;
381         return true;
382     }
383     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
384     {
385         if (i < 4) {
386             HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
387             getElementDataType()->accept(visitor);
388             _value[i] = visitor.getValue();
389         } else {
390             HLADataTypeDecodeVisitor visitor(stream);
391             getElementDataType()->accept(visitor);
392         }
393         return true;
394     }
395
396     virtual unsigned getNumElements() const
397     {
398         return 4;
399     }
400     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
401     {
402         if (i < 4) {
403             HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
404             getElementDataType()->accept(visitor);
405         } else {
406             HLADataTypeEncodeVisitor visitor(stream);
407             getElementDataType()->accept(visitor);
408         }
409         return true;
410     }
411
412 private:
413     SGQuat<T> _value;
414 };
415
416 }
417
418 #endif