Home | History | Annotate | Download | only in dae
      1 /*
      2 * Copyright 2006 Sony Computer Entertainment Inc.
      3 *
      4 * Licensed under the MIT Open Source License, for details please see license.txt or the website
      5 * http://www.opensource.org/licenses/mit-license.php
      6 *
      7 */
      8 
      9 #include <dae.h>
     10 #include <dae/daeMetaElement.h>
     11 #include <dae/daeElement.h>
     12 #include <dae/daeDocument.h>
     13 #include <dae/domAny.h>
     14 #include <dae/daeMetaCMPolicy.h>
     15 #include <dae/daeMetaElementAttribute.h>
     16 
     17 daeElementRef
     18 daeMetaElement::create()
     19 {
     20 	daeElementRef ret =  (*_createFunc)(dae);
     21 	ret->setup(this);
     22 
     23 	return ret;
     24 }
     25 
     26 daeElementRef
     27 daeMetaElement::create(daeString s)
     28 {
     29 	daeMetaElement* me = NULL;
     30 	if ( strcmp( s, _name ) == 0 ) {
     31 		//looking for this meta
     32 		me = this;
     33 	}
     34 	else if ( _contentModel != NULL ) {
     35 		me = _contentModel->findChild(s);
     36 	}
     37 	if (me != NULL) {
     38 		daeElementRef ret = me->create();
     39 		if ( strcmp(s, me->getName() ) != 0 ) {
     40 			ret->setElementName(s);
     41 		}
     42 		return ret;
     43 	}
     44 	if ( getAllowsAny() ) {
     45 		daeElementRef ret = domAny::registerElement(dae)->create();
     46 		ret->setElementName(s);
     47 		return ret;
     48 	}
     49 	return NULL;
     50 }
     51 
     52 daeMetaElement::daeMetaElement(DAE& dae) : dae(dae)
     53 {
     54 	_name = "noname";
     55 	_createFunc = NULL;
     56 	_elementSize = sizeof(daeElement);
     57 	_metaValue = NULL;
     58 	_metaContents = NULL;
     59 	_metaContentsOrder = NULL; // sthomas
     60 	_metaID = NULL;
     61 	_isTrackableForQueries = true;
     62 	_usesStringContents = false;
     63 	_isTransparent = false;
     64 	_isAbstract = false;
     65 	_allowsAny = false;
     66 	_innerClass = false;
     67 	_contentModel = NULL;
     68 	_metaCMData = NULL;
     69 	_numMetaChoices = 0;
     70 }
     71 
     72 daeMetaElement::~daeMetaElement()
     73 {
     74 	delete _metaContents;
     75 	delete _contentModel;
     76 	delete _metaContentsOrder;
     77 	delete _metaCMData;
     78 }
     79 
     80 DAE* daeMetaElement::getDAE() {
     81 	return &dae;
     82 }
     83 
     84 void daeMetaElement::setCMRoot( daeMetaCMPolicy *cm )
     85 {
     86 	if (_contentModel)
     87 		delete _contentModel;
     88 	_contentModel = cm;
     89 }
     90 
     91 void
     92 daeMetaElement::addContents(daeInt offset)
     93 {
     94 	daeMetaElementArrayAttribute* meaa = new daeMetaElementArrayAttribute( this, NULL, 0, 1, -1 );
     95 	meaa->setType(dae.getAtomicTypes().get("element"));
     96 	meaa->setName("contents");
     97 	meaa->setOffset(offset);
     98 	meaa->setContainer( this);
     99 	_metaContents = meaa;
    100 }
    101 void
    102 daeMetaElement::addContentsOrder(daeInt offset)
    103 {
    104 	daeMetaArrayAttribute* meaa = new daeMetaArrayAttribute();
    105 	meaa->setType(dae.getAtomicTypes().get("uint"));
    106 	meaa->setName("contentsOrder");
    107 	meaa->setOffset(offset);
    108 	meaa->setContainer( this);
    109 
    110     if (_metaContentsOrder)
    111         delete _metaContentsOrder;
    112 
    113 	_metaContentsOrder = meaa;
    114 }
    115 
    116 void daeMetaElement::addCMDataArray(daeInt offset, daeUInt numChoices)
    117 {
    118 	daeMetaArrayAttribute* meaa = new daeMetaArrayAttribute();
    119 	meaa->setType(dae.getAtomicTypes().get("int"));
    120 	meaa->setName("CMData");
    121 	meaa->setOffset(offset);
    122 	meaa->setContainer( this);
    123 
    124     if (_metaCMData)
    125         delete _metaCMData;
    126 
    127 	_metaCMData = meaa;
    128 
    129 	_numMetaChoices = numChoices;
    130 }
    131 
    132 
    133 /*void
    134 daeMetaElement::appendArrayElement(daeMetaElement* element, daeInt offset, daeString name)
    135 {
    136 	daeMetaElementArrayAttribute* meaa = new daeMetaElementArrayAttribute;
    137 	meaa->setType(daeAtomicType::get("element"));
    138 	if ( name ) {
    139 		meaa->setName(name);
    140 	}
    141 	else {
    142 		meaa->setName(element->getName());
    143 	}
    144 	meaa->setOffset(offset);
    145 	meaa->setContainer(this);
    146 	meaa->setElementType( element);
    147 	_metaElements.append(meaa);
    148 }
    149 void
    150 daeMetaElement::appendElement(daeMetaElement* element, daeInt offset, daeString name)
    151 {
    152 	daeMetaElementAttribute* meaa = new daeMetaElementAttribute;
    153 	meaa->setType(daeAtomicType::get("element"));
    154 	if ( name ) {
    155 		meaa->setName(name);
    156 	}
    157 	else {
    158 		meaa->setName(element->getName());
    159 	}
    160 	meaa->setOffset( offset);
    161 	meaa->setContainer( this );
    162 	meaa->setElementType( element );
    163 	_metaElements.append(meaa);
    164 }*/
    165 
    166 void
    167 daeMetaElement::appendAttribute(daeMetaAttribute* attr)
    168 {
    169 	if (attr == NULL)
    170 		return;
    171 
    172 	if (strcmp(attr->getName(),"_value") == 0) {
    173 		_metaValue = attr;
    174 	}
    175 	else
    176 		_metaAttributes.append(attr);
    177 
    178 	if ((attr->getName() != NULL) &&
    179 		(strcmp(attr->getName(),"id") == 0)) {
    180 		_metaID = attr;
    181 		_isTrackableForQueries = true;
    182 	}
    183 }
    184 
    185 void
    186 daeMetaElement::validate()
    187 {
    188 	if (_elementSize == 0)
    189 	{
    190 		daeInt place=0;
    191 		unsigned int i;
    192 		for(i=0;i<_metaAttributes.getCount();i++) {
    193 			place += _metaAttributes[i]->getSize();
    194 			int align = _metaAttributes[i]->getAlignment();
    195 			place += align;
    196 			place &= (~(align-1));
    197 		}
    198 		_elementSize = place;
    199 	}
    200 }
    201 
    202 daeMetaAttribute*
    203 daeMetaElement::getMetaAttribute(daeString s)
    204 {
    205 	int cnt = (int)_metaAttributes.getCount();
    206 	int i;
    207 	for(i=0;i<cnt;i++)
    208 		if (strcmp(_metaAttributes[i]->getName(),s) == 0)
    209 			return _metaAttributes[i];
    210 	return NULL;
    211 }
    212 
    213 
    214 // void daeMetaElement::releaseMetas()
    215 // {
    216 // 	_metas().clear();
    217 // 	size_t count = _classMetaPointers().getCount();
    218 // 	for ( size_t i = 0; i < count; i++ )
    219 // 	{
    220 // 		*(_classMetaPointers()[i]) = NULL;
    221 // 	}
    222 // 	_classMetaPointers().clear();
    223 // 	if (mera)
    224 // 	{
    225 // 		delete mera;
    226 // 		mera = NULL;
    227 // 	}
    228 // 	if (mes)
    229 // 	{
    230 // 		delete mes;
    231 // 		mes = NULL;
    232 // 	}
    233 // }
    234 
    235 daeBool daeMetaElement::place(daeElement *parent, daeElement *child, daeUInt *ordinal )
    236 {
    237 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
    238 		return false;
    239 	}
    240 	daeUInt ord;
    241 	daeElement *retVal = _contentModel->placeElement( parent, child, ord );
    242 	if ( retVal != NULL ) {
    243 		//update document pointer
    244 		child->setDocument( parent->getDocument() );
    245 		retVal->setDocument( parent->getDocument() );
    246 		//add to _contents array
    247 		if (_metaContents != NULL) {
    248 			daeElementRefArray* contents =
    249 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
    250 			daeUIntArray* contentsOrder =
    251 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
    252 			daeBool needsAppend = true;
    253 			size_t cnt = contentsOrder->getCount();
    254 			for ( size_t x = 0; x < cnt; x++ ) {
    255 				if ( contentsOrder->get(x) > ord ) {
    256 					contents->insertAt( x, retVal );
    257 					contentsOrder->insertAt( x, ord );
    258 					needsAppend = false;
    259 					break;
    260 				}
    261 			}
    262 			if ( needsAppend ) {
    263 				contents->append(retVal);
    264 				contentsOrder->append( ord );
    265 			}
    266 		}
    267 		if ( ordinal != NULL ) {
    268 			*ordinal = ord;
    269 		}
    270 	}
    271 	return retVal!=NULL;
    272 }
    273 
    274 daeBool daeMetaElement::placeAt( daeInt index, daeElement *parent, daeElement *child )
    275 {
    276 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this || index < 0 ) {
    277 		return false;
    278 	}
    279 	daeUInt ord;
    280 	daeElement *retVal = _contentModel->placeElement( parent, child, ord );
    281 	if ( retVal != NULL ) {
    282 		//add to _contents array
    283 		if (_metaContents != NULL) {
    284 			daeElementRefArray* contents =
    285 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
    286 			daeUIntArray* contentsOrder =
    287 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
    288 			daeBool validLoc;
    289 			if ( index > 0 ) {
    290 				validLoc = contentsOrder->get(index) >= ord && contentsOrder->get(index) <= ord;
    291 			}
    292 			else {
    293 				if ( contentsOrder->getCount() == 0 ) {
    294 					validLoc = true;
    295 				}
    296 				else {
    297 					validLoc = contentsOrder->get(index) >= ord;
    298 				}
    299 			}
    300 			if ( validLoc ) {
    301 				contents->insertAt( index, retVal );
    302 				contentsOrder->insertAt( index, ord );
    303 			}
    304 			else {
    305 				_contentModel->removeElement( parent, retVal );
    306 				retVal = NULL;
    307 			}
    308 		}
    309 	}
    310 	if ( retVal != NULL ) {
    311 		//update document pointer
    312 		child->setDocument( parent->getDocument() );
    313 		retVal->setDocument( parent->getDocument() );
    314 	}
    315 	return retVal!=NULL;
    316 }
    317 
    318 daeBool daeMetaElement::placeBefore( daeElement *marker, daeElement *parent, daeElement *child, daeUInt *ordinal )
    319 {
    320 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
    321 		return false;
    322 	}
    323 	daeUInt ord;
    324 	daeElement *retVal = _contentModel->placeElement( parent, child, ord, 0, marker, NULL );
    325 	if ( retVal != NULL ) {
    326 		//add to _contents array
    327 		if (_metaContents != NULL) {
    328 			daeElementRefArray* contents =
    329 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
    330 			daeUIntArray* contentsOrder =
    331 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
    332 			size_t index(0);
    333 			daeBool validLoc = false;
    334 			if ( contents->find( marker, index ) == DAE_OK ) {
    335 				if ( index > 0 ) {
    336 					daeUInt gt = contentsOrder->get(index-1);
    337 					daeUInt lt = contentsOrder->get(index);
    338 					validLoc = gt <= ord && lt >= ord;
    339 				}
    340 				else {
    341 					validLoc = contentsOrder->get(index) >= ord;
    342 				}
    343 			}
    344 			if ( validLoc ) {
    345 				contents->insertAt( index, retVal );
    346 				contentsOrder->insertAt( index, ord );
    347 				if ( ordinal != NULL ) {
    348 					*ordinal = ord;
    349 				}
    350 			}
    351 			else {
    352 				_contentModel->removeElement( parent, retVal );
    353 				retVal = NULL;
    354 			}
    355 		}
    356 	}
    357 	if ( retVal != NULL ) {
    358 		//update document pointer
    359 		child->setDocument( parent->getDocument() );
    360 		retVal->setDocument( parent->getDocument() );
    361 	}
    362 	return retVal!=NULL;
    363 }
    364 
    365 daeBool daeMetaElement::placeAfter( daeElement *marker, daeElement *parent, daeElement *child, daeUInt *ordinal )
    366 {
    367 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
    368 		return false;
    369 	}
    370 	daeUInt ord;
    371 	daeElement *retVal = _contentModel->placeElement( parent, child, ord, 0, NULL, marker );
    372 	if ( retVal != NULL ) {
    373 		//add to _contents array
    374 		if (_metaContents != NULL) {
    375 			daeElementRefArray* contents =
    376 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
    377 			daeUIntArray* contentsOrder =
    378 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
    379 			size_t index(0);
    380 			daeBool validLoc = false;
    381 			if ( contents->find( marker, index ) == DAE_OK ) {
    382 				if ( index < contentsOrder->getCount()-1 ) {
    383 					validLoc = contentsOrder->get(index) <= ord && contentsOrder->get(index+1) >= ord;
    384 				}
    385 				else {
    386 					validLoc = contentsOrder->get(index) <= ord;
    387 				}
    388 			}
    389 			if ( validLoc ) {
    390 				contents->insertAt( index+1, retVal );
    391 				contentsOrder->insertAt( index+1, ord );
    392 				if ( ordinal != NULL ) {
    393 					*ordinal = ord;
    394 				}
    395 			}
    396 			else {
    397 				_contentModel->removeElement( parent, retVal );
    398 				retVal = NULL;
    399 			}
    400 		}
    401 	}
    402 	if ( retVal != NULL ) {
    403 		//update document pointer
    404 		child->setDocument( parent->getDocument() );
    405 		retVal->setDocument( parent->getDocument() );
    406 	}
    407 	return retVal!=NULL;
    408 }
    409 
    410 daeBool daeMetaElement::remove(daeElement *parent, daeElement *child)
    411 {
    412 	if ( parent->getMeta() != this ) {
    413 		return false;
    414 	}
    415 	//prevent child from being deleted
    416 	daeElementRef el( child );
    417 	if ( _contentModel->removeElement( parent, child ) ) {
    418 		if ( _metaContents != NULL)
    419 		{
    420 			daeElementRefArray* contents = (daeElementRefArray*)_metaContents->getWritableMemory(parent);
    421 			daeUIntArray* contentsOrder = (daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
    422 			size_t idx(0);
    423 			if ( contents->remove(child, &idx) == DAE_OK ) {
    424 				contentsOrder->removeIndex( idx );
    425 			}
    426 		}
    427 		if ( child->getDocument() ) {
    428 			child->getDocument()->removeElement( child );
    429 		}
    430 
    431 		// Clear the child's parent pointer
    432 		child->setParentElement( NULL );
    433 
    434 		return true;
    435 	}
    436 	return false;
    437 }
    438 
    439 void daeMetaElement::getChildren( daeElement* parent, daeElementRefArray &array )
    440 {
    441 	if ( parent->getMeta() != this ) {
    442 		return;
    443 	}
    444 	if ( _metaContents != NULL ) {
    445 		daeElementRefArray* contents = (daeElementRefArray*)_metaContents->getWritableMemory(parent);
    446 		for ( size_t x = 0; x < contents->getCount(); x++ ) {
    447 			array.append( contents->get(x) );
    448 		}
    449 	}
    450 	else if ( _contentModel != NULL ) {
    451 		_contentModel->getChildren( parent, array );
    452 	}
    453 }
    454 
    455 // daeMetaElementRefArray &daeMetaElement::_metas()
    456 // {
    457 // 	if (!mera)
    458 // 	{
    459 // 		mera = new daeMetaElementRefArray();
    460 // 	}
    461 // 	return *mera;
    462 // }
    463 
    464 // daeTArray< daeMetaElement** > &daeMetaElement::_classMetaPointers()
    465 // {
    466 // 	if (!mes)
    467 // 	{
    468 // 		mes = new daeTArray< daeMetaElement** >();
    469 // 	}
    470 // 	return *mes;
    471 // }
    472 
    473