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