]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAArrayDataElement.cxx
191a84eb1d766130bcbe0c789c710526d1c923e5
[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::setNumElements(unsigned size)
161 {
162     unsigned oldSize = _elementVector.size();
163     if (size == oldSize)
164         return true;
165     _elementVector.resize(size);
166     for (unsigned i = oldSize; i < size; ++i)
167         _elementVector[i] = newElement(i);
168     setDirty(true);
169     return true;
170 }
171
172 bool
173 HLAArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
174 {
175     HLADataElement* dataElement = getElement(i);
176     if (!dataElement)
177         return false;
178     return dataElement->decode(stream);
179 }
180
181 unsigned
182 HLAArrayDataElement::getNumElements() const
183 {
184     return _elementVector.size();
185 }
186
187 bool
188 HLAArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
189 {
190     const HLADataElement* dataElement = getElement(i);
191     if (!dataElement)
192         return false;
193     return dataElement->encode(stream);
194 }
195
196 const HLADataElement*
197 HLAArrayDataElement::getElement(unsigned index) const
198 {
199     if (_elementVector.size() <= index)
200         return 0;
201     return _elementVector[index].get();
202 }
203
204 HLADataElement*
205 HLAArrayDataElement::getElement(unsigned index)
206 {
207     if (_elementVector.size() <= index)
208         return 0;
209     return _elementVector[index].get();
210 }
211
212 HLADataElement*
213 HLAArrayDataElement::getOrCreateElement(unsigned index)
214 {
215     if (_elementVector.size() <= index)
216         if (!setNumElements(index + 1))
217             return 0;
218     return _elementVector[index].get();
219 }
220
221 void
222 HLAArrayDataElement::setElement(unsigned index, HLADataElement* value)
223 {
224     unsigned oldSize = _elementVector.size();
225     if (oldSize <= index) {
226         _elementVector.resize(index + 1);
227         for (unsigned j = oldSize; j < index; ++j)
228             _elementVector[j] = newElement(j);
229     }
230     if (_elementVector[index].valid())
231         _elementVector[index]->clearStamp();
232     _elementVector[index] = value;
233     if (value)
234         value->attachStamp(*this);
235     setDirty(true);
236 }
237
238 void
239 HLAArrayDataElement::setDataElementFactory(HLAArrayDataElement::DataElementFactory* dataElementFactory)
240 {
241     _dataElementFactory = dataElementFactory;
242 }
243
244 HLAArrayDataElement::DataElementFactory*
245 HLAArrayDataElement::getDataElementFactory()
246 {
247     return _dataElementFactory.get();
248 }
249
250 void
251 HLAArrayDataElement::_setStamp(Stamp* stamp)
252 {
253     HLAAbstractArrayDataElement::_setStamp(stamp);
254     for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
255         if (!i->valid())
256             continue;
257         (*i)->attachStamp(*this);
258     }
259 }
260
261 HLADataElement*
262 HLAArrayDataElement::newElement(unsigned index)
263 {
264     if (!_dataElementFactory.valid())
265         return 0;
266     HLADataElement* dataElement = _dataElementFactory->createElement(*this, index);
267     if (!dataElement)
268         return 0;
269     dataElement->attachStamp(*this);
270     return dataElement;
271 }
272
273 ////////////////////////////////////////////////////////////////////////
274
275 HLAVariantArrayDataElement::HLAVariantArrayDataElement() :
276     HLAAbstractArrayDataElement(0)
277 {
278 }
279
280 HLAVariantArrayDataElement::~HLAVariantArrayDataElement()
281 {
282     clearStamp();
283 }
284
285 bool
286 HLAVariantArrayDataElement::setDataType(const HLADataType* dataType)
287 {
288     const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
289     if (!arrayDataType) {
290         SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type, dataType is not an array data type!");
291         return false;
292     }
293     const HLAVariantRecordDataType* variantRecordDataType = arrayDataType->getElementDataType()->toVariantRecordDataType();
294     if (!variantRecordDataType) {
295         SG_LOG(SG_NETWORK, SG_WARN, "HLAVariantArrayDataType: unable to set data type: arrayDataTypes element data type is no a variant data type!");
296         return false;
297     }
298     _dataType = arrayDataType;
299     return true;
300 }
301
302 bool
303 HLAVariantArrayDataElement::setNumElements(unsigned size)
304 {
305     unsigned oldSize = _elementVector.size();
306     if (size == oldSize)
307         return true;
308     _elementVector.resize(size);
309     for (unsigned i = oldSize; i < size; ++i)
310         _elementVector[i] = newElement();
311     setDirty(true);
312     return true;
313 }
314
315 bool
316 HLAVariantArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
317 {
318     HLAVariantRecordDataElement* dataElement = getElement(i);
319     if (!dataElement)
320         return false;
321     return dataElement->decode(stream);
322 }
323
324 unsigned
325 HLAVariantArrayDataElement::getNumElements() const
326 {
327     return _elementVector.size();
328 }
329
330 bool
331 HLAVariantArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
332 {
333     const HLADataElement* dataElement = getElement(i);
334     if (!dataElement)
335         return false;
336     return dataElement->encode(stream);
337 }
338
339 const HLAVariantRecordDataElement*
340 HLAVariantArrayDataElement::getElement(unsigned index) const
341 {
342     if (_elementVector.size() <= index)
343         return 0;
344     return _elementVector[index].get();
345 }
346
347 HLAVariantRecordDataElement*
348 HLAVariantArrayDataElement::getElement(unsigned index)
349 {
350     if (_elementVector.size() <= index)
351         return 0;
352     return _elementVector[index].get();
353 }
354
355 HLAVariantRecordDataElement*
356 HLAVariantArrayDataElement::getOrCreateElement(unsigned index)
357 {
358     if (_elementVector.size() <= index)
359         if (!setNumElements(index + 1))
360             return 0;
361     return _elementVector[index].get();
362 }
363
364 void
365 HLAVariantArrayDataElement::setElement(unsigned index, HLAVariantRecordDataElement* value)
366 {
367     unsigned oldSize = _elementVector.size();
368     if (oldSize <= index) {
369         _elementVector.resize(index + 1);
370         for (unsigned j = oldSize; j < index; ++j)
371             _elementVector[j] = newElement();
372     }
373     if (_elementVector[index].valid())
374         _elementVector[index]->clearStamp();
375     _elementVector[index] = value;
376     if (value)
377         value->attachStamp(*this);
378     setDirty(true);
379 }
380
381 void
382 HLAVariantArrayDataElement::setAlternativeDataElementFactory(HLAVariantArrayDataElement::AlternativeDataElementFactory* alternativeDataElementFactory)
383 {
384     _alternativeDataElementFactory = alternativeDataElementFactory;
385 }
386
387 HLAVariantArrayDataElement::AlternativeDataElementFactory*
388 HLAVariantArrayDataElement::getAlternativeDataElementFactory()
389 {
390     return _alternativeDataElementFactory.get();
391 }
392
393 void
394 HLAVariantArrayDataElement::_setStamp(Stamp* stamp)
395 {
396     HLAAbstractArrayDataElement::_setStamp(stamp);
397     for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
398         if (!i->valid())
399             continue;
400         (*i)->attachStamp(*this);
401     }
402 }
403
404 HLAVariantRecordDataElement*
405 HLAVariantArrayDataElement::newElement()
406 {
407     const HLAArrayDataType* arrayDataType = getDataType();
408     if (!arrayDataType)
409         return 0;
410     const HLADataType* elementDataType = arrayDataType->getElementDataType();
411     if (!elementDataType)
412         return 0;
413     const HLAVariantRecordDataType* variantRecordDataType = elementDataType->toVariantRecordDataType();
414     if (!variantRecordDataType)
415         return 0;
416     HLAVariantRecordDataElement* variantRecordDataElement = new HLAVariantRecordDataElement(variantRecordDataType);
417     variantRecordDataElement->setDataElementFactory(_alternativeDataElementFactory.get());
418     variantRecordDataElement->attachStamp(*this);
419     return variantRecordDataElement;
420 }
421
422 }