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 HLADataTypeVisitor_hxx
19 #define HLADataTypeVisitor_hxx
23 #include <simgear/debug/logstream.hxx>
24 #include <simgear/math/SGMath.hxx>
25 #include "HLAArrayDataType.hxx"
26 #include "HLABasicDataType.hxx"
27 #include "HLADataElement.hxx"
28 #include "HLAEnumeratedDataType.hxx"
29 #include "HLAFixedRecordDataType.hxx"
30 #include "HLAVariantRecordDataType.hxx"
34 class HLADataTypeVisitor {
36 virtual ~HLADataTypeVisitor() {}
38 virtual void apply(const HLADataType& dataType)
41 virtual void apply(const HLABasicDataType& dataType)
42 { apply(static_cast<const HLADataType&>(dataType)); }
43 virtual void apply(const HLAInt8DataType& dataType)
44 { apply(static_cast<const HLABasicDataType&>(dataType)); }
45 virtual void apply(const HLAUInt8DataType& dataType)
46 { apply(static_cast<const HLABasicDataType&>(dataType)); }
47 virtual void apply(const HLAInt16DataType& dataType)
48 { apply(static_cast<const HLABasicDataType&>(dataType)); }
49 virtual void apply(const HLAUInt16DataType& dataType)
50 { apply(static_cast<const HLABasicDataType&>(dataType)); }
51 virtual void apply(const HLAInt32DataType& dataType)
52 { apply(static_cast<const HLABasicDataType&>(dataType)); }
53 virtual void apply(const HLAUInt32DataType& dataType)
54 { apply(static_cast<const HLABasicDataType&>(dataType)); }
55 virtual void apply(const HLAInt64DataType& dataType)
56 { apply(static_cast<const HLABasicDataType&>(dataType)); }
57 virtual void apply(const HLAUInt64DataType& dataType)
58 { apply(static_cast<const HLABasicDataType&>(dataType)); }
59 virtual void apply(const HLAFloat32DataType& dataType)
60 { apply(static_cast<const HLABasicDataType&>(dataType)); }
61 virtual void apply(const HLAFloat64DataType& dataType)
62 { apply(static_cast<const HLABasicDataType&>(dataType)); }
64 virtual void apply(const HLAArrayDataType& dataType)
65 { apply(static_cast<const HLADataType&>(dataType)); }
66 virtual void apply(const HLAFixedArrayDataType& dataType)
67 { apply(static_cast<const HLAArrayDataType&>(dataType)); }
68 virtual void apply(const HLAVariableArrayDataType& dataType)
69 { apply(static_cast<const HLAArrayDataType&>(dataType)); }
71 virtual void apply(const HLAEnumeratedDataType& dataType)
72 { apply(static_cast<const HLADataType&>(dataType)); }
74 virtual void apply(const HLAFixedRecordDataType& dataType)
75 { apply(static_cast<const HLADataType&>(dataType)); }
77 virtual void apply(const HLAVariantRecordDataType& dataType)
78 { apply(static_cast<const HLADataType&>(dataType)); }
81 /// Walks the datatype tree and checks if it is completely defined
82 class HLADataTypeCheckVisitor : public HLADataTypeVisitor {
84 HLADataTypeCheckVisitor() : _valid(true) {}
86 bool valid() const { return _valid; }
88 virtual void apply(const HLAInt8DataType& dataType) { }
89 virtual void apply(const HLAUInt8DataType& dataType) { }
90 virtual void apply(const HLAInt16DataType& dataType) { }
91 virtual void apply(const HLAUInt16DataType& dataType) { }
92 virtual void apply(const HLAInt32DataType& dataType) { }
93 virtual void apply(const HLAUInt32DataType& dataType) { }
94 virtual void apply(const HLAInt64DataType& dataType) { }
95 virtual void apply(const HLAUInt64DataType& dataType) { }
96 virtual void apply(const HLAFloat32DataType& dataType) { }
97 virtual void apply(const HLAFloat64DataType& dataType) { }
99 virtual void apply(const HLAFixedArrayDataType& dataType)
101 if (!dataType.getElementDataType())
104 dataType.getElementDataType()->accept(*this);
106 virtual void apply(const HLAVariableArrayDataType& dataType)
108 if (!dataType.getElementDataType())
111 dataType.getElementDataType()->accept(*this);
113 if (!dataType.getSizeDataType())
116 dataType.getSizeDataType()->accept(*this);
119 virtual void apply(const HLAEnumeratedDataType& dataType)
121 if (!dataType.getRepresentation())
124 dataType.getRepresentation()->accept(*this);
127 virtual void apply(const HLAFixedRecordDataType& dataType)
129 unsigned numFields = dataType.getNumFields();
130 for (unsigned i = 0; i < numFields; ++i) {
131 if (!dataType.getFieldDataType(i))
134 dataType.getFieldDataType(i)->accept(*this);
138 virtual void apply(const HLAVariantRecordDataType& dataType)
145 class HLADataTypeDecodeVisitor : public HLADataTypeVisitor {
147 HLADataTypeDecodeVisitor(HLADecodeStream& stream) : _stream(stream) {}
148 virtual ~HLADataTypeDecodeVisitor() {}
150 virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
151 virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
152 virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
153 virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
154 virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
155 virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
156 virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
157 virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
158 virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
159 virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
161 virtual void apply(const HLAFixedArrayDataType& dataType)
163 unsigned numElements = dataType.getNumElements();
164 for (unsigned i = 0; i < numElements; ++i)
165 dataType.getElementDataType()->accept(*this);
167 virtual void apply(const HLAVariableArrayDataType& dataType);
169 virtual void apply(const HLAEnumeratedDataType& dataType)
171 dataType.getRepresentation()->accept(*this);
174 virtual void apply(const HLAFixedRecordDataType& dataType)
176 unsigned numFields = dataType.getNumFields();
177 for (unsigned i = 0; i < numFields; ++i)
178 dataType.getFieldDataType(i)->accept(*this);
181 virtual void apply(const HLAVariantRecordDataType& dataType) { assert(0); }
184 HLADecodeStream& _stream;
187 class HLADataTypeEncodeVisitor : public HLADataTypeVisitor {
189 HLADataTypeEncodeVisitor(HLAEncodeStream& stream) : _stream(stream) {}
190 virtual ~HLADataTypeEncodeVisitor() {}
192 virtual void apply(const HLAInt8DataType& dataType) { dataType.skip(_stream); }
193 virtual void apply(const HLAUInt8DataType& dataType) { dataType.skip(_stream); }
194 virtual void apply(const HLAInt16DataType& dataType) { dataType.skip(_stream); }
195 virtual void apply(const HLAUInt16DataType& dataType) { dataType.skip(_stream); }
196 virtual void apply(const HLAInt32DataType& dataType) { dataType.skip(_stream); }
197 virtual void apply(const HLAUInt32DataType& dataType) { dataType.skip(_stream); }
198 virtual void apply(const HLAInt64DataType& dataType) { dataType.skip(_stream); }
199 virtual void apply(const HLAUInt64DataType& dataType) { dataType.skip(_stream); }
200 virtual void apply(const HLAFloat32DataType& dataType) { dataType.skip(_stream); }
201 virtual void apply(const HLAFloat64DataType& dataType) { dataType.skip(_stream); }
203 virtual void apply(const HLAFixedArrayDataType& dataType)
205 /// FIXME, might vanish in this sense ...
206 // dataType.encode(_stream, *this);
207 unsigned numElements = dataType.getNumElements();
208 for (unsigned i = 0; i < numElements; ++i)
209 dataType.getElementDataType()->accept(*this);
211 virtual void apply(const HLAVariableArrayDataType& dataType);
213 virtual void apply(const HLAEnumeratedDataType& dataType)
215 dataType.getRepresentation()->accept(*this);
218 virtual void apply(const HLAFixedRecordDataType& dataType)
220 unsigned numFields = dataType.getNumFields();
221 for (unsigned i = 0; i < numFields; ++i)
222 dataType.getFieldDataType(i)->accept(*this);
225 virtual void apply(const HLAVariantRecordDataType& dataType) { assert(0); }
228 HLAEncodeStream& _stream;
231 /// Begin implementation of some get/set visitors
233 class HLAScalarDecodeVisitor : public HLADataTypeDecodeVisitor {
235 HLAScalarDecodeVisitor(HLADecodeStream& stream) :
236 HLADataTypeDecodeVisitor(stream)
239 virtual void apply(const HLAFixedArrayDataType& dataType)
241 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
242 HLADataTypeDecodeVisitor::apply(dataType);
244 virtual void apply(const HLAVariableArrayDataType& dataType)
246 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
247 HLADataTypeDecodeVisitor::apply(dataType);
250 virtual void apply(const HLAEnumeratedDataType& dataType)
252 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
253 HLADataTypeDecodeVisitor::apply(dataType);
256 virtual void apply(const HLAFixedRecordDataType& dataType)
258 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
259 HLADataTypeDecodeVisitor::apply(dataType);
262 virtual void apply(const HLAVariantRecordDataType& dataType)
264 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing scalar value");
265 HLADataTypeDecodeVisitor::apply(dataType);
269 class HLAScalarEncodeVisitor : public HLADataTypeEncodeVisitor {
271 HLAScalarEncodeVisitor(HLAEncodeStream& stream) :
272 HLADataTypeEncodeVisitor(stream)
275 virtual void apply(const HLAFixedArrayDataType& dataType)
277 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
278 HLADataTypeEncodeVisitor::apply(dataType);
280 virtual void apply(const HLAVariableArrayDataType& dataType)
282 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
283 HLADataTypeEncodeVisitor::apply(dataType);
286 virtual void apply(const HLAEnumeratedDataType& dataType)
288 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
289 HLADataTypeEncodeVisitor::apply(dataType);
292 virtual void apply(const HLAFixedRecordDataType& dataType)
294 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
295 HLADataTypeEncodeVisitor::apply(dataType);
298 virtual void apply(const HLAVariantRecordDataType& dataType)
300 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing scalar value");
301 HLADataTypeEncodeVisitor::apply(dataType);
305 class HLAFixedRecordDecodeVisitor : public HLADataTypeDecodeVisitor {
307 HLAFixedRecordDecodeVisitor(HLADecodeStream& stream) :
308 HLADataTypeDecodeVisitor(stream)
311 virtual void apply(const HLAInt8DataType& dataType)
313 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
314 HLADataTypeDecodeVisitor::apply(dataType);
316 virtual void apply(const HLAUInt8DataType& dataType)
318 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
319 HLADataTypeDecodeVisitor::apply(dataType);
321 virtual void apply(const HLAInt16DataType& dataType)
323 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
324 HLADataTypeDecodeVisitor::apply(dataType);
326 virtual void apply(const HLAUInt16DataType& dataType)
328 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
329 HLADataTypeDecodeVisitor::apply(dataType);
331 virtual void apply(const HLAInt32DataType& dataType)
333 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
334 HLADataTypeDecodeVisitor::apply(dataType);
336 virtual void apply(const HLAUInt32DataType& dataType)
338 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
339 HLADataTypeDecodeVisitor::apply(dataType);
341 virtual void apply(const HLAInt64DataType& dataType)
343 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
344 HLADataTypeDecodeVisitor::apply(dataType);
346 virtual void apply(const HLAUInt64DataType& dataType)
348 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
349 HLADataTypeDecodeVisitor::apply(dataType);
351 virtual void apply(const HLAFloat32DataType& dataType)
353 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
354 HLADataTypeDecodeVisitor::apply(dataType);
356 virtual void apply(const HLAFloat64DataType& dataType)
358 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
359 HLADataTypeDecodeVisitor::apply(dataType);
362 virtual void apply(const HLAFixedArrayDataType& dataType)
364 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
365 HLADataTypeDecodeVisitor::apply(dataType);
367 virtual void apply(const HLAVariableArrayDataType& dataType)
369 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
370 HLADataTypeDecodeVisitor::apply(dataType);
373 virtual void apply(const HLAEnumeratedDataType& dataType)
375 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
376 HLADataTypeDecodeVisitor::apply(dataType);
379 virtual void apply(const HLAVariantRecordDataType& dataType)
381 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while decodeing a fixed record value");
382 HLADataTypeDecodeVisitor::apply(dataType);
386 class HLAFixedRecordEncodeVisitor : public HLADataTypeEncodeVisitor {
388 HLAFixedRecordEncodeVisitor(HLAEncodeStream& stream) :
389 HLADataTypeEncodeVisitor(stream)
392 virtual void apply(const HLAInt8DataType& dataType)
394 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
395 HLADataTypeEncodeVisitor::apply(dataType);
397 virtual void apply(const HLAUInt8DataType& dataType)
399 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
400 HLADataTypeEncodeVisitor::apply(dataType);
402 virtual void apply(const HLAInt16DataType& dataType)
404 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
405 HLADataTypeEncodeVisitor::apply(dataType);
407 virtual void apply(const HLAUInt16DataType& dataType)
409 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
410 HLADataTypeEncodeVisitor::apply(dataType);
412 virtual void apply(const HLAInt32DataType& dataType)
414 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
415 HLADataTypeEncodeVisitor::apply(dataType);
417 virtual void apply(const HLAUInt32DataType& dataType)
419 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
420 HLADataTypeEncodeVisitor::apply(dataType);
422 virtual void apply(const HLAInt64DataType& dataType)
424 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
425 HLADataTypeEncodeVisitor::apply(dataType);
427 virtual void apply(const HLAUInt64DataType& dataType)
429 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
430 HLADataTypeEncodeVisitor::apply(dataType);
432 virtual void apply(const HLAFloat32DataType& dataType)
434 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
435 HLADataTypeEncodeVisitor::apply(dataType);
437 virtual void apply(const HLAFloat64DataType& dataType)
439 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
440 HLADataTypeEncodeVisitor::apply(dataType);
443 virtual void apply(const HLAFixedArrayDataType& dataType)
445 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
446 HLADataTypeEncodeVisitor::apply(dataType);
448 virtual void apply(const HLAVariableArrayDataType& dataType)
450 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
451 HLADataTypeEncodeVisitor::apply(dataType);
454 virtual void apply(const HLAEnumeratedDataType& dataType)
456 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
457 HLADataTypeEncodeVisitor::apply(dataType);
460 virtual void apply(const HLAVariantRecordDataType& dataType)
462 SG_LOG(SG_NETWORK, SG_WARN, "Unexpected HLADataType while writing a fixed record value");
463 HLADataTypeEncodeVisitor::apply(dataType);
468 class HLATemplateDecodeVisitor : public HLAScalarDecodeVisitor {
470 typedef T value_type;
472 HLATemplateDecodeVisitor(HLADecodeStream& stream, const value_type& value = value_type()) :
473 HLAScalarDecodeVisitor(stream),
477 void setValue(const value_type& value)
479 const value_type& getValue() const
482 virtual void apply(const HLAInt8DataType& dataType)
485 dataType.decode(_stream, value);
486 _value = value_type(value);
488 virtual void apply(const HLAUInt8DataType& dataType)
491 dataType.decode(_stream, value);
492 _value = value_type(value);
494 virtual void apply(const HLAInt16DataType& dataType)
497 dataType.decode(_stream, value);
498 _value = value_type(value);
500 virtual void apply(const HLAUInt16DataType& dataType)
503 dataType.decode(_stream, value);
504 _value = value_type(value);
506 virtual void apply(const HLAInt32DataType& dataType)
509 dataType.decode(_stream, value);
510 _value = value_type(value);
512 virtual void apply(const HLAUInt32DataType& dataType)
515 dataType.decode(_stream, value);
516 _value = value_type(value);
518 virtual void apply(const HLAInt64DataType& dataType)
521 dataType.decode(_stream, value);
522 _value = value_type(value);
524 virtual void apply(const HLAUInt64DataType& dataType)
527 dataType.decode(_stream, value);
528 _value = value_type(value);
530 virtual void apply(const HLAFloat32DataType& dataType)
533 dataType.decode(_stream, value);
534 _value = value_type(value);
536 virtual void apply(const HLAFloat64DataType& dataType)
539 dataType.decode(_stream, value);
540 _value = value_type(value);
548 class HLATemplateEncodeVisitor : public HLAScalarEncodeVisitor {
550 typedef T value_type;
552 HLATemplateEncodeVisitor(HLAEncodeStream& stream, const value_type& value = value_type()) :
553 HLAScalarEncodeVisitor(stream),
557 void setValue(const value_type& value)
559 const value_type& getValue() const
562 virtual void apply(const HLAInt8DataType& dataType)
564 dataType.encode(_stream, _value);
566 virtual void apply(const HLAUInt8DataType& dataType)
568 dataType.encode(_stream, _value);
570 virtual void apply(const HLAInt16DataType& dataType)
572 dataType.encode(_stream, _value);
574 virtual void apply(const HLAUInt16DataType& dataType)
576 dataType.encode(_stream, _value);
578 virtual void apply(const HLAInt32DataType& dataType)
580 dataType.encode(_stream, _value);
582 virtual void apply(const HLAUInt32DataType& dataType)
584 dataType.encode(_stream, _value);
586 virtual void apply(const HLAInt64DataType& dataType)
588 dataType.encode(_stream, _value);
590 virtual void apply(const HLAUInt64DataType& dataType)
592 dataType.encode(_stream, _value);
594 virtual void apply(const HLAFloat32DataType& dataType)
596 dataType.encode(_stream, _value);
598 virtual void apply(const HLAFloat64DataType& dataType)
600 dataType.encode(_stream, _value);
607 inline void HLADataTypeDecodeVisitor::apply(const HLAVariableArrayDataType& dataType)
609 HLATemplateDecodeVisitor<unsigned> numElementsVisitor(_stream);
610 dataType.getSizeDataType()->accept(numElementsVisitor);
611 unsigned numElements = numElementsVisitor.getValue();
612 for (unsigned i = 0; i < numElements; ++i)
613 dataType.getElementDataType()->accept(*this);
616 inline void HLADataTypeEncodeVisitor::apply(const HLAVariableArrayDataType& dataType)
618 HLATemplateEncodeVisitor<unsigned> numElementsVisitor(_stream, 0);
619 dataType.getSizeDataType()->accept(numElementsVisitor);
622 /// Generate standard data elements according to the traversed type
623 class HLADataElementFactoryVisitor : public HLADataTypeVisitor {
625 virtual ~HLADataElementFactoryVisitor();
627 virtual void apply(const HLADataType& dataType);
629 virtual void apply(const HLAInt8DataType& dataType);
630 virtual void apply(const HLAUInt8DataType& dataType);
631 virtual void apply(const HLAInt16DataType& dataType);
632 virtual void apply(const HLAUInt16DataType& dataType);
633 virtual void apply(const HLAInt32DataType& dataType);
634 virtual void apply(const HLAUInt32DataType& dataType);
635 virtual void apply(const HLAInt64DataType& dataType);
636 virtual void apply(const HLAUInt64DataType& dataType);
637 virtual void apply(const HLAFloat32DataType& dataType);
638 virtual void apply(const HLAFloat64DataType& dataType);
640 virtual void apply(const HLAFixedArrayDataType& dataType);
641 virtual void apply(const HLAVariableArrayDataType& dataType);
643 virtual void apply(const HLAEnumeratedDataType& dataType);
645 virtual void apply(const HLAFixedRecordDataType& dataType);
647 virtual void apply(const HLAVariantRecordDataType& dataType);
649 HLADataElement* getDataElement()
650 { return _dataElement.release(); }
653 class ArrayDataElementFactory;
654 class VariantRecordDataElementFactory;
656 SGSharedPtr<HLADataElement> _dataElement;
659 } // namespace simgear