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.
19 # include <simgear_config.h>
22 #include <simgear/compiler.h>
24 #include "HLAArrayDataElement.hxx"
26 #include <simgear/debug/logstream.hxx>
28 #include "HLADataElementVisitor.hxx"
32 HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
37 HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
42 HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor)
48 HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const
54 HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
56 if (!_dataType.valid())
58 return _dataType->decode(stream, *this);
62 HLAAbstractArrayDataElement::encode(HLAEncodeStream& stream) const
64 if (!_dataType.valid())
66 return _dataType->encode(stream, *this);
69 const HLAArrayDataType*
70 HLAAbstractArrayDataElement::getDataType() const
72 return _dataType.get();
76 HLAAbstractArrayDataElement::setDataType(const HLADataType* dataType)
78 const HLAArrayDataType* arrayDataType = dynamic_cast<const HLAArrayDataType*>(dataType);
80 SG_LOG(SG_NETWORK, SG_WARN, "HLAArrayDataType: unable to set data type!");
83 _dataType = arrayDataType;
88 HLAAbstractArrayDataElement::getElementDataType() const
90 if (!_dataType.valid())
92 return _dataType->getElementDataType();
95 ////////////////////////////////////////////////////////////////////////
97 HLAArrayDataElement::DataElementFactory::~DataElementFactory()
101 HLAArrayDataElement::HLAArrayDataElement(const HLAArrayDataType* dataType) :
102 HLAAbstractArrayDataElement(dataType)
106 HLAArrayDataElement::~HLAArrayDataElement()
112 HLAArrayDataElement::setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement)
114 // Must have happened in the parent
117 unsigned index = *begin;
118 if (++begin != end) {
119 if (getNumElements() <= index && !setNumElements(index + 1))
121 if (!getElement(index) && getElementDataType()) {
122 HLADataElementFactoryVisitor visitor;
123 getElementDataType()->accept(visitor);
124 setElement(index, visitor.getDataElement());
126 if (!getElement(index))
128 return getElement(index)->setDataElement(begin, end, dataElement);
130 if (!dataElement->setDataType(getElementDataType()))
132 setElement(index, dataElement);
138 HLAArrayDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end)
142 HLADataElement* dataElement = getElement(*begin);
145 return dataElement->getDataElement(++begin, end);
148 const HLADataElement*
149 HLAArrayDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const
153 const HLADataElement* dataElement = getElement(*begin);
156 return dataElement->getDataElement(++begin, end);
160 HLAArrayDataElement::setNumElements(unsigned size)
162 unsigned oldSize = _elementVector.size();
165 _elementVector.resize(size);
166 for (unsigned i = oldSize; i < size; ++i)
167 _elementVector[i] = newElement(i);
173 HLAArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
175 HLADataElement* dataElement = getElement(i);
178 return dataElement->decode(stream);
182 HLAArrayDataElement::getNumElements() const
184 return _elementVector.size();
188 HLAArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
190 const HLADataElement* dataElement = getElement(i);
193 return dataElement->encode(stream);
196 const HLADataElement*
197 HLAArrayDataElement::getElement(unsigned index) const
199 if (_elementVector.size() <= index)
201 return _elementVector[index].get();
205 HLAArrayDataElement::getElement(unsigned index)
207 if (_elementVector.size() <= index)
209 return _elementVector[index].get();
213 HLAArrayDataElement::getOrCreateElement(unsigned index)
215 if (_elementVector.size() <= index)
216 if (!setNumElements(index + 1))
218 return _elementVector[index].get();
222 HLAArrayDataElement::setElement(unsigned index, HLADataElement* value)
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);
230 if (_elementVector[index].valid())
231 _elementVector[index]->clearStamp();
232 _elementVector[index] = value;
234 value->attachStamp(*this);
239 HLAArrayDataElement::setDataElementFactory(HLAArrayDataElement::DataElementFactory* dataElementFactory)
241 _dataElementFactory = dataElementFactory;
244 HLAArrayDataElement::DataElementFactory*
245 HLAArrayDataElement::getDataElementFactory()
247 return _dataElementFactory.get();
251 HLAArrayDataElement::_setStamp(Stamp* stamp)
253 HLAAbstractArrayDataElement::_setStamp(stamp);
254 for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
257 (*i)->attachStamp(*this);
262 HLAArrayDataElement::newElement(unsigned index)
264 if (!_dataElementFactory.valid())
266 HLADataElement* dataElement = _dataElementFactory->createElement(*this, index);
269 dataElement->attachStamp(*this);
273 ////////////////////////////////////////////////////////////////////////
275 HLAVariantArrayDataElement::HLAVariantArrayDataElement() :
276 HLAAbstractArrayDataElement(0)
280 HLAVariantArrayDataElement::~HLAVariantArrayDataElement()
286 HLAVariantArrayDataElement::setDataType(const HLADataType* dataType)
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!");
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!");
298 _dataType = arrayDataType;
303 HLAVariantArrayDataElement::setNumElements(unsigned size)
305 unsigned oldSize = _elementVector.size();
308 _elementVector.resize(size);
309 for (unsigned i = oldSize; i < size; ++i)
310 _elementVector[i] = newElement();
316 HLAVariantArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
318 HLAVariantRecordDataElement* dataElement = getElement(i);
321 return dataElement->decode(stream);
325 HLAVariantArrayDataElement::getNumElements() const
327 return _elementVector.size();
331 HLAVariantArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
333 const HLADataElement* dataElement = getElement(i);
336 return dataElement->encode(stream);
339 const HLAVariantRecordDataElement*
340 HLAVariantArrayDataElement::getElement(unsigned index) const
342 if (_elementVector.size() <= index)
344 return _elementVector[index].get();
347 HLAVariantRecordDataElement*
348 HLAVariantArrayDataElement::getElement(unsigned index)
350 if (_elementVector.size() <= index)
352 return _elementVector[index].get();
355 HLAVariantRecordDataElement*
356 HLAVariantArrayDataElement::getOrCreateElement(unsigned index)
358 if (_elementVector.size() <= index)
359 if (!setNumElements(index + 1))
361 return _elementVector[index].get();
365 HLAVariantArrayDataElement::setElement(unsigned index, HLAVariantRecordDataElement* value)
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();
373 if (_elementVector[index].valid())
374 _elementVector[index]->clearStamp();
375 _elementVector[index] = value;
377 value->attachStamp(*this);
382 HLAVariantArrayDataElement::setAlternativeDataElementFactory(HLAVariantArrayDataElement::AlternativeDataElementFactory* alternativeDataElementFactory)
384 _alternativeDataElementFactory = alternativeDataElementFactory;
387 HLAVariantArrayDataElement::AlternativeDataElementFactory*
388 HLAVariantArrayDataElement::getAlternativeDataElementFactory()
390 return _alternativeDataElementFactory.get();
394 HLAVariantArrayDataElement::_setStamp(Stamp* stamp)
396 HLAAbstractArrayDataElement::_setStamp(stamp);
397 for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
400 (*i)->attachStamp(*this);
404 HLAVariantRecordDataElement*
405 HLAVariantArrayDataElement::newElement()
407 const HLAArrayDataType* arrayDataType = getDataType();
410 const HLADataType* elementDataType = arrayDataType->getElementDataType();
411 if (!elementDataType)
413 const HLAVariantRecordDataType* variantRecordDataType = elementDataType->toVariantRecordDataType();
414 if (!variantRecordDataType)
416 HLAVariantRecordDataElement* variantRecordDataElement = new HLAVariantRecordDataElement(variantRecordDataType);
417 variantRecordDataElement->setDataElementFactory(_alternativeDataElementFactory.get());
418 variantRecordDataElement->attachStamp(*this);
419 return variantRecordDataElement;