]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAArrayDataElement.hxx
Merge branch 'timoore/optimizations' into next
[simgear.git] / simgear / hla / HLAArrayDataElement.hxx
1 // Copyright (C) 2009 - 2012  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 "HLAVariantRecordDataElement.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 void accept(HLADataElementVisitor& visitor);
37     virtual void accept(HLAConstDataElementVisitor& visitor) const;
38
39     virtual bool decode(HLADecodeStream& stream);
40     virtual bool encode(HLAEncodeStream& stream) const;
41
42     virtual const HLAArrayDataType* getDataType() const;
43     virtual bool setDataType(const HLADataType* dataType);
44
45     const HLADataType* getElementDataType() const;
46
47     virtual bool setNumElements(unsigned count) = 0;
48     virtual bool decodeElement(HLADecodeStream& stream, unsigned i) = 0;
49
50     virtual unsigned getNumElements() const = 0;
51     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const = 0;
52
53 protected:
54     SGSharedPtr<const HLAArrayDataType> _dataType;
55 };
56
57 class HLAArrayDataElement : public HLAAbstractArrayDataElement {
58 public:
59     HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
60     virtual ~HLAArrayDataElement();
61
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;
66
67     const HLADataElement* getElement(unsigned index) const;
68     HLADataElement* getElement(unsigned index);
69     HLADataElement* getOrCreateElement(unsigned index);
70     void setElement(unsigned i, HLADataElement* value);
71
72     class DataElementFactory : public SGReferenced {
73     public:
74         virtual ~DataElementFactory();
75         virtual HLADataElement* createElement(const HLAArrayDataElement&, unsigned) = 0;
76     };
77
78     void setDataElementFactory(DataElementFactory* dataElementFactory);
79     DataElementFactory* getDataElementFactory();
80
81 protected:
82     virtual void _setStamp(Stamp* stamp);
83
84 private:
85     HLADataElement* newElement(unsigned index);
86
87     typedef std::vector<SGSharedPtr<HLADataElement> > ElementVector;
88     ElementVector _elementVector;
89
90     SGSharedPtr<DataElementFactory> _dataElementFactory;
91 };
92
93 // Holds an array of variants.
94 // Factors out common code for that use case.
95 class HLAVariantArrayDataElement : public HLAAbstractArrayDataElement {
96 public:
97     HLAVariantArrayDataElement();
98     virtual ~HLAVariantArrayDataElement();
99
100     // Overwrite this from the abstract class, need some more checks here
101     virtual bool setDataType(const HLADataType* dataType);
102
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;
107
108     const HLAVariantRecordDataElement* getElement(unsigned index) const;
109     HLAVariantRecordDataElement* getElement(unsigned index);
110     HLAVariantRecordDataElement* getOrCreateElement(unsigned index);
111     void setElement(unsigned index, HLAVariantRecordDataElement* value);
112
113     typedef HLAVariantRecordDataElement::DataElementFactory AlternativeDataElementFactory;
114
115     void setAlternativeDataElementFactory(AlternativeDataElementFactory* alternativeDataElementFactory);
116     AlternativeDataElementFactory* getAlternativeDataElementFactory();
117
118 protected:
119     virtual void _setStamp(Stamp* stamp);
120
121 private:
122     HLAVariantRecordDataElement* newElement();
123
124     typedef std::vector<SGSharedPtr<HLAVariantRecordDataElement> > ElementVector;
125     ElementVector _elementVector;
126
127     SGSharedPtr<AlternativeDataElementFactory> _alternativeDataElementFactory;
128 };
129
130 class HLAStringDataElement : public HLAAbstractArrayDataElement {
131 public:
132     HLAStringDataElement(const HLAArrayDataType* dataType = 0) :
133         HLAAbstractArrayDataElement(dataType)
134     {}
135     HLAStringDataElement(const HLAArrayDataType* dataType, const std::string& value) :
136         HLAAbstractArrayDataElement(dataType),
137         _value(value)
138     {}
139     const std::string& getValue() const
140     { return _value; }
141     void setValue(const std::string& value)
142     { _value = value; setDirty(true); }
143
144     virtual bool setNumElements(unsigned count)
145     {
146         _value.resize(count);
147         return true;
148     }
149     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
150     {
151         HLATemplateDecodeVisitor<std::string::value_type> visitor(stream);
152         getElementDataType()->accept(visitor);
153         _value[i] = visitor.getValue();
154         return true;
155     }
156
157     virtual unsigned getNumElements() const
158     {
159         return _value.size();
160     }
161     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
162     {
163         HLATemplateEncodeVisitor<std::string::value_type> visitor(stream, _value[i]);
164         getElementDataType()->accept(visitor);
165         return true;
166     }
167
168 private:
169     std::string _value;
170 };
171
172 class HLAStringData {
173 public:
174     HLAStringData() :
175         _value(new HLAStringDataElement(0))
176     { }
177     HLAStringData(const std::string& value) :
178         _value(new HLAStringDataElement(0))
179     { _value->setValue(value); }
180
181     operator const std::string&() const
182     { return _value->getValue(); }
183     HLAStringData& operator=(const std::string& value)
184     { _value->setValue(value); return *this; }
185
186     const std::string& getValue() const
187     { return _value->getValue(); }
188     void setValue(const std::string& value)
189     { _value->setValue(value); }
190
191     const HLAStringDataElement* getDataElement() const
192     { return _value.get(); }
193     HLAStringDataElement* getDataElement()
194     { return _value.get(); }
195
196     const HLAArrayDataType* getDataType() const
197     { return _value->getDataType(); }
198     void setDataType(const HLAArrayDataType* dataType)
199     { _value->setDataType(dataType); }
200
201 private:
202     SGSharedPtr<HLAStringDataElement> _value;
203 };
204
205 template<typename T>
206 class HLAVec2DataElement : public HLAAbstractArrayDataElement {
207 public:
208     HLAVec2DataElement(const HLAArrayDataType* dataType = 0) :
209         HLAAbstractArrayDataElement(dataType),
210         _value(SGVec2<T>::zeros())
211     {}
212     HLAVec2DataElement(const HLAArrayDataType* dataType, const SGVec2<T>& value) :
213         HLAAbstractArrayDataElement(dataType),
214         _value(value)
215     {}
216     const SGVec2<T>& getValue() const
217     { return _value; }
218     void setValue(const SGVec2<T>& value)
219     { _value = value; setDirty(true); }
220
221     virtual bool setNumElements(unsigned count)
222     {
223         for (unsigned i = count; i < 2; ++i)
224             _value[i] = 0;
225         return true;
226     }
227     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
228     {
229         if (i < 2) {
230             HLATemplateDecodeVisitor<typename SGVec2<T>::value_type> visitor(stream);
231             getElementDataType()->accept(visitor);
232             _value[i] = visitor.getValue();
233         } else {
234             HLADataTypeDecodeVisitor visitor(stream);
235             getElementDataType()->accept(visitor);
236         }
237         return true;
238     }
239
240     virtual unsigned getNumElements() const
241     {
242         return 2;
243     }
244     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
245     {
246         if (i < 2) {
247             HLATemplateEncodeVisitor<typename SGVec2<T>::value_type> visitor(stream, _value[i]);
248             getElementDataType()->accept(visitor);
249         } else {
250             HLADataTypeEncodeVisitor visitor(stream);
251             getElementDataType()->accept(visitor);
252         }
253         return true;
254     }
255
256 private:
257     SGVec2<T> _value;
258 };
259
260 template<typename T>
261 class HLAVec2Data {
262 public:
263     HLAVec2Data() :
264         _value(new HLAVec2DataElement<T>(0))
265     { }
266     HLAVec2Data(const SGVec2<T>& value) :
267         _value(new HLAVec2DataElement<T>(0, value))
268     { }
269
270     operator const SGVec2<T>&() const
271     { return _value->getValue(); }
272     HLAVec2Data& operator=(const SGVec2<T>& value)
273     { _value->setValue(value); return *this; }
274
275     const SGVec2<T>& getValue() const
276     { return _value->getValue(); }
277     void setValue(const SGVec2<T>& value)
278     { _value->setValue(value); }
279
280     const HLAVec2DataElement<T>* getDataElement() const
281     { return _value.get(); }
282     HLAVec2DataElement<T>* getDataElement()
283     { return _value.get(); }
284
285     const HLAArrayDataType* getDataType() const
286     { return _value->getDataType(); }
287     void setDataType(const HLAArrayDataType* dataType)
288     { _value->setDataType(dataType); }
289
290 private:
291     SGSharedPtr<HLAVec2DataElement<T> > _value;
292 };
293
294 typedef HLAVec2Data<float> HLAVec2fData;
295 typedef HLAVec2Data<double> HLAVec2dData;
296
297 template<typename T>
298 class HLAVec3DataElement : public HLAAbstractArrayDataElement {
299 public:
300     HLAVec3DataElement(const HLAArrayDataType* dataType = 0) :
301         HLAAbstractArrayDataElement(dataType),
302         _value(SGVec3<T>::zeros())
303     {}
304     HLAVec3DataElement(const HLAArrayDataType* dataType, const SGVec3<T>& value) :
305         HLAAbstractArrayDataElement(dataType),
306         _value(value)
307     {}
308     const SGVec3<T>& getValue() const
309     { return _value; }
310     void setValue(const SGVec3<T>& value)
311     { _value = value; setDirty(true); }
312
313     virtual bool setNumElements(unsigned count)
314     {
315         for (unsigned i = count; i < 3; ++i)
316             _value[i] = 0;
317         return true;
318     }
319     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
320     {
321         if (i < 3) {
322             HLATemplateDecodeVisitor<typename SGVec3<T>::value_type> visitor(stream);
323             getElementDataType()->accept(visitor);
324             _value[i] = visitor.getValue();
325         } else {
326             HLADataTypeDecodeVisitor visitor(stream);
327             getElementDataType()->accept(visitor);
328         }
329         return true;
330     }
331
332     virtual unsigned getNumElements() const
333     {
334         return 3;
335     }
336     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
337     {
338         if (i < 3) {
339             HLATemplateEncodeVisitor<typename SGVec3<T>::value_type> visitor(stream, _value[i]);
340             getElementDataType()->accept(visitor);
341         } else {
342             HLADataTypeEncodeVisitor visitor(stream);
343             getElementDataType()->accept(visitor);
344         }
345         return true;
346     }
347
348 private:
349     SGVec3<T> _value;
350 };
351
352 template<typename T>
353 class HLAVec3Data {
354 public:
355     HLAVec3Data() :
356         _value(new HLAVec3DataElement<T>(0))
357     { }
358     HLAVec3Data(const SGVec3<T>& value) :
359         _value(new HLAVec3DataElement<T>(0, value))
360     { }
361
362     operator const SGVec3<T>&() const
363     { return _value->getValue(); }
364     HLAVec3Data& operator=(const SGVec3<T>& value)
365     { _value->setValue(value); return *this; }
366
367     const SGVec3<T>& getValue() const
368     { return _value->getValue(); }
369     void setValue(const SGVec3<T>& value)
370     { _value->setValue(value); }
371
372     const HLAVec3DataElement<T>* getDataElement() const
373     { return _value.get(); }
374     HLAVec3DataElement<T>* getDataElement()
375     { return _value.get(); }
376
377     const HLAArrayDataType* getDataType() const
378     { return _value->getDataType(); }
379     void setDataType(const HLAArrayDataType* dataType)
380     { _value->setDataType(dataType); }
381
382 private:
383     SGSharedPtr<HLAVec3DataElement<T> > _value;
384 };
385
386 typedef HLAVec3Data<float> HLAVec3fData;
387 typedef HLAVec3Data<double> HLAVec3dData;
388
389 template<typename T>
390 class HLAVec4DataElement : public HLAAbstractArrayDataElement {
391 public:
392     HLAVec4DataElement(const HLAArrayDataType* dataType = 0) :
393         HLAAbstractArrayDataElement(dataType),
394         _value(SGVec4<T>::zeros())
395     {}
396     HLAVec4DataElement(const HLAArrayDataType* dataType, const SGVec4<T>& value) :
397         HLAAbstractArrayDataElement(dataType),
398         _value(value)
399     {}
400     const SGVec4<T>& getValue() const
401     { return _value; }
402     void setValue(const SGVec4<T>& value)
403     { _value = value; setDirty(true); }
404
405     virtual bool setNumElements(unsigned count)
406     {
407         for (unsigned i = count; i < 4; ++i)
408             _value[i] = 0;
409         return true;
410     }
411     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
412     {
413         if (i < 4) {
414             HLATemplateDecodeVisitor<typename SGVec4<T>::value_type> visitor(stream);
415             getElementDataType()->accept(visitor);
416             _value[i] = visitor.getValue();
417         } else {
418             HLADataTypeDecodeVisitor visitor(stream);
419             getElementDataType()->accept(visitor);
420         }
421         return true;
422     }
423
424     virtual unsigned getNumElements() const
425     {
426         return 4;
427     }
428     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
429     {
430         if (i < 4) {
431             HLATemplateEncodeVisitor<typename SGVec4<T>::value_type> visitor(stream, _value[i]);
432             getElementDataType()->accept(visitor);
433         } else {
434             HLADataTypeEncodeVisitor visitor(stream);
435             getElementDataType()->accept(visitor);
436         }
437         return true;
438     }
439
440 private:
441     SGVec4<T> _value;
442 };
443
444 template<typename T>
445 class HLAVec4Data {
446 public:
447     HLAVec4Data() :
448         _value(new HLAVec4DataElement<T>(0))
449     { }
450     HLAVec4Data(const SGVec4<T>& value) :
451         _value(new HLAVec4DataElement<T>(0, value))
452     { }
453
454     operator const SGVec4<T>&() const
455     { return _value->getValue(); }
456     HLAVec4Data& operator=(const SGVec4<T>& value)
457     { _value->setValue(value); return *this; }
458
459     const SGVec4<T>& getValue() const
460     { return _value->getValue(); }
461     void setValue(const SGVec4<T>& value)
462     { _value->setValue(value); }
463
464     const HLAVec4DataElement<T>* getDataElement() const
465     { return _value.get(); }
466     HLAVec4DataElement<T>* getDataElement()
467     { return _value.get(); }
468
469     const HLAArrayDataType* getDataType() const
470     { return _value->getDataType(); }
471     void setDataType(const HLAArrayDataType* dataType)
472     { _value->setDataType(dataType); }
473
474 private:
475     SGSharedPtr<HLAVec4DataElement<T> > _value;
476 };
477
478 typedef HLAVec4Data<float> HLAVec4fData;
479 typedef HLAVec4Data<double> HLAVec4dData;
480
481 template<typename T>
482 class HLAQuatDataElement : public HLAAbstractArrayDataElement {
483 public:
484     HLAQuatDataElement(const HLAArrayDataType* dataType = 0) :
485         HLAAbstractArrayDataElement(dataType),
486         _value(SGQuat<T>::zeros())
487     {}
488     HLAQuatDataElement(const HLAArrayDataType* dataType, const SGQuat<T>& value) :
489         HLAAbstractArrayDataElement(dataType),
490         _value(value)
491     {}
492     const SGQuat<T>& getValue() const
493     { return _value; }
494     void setValue(const SGQuat<T>& value)
495     { _value = value; setDirty(true); }
496
497     virtual bool setNumElements(unsigned count)
498     {
499         for (unsigned i = count; i < 4; ++i)
500             _value[i] = 0;
501         return true;
502     }
503     virtual bool decodeElement(HLADecodeStream& stream, unsigned i)
504     {
505         if (i < 4) {
506             HLATemplateDecodeVisitor<typename SGQuat<T>::value_type> visitor(stream);
507             getElementDataType()->accept(visitor);
508             _value[i] = visitor.getValue();
509         } else {
510             HLADataTypeDecodeVisitor visitor(stream);
511             getElementDataType()->accept(visitor);
512         }
513         return true;
514     }
515
516     virtual unsigned getNumElements() const
517     {
518         return 4;
519     }
520     virtual bool encodeElement(HLAEncodeStream& stream, unsigned i) const
521     {
522         if (i < 4) {
523             HLATemplateEncodeVisitor<typename SGQuat<T>::value_type> visitor(stream, _value[i]);
524             getElementDataType()->accept(visitor);
525         } else {
526             HLADataTypeEncodeVisitor visitor(stream);
527             getElementDataType()->accept(visitor);
528         }
529         return true;
530     }
531
532 private:
533     SGQuat<T> _value;
534 };
535
536 }
537
538 #endif