]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAArrayDataElement.cxx
hla: For setting data types recurse into array data elements.
[simgear.git] / simgear / hla / HLAArrayDataElement.cxx
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 #ifdef HAVE_CONFIG_H
19 #  include <simgear_config.h>
20 #endif
21
22 #include <simgear/compiler.h>
23
24 #include "HLAArrayDataElement.hxx"
25
26 #include <simgear/debug/logstream.hxx>
27
28 #include "HLADataElementVisitor.hxx"
29
30 namespace simgear {
31
32 HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
33     _dataType(dataType)
34 {
35 }
36
37 HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
38 {
39 }
40
41 void
42 HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor)
43 {
44     visitor.apply(*this);
45 }
46
47 void
48 HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const
49 {
50     visitor.apply(*this);
51 }
52
53 bool
54 HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
55 {
56     if (!_dataType.valid())
57         return false;
58     return _dataType->decode(stream, *this);
59 }
60
61 bool
62 HLAAbstractArrayDataElement::encode(HLAEncodeStream& stream) const
63 {
64     if (!_dataType.valid())
65         return false;
66     return _dataType->encode(stream, *this);
67 }
68
69 const HLAArrayDataType*
70 HLAAbstractArrayDataElement::getDataType() const
71 {
72     return _dataType.get();
73 }
74
75 bool
76 HLAAbstractArrayDataElement::setDataType(const HLADataType* dataType)
77 {
78     const HLAArrayDataType* arrayDataType = dynamic_cast<const HLAArrayDataType*>(dataType);
79     if (!arrayDataType) {
80         SG_LOG(SG_NETWORK, SG_WARN, "HLAArrayDataType: unable to set data type!");
81         return false;
82     }
83     _dataType = arrayDataType;
84     return true;
85 }
86
87 const HLADataType*
88 HLAAbstractArrayDataElement::getElementDataType() const
89 {
90     if (!_dataType.valid())
91         return 0;
92     return _dataType->getElementDataType();
93 }
94
95 ////////////////////////////////////////////////////////////////////////
96
97 HLAArrayDataElement::DataElementFactory::~DataElementFactory()
98 {
99 }
100
101 HLAArrayDataElement::HLAArrayDataElement(const HLAArrayDataType* dataType) :
102     HLAAbstractArrayDataElement(dataType)
103 {
104 }
105
106 HLAArrayDataElement::~HLAArrayDataElement()
107 {
108     clearStamp();
109 }
110
111 bool
112 HLAArrayDataElement::setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement)
113 {
114     // Must have happened in the parent
115     if (begin == end)
116         return false;
117     unsigned index = *begin;
118     if (++begin != end) {
119         if (getNumElements() <= index && !setNumElements(index + 1))
120             return false;
121         if (!getElement(index) && getElementDataType()) {
122             HLADataElementFactoryVisitor visitor;
123             getElementDataType()->accept(visitor);
124             setElement(index, visitor.getDataElement());
125         }
126         if (!getElement(index))
127             return false;
128         return getElement(index)->setDataElement(begin, end, dataElement);
129     } else {
130         if (!dataElement->setDataType(getElementDataType()))
131             return false;
132         setElement(index, dataElement);
133         return true;
134     }
135 }
136
137 HLADataElement*
138 HLAArrayDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end)
139 {
140     if (begin == end)
141         return this;
142     HLADataElement* dataElement = getElement(*begin);
143     if (!dataElement)
144         return 0;
145     return dataElement->getDataElement(++begin, end);
146 }
147
148 const HLADataElement*
149 HLAArrayDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const
150 {
151     if (begin == end)
152         return this;
153     const HLADataElement* dataElement = getElement(*begin);
154     if (!dataElement)
155         return 0;
156     return dataElement->getDataElement(++begin, end);
157 }
158
159 bool
160 HLAArrayDataElement::setDataType(const HLADataType* dataType)
161 {
162     if (!HLAAbstractArrayDataElement::setDataType(dataType))
163         return false;
164     for (unsigned i = 0; i < getNumElements(); ++i) {
165         HLADataElement* dataElement = getElement(i);
166         if (!dataElement)
167             continue;
168         if (!dataElement->setDataType(getElementDataType()))
169             return false;
170     }
171     return true;
172 }
173
174 bool
175 HLAArrayDataElement::setNumElements(unsigned size)
176 {
177     unsigned oldSize = _elementVector.size();
178     if (size == oldSize)
179         return true;
180     _elementVector.resize(size);
181     for (unsigned i = oldSize; i < size; ++i)
182         _elementVector[i] = newElement(i);
183     setDirty(true);
184     return true;
185 }
186
187 bool
188 HLAArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
189 {
190     HLADataElement* dataElement = getElement(i);
191     if (!dataElement)
192         return false;
193     return dataElement->decode(stream);
194 }
195
196 unsigned
197 HLAArrayDataElement::getNumElements() const
198 {
199     return _elementVector.size();
200 }
201
202 bool
203 HLAArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
204 {
205     const HLADataElement* dataElement = getElement(i);
206     if (!dataElement)
207         return false;
208     return dataElement->encode(stream);
209 }
210
211 const HLADataElement*
212 HLAArrayDataElement::getElement(unsigned index) const
213 {
214     if (_elementVector.size() <= index)
215         return 0;
216     return _elementVector[index].get();
217 }
218
219 HLADataElement*
220 HLAArrayDataElement::getElement(unsigned index)
221 {
222     if (_elementVector.size() <= index)
223         return 0;
224     return _elementVector[index].get();
225 }
226
227 HLADataElement*
228 HLAArrayDataElement::getOrCreateElement(unsigned index)
229 {
230     if (_elementVector.size() <= index)
231         if (!setNumElements(index + 1))
232             return 0;
233     return _elementVector[index].get();
234 }
235
236 void
237 HLAArrayDataElement::setElement(unsigned index, HLADataElement* value)
238 {
239     unsigned oldSize = _elementVector.size();
240     if (oldSize <= index) {
241         _elementVector.resize(index + 1);
242         for (unsigned j = oldSize; j < index; ++j)
243             _elementVector[j] = newElement(j);
244     }
245     if (_elementVector[index].valid())
246         _elementVector[index]->clearStamp();
247     _elementVector[index] = value;
248     if (value)
249         value->attachStamp(*this);
250     setDirty(true);
251 }
252
253 void
254 HLAArrayDataElement::setDataElementFactory(HLAArrayDataElement::DataElementFactory* dataElementFactory)
255 {
256     _dataElementFactory = dataElementFactory;
257 }
258
259 HLAArrayDataElement::DataElementFactory*
260 HLAArrayDataElement::getDataElementFactory()
261 {
262     return _dataElementFactory.get();
263 }
264
265 void
266 HLAArrayDataElement::_setStamp(Stamp* stamp)
267 {
268     HLAAbstractArrayDataElement::_setStamp(stamp);
269     for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
270         if (!i->valid())
271             continue;
272         (*i)->attachStamp(*this);
273     }
274 }
275
276 HLADataElement*
277 HLAArrayDataElement::newElement(unsigned index)
278 {
279     if (!_dataElementFactory.valid())
280         return 0;
281     HLADataElement* dataElement = _dataElementFactory->createElement(*this, index);
282     if (!dataElement)
283         return 0;
284     dataElement->attachStamp(*this);
285     return dataElement;
286 }
287
288 ////////////////////////////////////////////////////////////////////////
289
290 HLAVariantArrayDataElement::HLAVariantArrayDataElement() :
291     HLAAbstractArrayDataElement(0)
292 {
293 }
294
295 HLAVariantArrayDataElement::~HLAVariantArrayDataElement()
296 {
297     clearStamp();
298 }
299
300 bool
301 HLAVariantArrayDataElement::setDataType(const HLADataType* dataType)
302 {
303     const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
304     if (!arrayDataType) {
305         SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type, dataType is not an array data type!");
306         return false;
307     }
308     const HLAVariantRecordDataType* variantRecordDataType = arrayDataType->getElementDataType()->toVariantRecordDataType();
309     if (!variantRecordDataType) {
310         SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type: arrayDataTypes element data type is no a variant data type!");
311         return false;
312     }
313     _dataType = arrayDataType;
314     return true;
315 }
316
317 bool
318 HLAVariantArrayDataElement::setNumElements(unsigned size)
319 {
320     unsigned oldSize = _elementVector.size();
321     if (size == oldSize)
322         return true;
323     _elementVector.resize(size);
324     for (unsigned i = oldSize; i < size; ++i)
325         _elementVector[i] = newElement();
326     setDirty(true);
327     return true;
328 }
329
330 bool
331 HLAVariantArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
332 {
333     HLAVariantRecordDataElement* dataElement = getElement(i);
334     if (!dataElement)
335         return false;
336     return dataElement->decode(stream);
337 }
338
339 unsigned
340 HLAVariantArrayDataElement::getNumElements() const
341 {
342     return _elementVector.size();
343 }
344
345 bool
346 HLAVariantArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
347 {
348     const HLADataElement* dataElement = getElement(i);
349     if (!dataElement)
350         return false;
351     return dataElement->encode(stream);
352 }
353
354 const HLAVariantRecordDataElement*
355 HLAVariantArrayDataElement::getElement(unsigned index) const
356 {
357     if (_elementVector.size() <= index)
358         return 0;
359     return _elementVector[index].get();
360 }
361
362 HLAVariantRecordDataElement*
363 HLAVariantArrayDataElement::getElement(unsigned index)
364 {
365     if (_elementVector.size() <= index)
366         return 0;
367     return _elementVector[index].get();
368 }
369
370 HLAVariantRecordDataElement*
371 HLAVariantArrayDataElement::getOrCreateElement(unsigned index)
372 {
373     if (_elementVector.size() <= index)
374         if (!setNumElements(index + 1))
375             return 0;
376     return _elementVector[index].get();
377 }
378
379 void
380 HLAVariantArrayDataElement::setElement(unsigned index, HLAVariantRecordDataElement* value)
381 {
382     unsigned oldSize = _elementVector.size();
383     if (oldSize <= index) {
384         _elementVector.resize(index + 1);
385         for (unsigned j = oldSize; j < index; ++j)
386             _elementVector[j] = newElement();
387     }
388     if (_elementVector[index].valid())
389         _elementVector[index]->clearStamp();
390     _elementVector[index] = value;
391     if (value)
392         value->attachStamp(*this);
393     setDirty(true);
394 }
395
396 void
397 HLAVariantArrayDataElement::setAlternativeDataElementFactory(HLAVariantArrayDataElement::AlternativeDataElementFactory* alternativeDataElementFactory)
398 {
399     _alternativeDataElementFactory = alternativeDataElementFactory;
400 }
401
402 HLAVariantArrayDataElement::AlternativeDataElementFactory*
403 HLAVariantArrayDataElement::getAlternativeDataElementFactory()
404 {
405     return _alternativeDataElementFactory.get();
406 }
407
408 void
409 HLAVariantArrayDataElement::_setStamp(Stamp* stamp)
410 {
411     HLAAbstractArrayDataElement::_setStamp(stamp);
412     for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
413         if (!i->valid())
414             continue;
415         (*i)->attachStamp(*this);
416     }
417 }
418
419 HLAVariantRecordDataElement*
420 HLAVariantArrayDataElement::newElement()
421 {
422     const HLAArrayDataType* arrayDataType = getDataType();
423     if (!arrayDataType)
424         return 0;
425     const HLADataType* elementDataType = arrayDataType->getElementDataType();
426     if (!elementDataType)
427         return 0;
428     const HLAVariantRecordDataType* variantRecordDataType = elementDataType->toVariantRecordDataType();
429     if (!variantRecordDataType)
430         return 0;
431     HLAVariantRecordDataElement* variantRecordDataElement = new HLAVariantRecordDataElement(variantRecordDataType);
432     variantRecordDataElement->setDataElementFactory(_alternativeDataElementFactory.get());
433     variantRecordDataElement->attachStamp(*this);
434     return variantRecordDataElement;
435 }
436
437 }