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