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::setDataType(const HLADataType* dataType)
162 if (!HLAAbstractArrayDataElement::setDataType(dataType))
164 for (unsigned i = 0; i < getNumElements(); ++i) {
165 HLADataElement* dataElement = getElement(i);
168 if (!dataElement->setDataType(getElementDataType()))
175 HLAArrayDataElement::setNumElements(unsigned size)
177 unsigned oldSize = _elementVector.size();
180 _elementVector.resize(size);
181 for (unsigned i = oldSize; i < size; ++i)
182 _elementVector[i] = newElement(i);
188 HLAArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
190 HLADataElement* dataElement = getElement(i);
193 return dataElement->decode(stream);
197 HLAArrayDataElement::getNumElements() const
199 return _elementVector.size();
203 HLAArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
205 const HLADataElement* dataElement = getElement(i);
208 return dataElement->encode(stream);
211 const HLADataElement*
212 HLAArrayDataElement::getElement(unsigned index) const
214 if (_elementVector.size() <= index)
216 return _elementVector[index].get();
220 HLAArrayDataElement::getElement(unsigned index)
222 if (_elementVector.size() <= index)
224 return _elementVector[index].get();
228 HLAArrayDataElement::getOrCreateElement(unsigned index)
230 if (_elementVector.size() <= index)
231 if (!setNumElements(index + 1))
233 return _elementVector[index].get();
237 HLAArrayDataElement::setElement(unsigned index, HLADataElement* value)
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);
245 if (_elementVector[index].valid())
246 _elementVector[index]->clearStamp();
247 _elementVector[index] = value;
249 value->attachStamp(*this);
254 HLAArrayDataElement::setDataElementFactory(HLAArrayDataElement::DataElementFactory* dataElementFactory)
256 _dataElementFactory = dataElementFactory;
259 HLAArrayDataElement::DataElementFactory*
260 HLAArrayDataElement::getDataElementFactory()
262 return _dataElementFactory.get();
266 HLAArrayDataElement::_setStamp(Stamp* stamp)
268 HLAAbstractArrayDataElement::_setStamp(stamp);
269 for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
272 (*i)->attachStamp(*this);
277 HLAArrayDataElement::newElement(unsigned index)
279 if (!_dataElementFactory.valid())
281 HLADataElement* dataElement = _dataElementFactory->createElement(*this, index);
284 dataElement->attachStamp(*this);
288 ////////////////////////////////////////////////////////////////////////
290 HLAVariantArrayDataElement::HLAVariantArrayDataElement() :
291 HLAAbstractArrayDataElement(0)
295 HLAVariantArrayDataElement::~HLAVariantArrayDataElement()
301 HLAVariantArrayDataElement::setDataType(const HLADataType* dataType)
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!");
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!");
313 _dataType = arrayDataType;
318 HLAVariantArrayDataElement::setNumElements(unsigned size)
320 unsigned oldSize = _elementVector.size();
323 _elementVector.resize(size);
324 for (unsigned i = oldSize; i < size; ++i)
325 _elementVector[i] = newElement();
331 HLAVariantArrayDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
333 HLAVariantRecordDataElement* dataElement = getElement(i);
336 return dataElement->decode(stream);
340 HLAVariantArrayDataElement::getNumElements() const
342 return _elementVector.size();
346 HLAVariantArrayDataElement::encodeElement(HLAEncodeStream& stream, unsigned i) const
348 const HLADataElement* dataElement = getElement(i);
351 return dataElement->encode(stream);
354 const HLAVariantRecordDataElement*
355 HLAVariantArrayDataElement::getElement(unsigned index) const
357 if (_elementVector.size() <= index)
359 return _elementVector[index].get();
362 HLAVariantRecordDataElement*
363 HLAVariantArrayDataElement::getElement(unsigned index)
365 if (_elementVector.size() <= index)
367 return _elementVector[index].get();
370 HLAVariantRecordDataElement*
371 HLAVariantArrayDataElement::getOrCreateElement(unsigned index)
373 if (_elementVector.size() <= index)
374 if (!setNumElements(index + 1))
376 return _elementVector[index].get();
380 HLAVariantArrayDataElement::setElement(unsigned index, HLAVariantRecordDataElement* value)
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();
388 if (_elementVector[index].valid())
389 _elementVector[index]->clearStamp();
390 _elementVector[index] = value;
392 value->attachStamp(*this);
397 HLAVariantArrayDataElement::setAlternativeDataElementFactory(HLAVariantArrayDataElement::AlternativeDataElementFactory* alternativeDataElementFactory)
399 _alternativeDataElementFactory = alternativeDataElementFactory;
402 HLAVariantArrayDataElement::AlternativeDataElementFactory*
403 HLAVariantArrayDataElement::getAlternativeDataElementFactory()
405 return _alternativeDataElementFactory.get();
409 HLAVariantArrayDataElement::_setStamp(Stamp* stamp)
411 HLAAbstractArrayDataElement::_setStamp(stamp);
412 for (ElementVector::iterator i = _elementVector.begin(); i != _elementVector.end(); ++i) {
415 (*i)->attachStamp(*this);
419 HLAVariantRecordDataElement*
420 HLAVariantArrayDataElement::newElement()
422 const HLAArrayDataType* arrayDataType = getDataType();
425 const HLADataType* elementDataType = arrayDataType->getElementDataType();
426 if (!elementDataType)
428 const HLAVariantRecordDataType* variantRecordDataType = elementDataType->toVariantRecordDataType();
429 if (!variantRecordDataType)
431 HLAVariantRecordDataElement* variantRecordDataElement = new HLAVariantRecordDataElement(variantRecordDataType);
432 variantRecordDataElement->setDataElementFactory(_alternativeDataElementFactory.get());
433 variantRecordDataElement->attachStamp(*this);
434 return variantRecordDataElement;