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/daeMetaGroup.h>
     10 #include <dae/daeMetaElementAttribute.h>
     11 #include <dae/daeMetaElement.h>
     12 
     13 daeMetaGroup::daeMetaGroup( daeMetaElementAttribute *econ, daeMetaElement *container,
     14 							daeMetaCMPolicy *parent, daeUInt ordinal, daeInt minO, daeInt maxO) :
     15 							daeMetaCMPolicy( container, parent, ordinal, minO, maxO ), _elementContainer( econ )
     16 {}
     17 
     18 daeMetaGroup::~daeMetaGroup()
     19 {
     20 	if ( _elementContainer != NULL ) {
     21 		delete _elementContainer;
     22 	}
     23 }
     24 
     25 daeElement *daeMetaGroup::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) {
     26 	(void)offset;
     27 	daeString nm = child->getElementName();
     28 	if ( findChild( nm ) == NULL ) {
     29 		return false;
     30 	}
     31 	daeElementRef el;
     32 
     33 	//check if the element trying to be placed is a group element. If so Just add it don't create a new one.
     34 	if ( strcmp( nm, _elementContainer->getName() ) == 0 ) {
     35 		if ( _elementContainer->placeElement(parent, child, ordinal, offset ) != NULL ) {
     36 			return child;
     37 		}
     38 	}
     39 
     40 #if 1
     41 	daeInt elCnt = _elementContainer->getCount(parent);
     42 	//check existing groups
     43       //This doesn't work properly. Because the choice can't check if you make two decisions you cannot fail
     44 	  //here when you are supposed to. Luckily the current schema just has groups with single choices so
     45 	  //every element needs a new group container. Wasteful but thats how the schema is and its how it works.
     46 	for ( daeInt x = 0; x < elCnt; x++ ) {
     47 		daeMemoryRef mem = _elementContainer->get(parent, x );
     48 		if ( mem != NULL ) {
     49 			el = *(daeElementRef*)mem;
     50 		}
     51 		if ( el == NULL ) {
     52 			continue;
     53 		}
     54 		if ( before != NULL ) {
     55 			if ( _elementContainer->_elementType->placeBefore( before, el, child, &ordinal ) ) {
     56 				ordinal = ordinal + _ordinalOffset;
     57 				return el;
     58 			}
     59 		}
     60 		else if ( after != NULL ) {
     61 			if ( _elementContainer->_elementType->placeAfter( after, el, child, &ordinal ) ) {
     62 				ordinal = ordinal + _ordinalOffset;
     63 				return el;
     64 			}
     65 		}
     66 		else {
     67 			if ( _elementContainer->_elementType->place( el, child, &ordinal ) ) {
     68 				ordinal = ordinal + _ordinalOffset;
     69 				return el;
     70 			}
     71 		}
     72 	}
     73 #endif
     74 	//if you couldn't place in existing groups make a new one if you can
     75 	el = _elementContainer->placeElement(parent, _elementContainer->_elementType->create(), ordinal, offset );
     76 	if ( el != NULL ) {
     77 		//el = *(daeElementRef*)_elementContainer->get(parent, elCnt );
     78 		if ( before != NULL ) {
     79 			if ( _elementContainer->_elementType->placeBefore( before, el, child, &ordinal ) ) {
     80 				ordinal = ordinal + _ordinalOffset;
     81 				return el;
     82 			}
     83 		}
     84 		else if ( after != NULL ) {
     85 			if ( _elementContainer->_elementType->placeAfter( after, el, child, &ordinal ) ) {
     86 				ordinal = ordinal + _ordinalOffset;
     87 				return el;
     88 			}
     89 		}
     90 		else {
     91 			if ( _elementContainer->_elementType->place( el, child, &ordinal ) ) {
     92 				ordinal = ordinal + _ordinalOffset;
     93 				return el;
     94 			}
     95 		}
     96 	}
     97 	return NULL;
     98 }
     99 
    100 daeBool daeMetaGroup::removeElement( daeElement *parent, daeElement *child ) {
    101 	daeElementRef el;
    102 	daeInt elCnt = _elementContainer->getCount(parent);
    103 	for ( daeInt x = 0; x < elCnt; x++ ) {
    104 		daeMemoryRef mem = _elementContainer->get(parent, x );
    105 		if ( mem != NULL ) {
    106 			el = *(daeElementRef*)mem;
    107 		}
    108 		if ( el == NULL ) {
    109 			continue;
    110 		}
    111 		if ( el->removeChildElement( child ) ) {
    112 			//check if there are any more children in this group. If not remove the group container element too.
    113 			daeElementRefArray array;
    114 			getChildren( parent, array );
    115 			if ( array.getCount() == 0 )
    116 			{
    117 				_elementContainer->removeElement( parent, el );
    118 			}
    119 			return true;
    120 		}
    121 	}
    122 	return false;
    123 }
    124 
    125 daeMetaElement * daeMetaGroup::findChild( daeString elementName ) {
    126 	if ( strcmp( _elementContainer->getName(), elementName ) == 0 ) {
    127 		return _elementContainer->getElementType();
    128 	}
    129 	return _elementContainer->_elementType->getCMRoot()->findChild( elementName );
    130 }
    131 
    132 void daeMetaGroup::getChildren( daeElement *parent, daeElementRefArray &array ) {
    133 	size_t cnt = _elementContainer->getCount( parent );
    134 	for ( size_t x = 0; x < cnt; x++ ) {
    135 		(*((daeElementRef*)_elementContainer->get(parent, (daeInt)x )))->getChildren( array );
    136 		/*daeElementRef el = (*((daeElementRef*)_elementContainer->get(parent, (daeInt)x )));
    137 		size_t cnt2 = _children.getCount();
    138 		for ( size_t i = 0; i < cnt2; i++ ) {
    139 			_children[i]->getChildren( el, array );
    140 		}*/
    141 	}
    142 	//_elementContainer->_elementType->getChildren( parent, array );
    143 }
    144 
    145