/* * Copyright 2006 Sony Computer Entertainment Inc. * * Licensed under the MIT Open Source License, for details please see license.txt or the website * http://www.opensource.org/licenses/mit-license.php * */ #include <dae/daeMetaChoice.h> #include <dae/daeMetaElement.h> daeMetaChoice::daeMetaChoice( daeMetaElement *container, daeMetaCMPolicy *parent, daeUInt choiceNum, daeUInt ordinal, daeInt minO, daeInt maxO) : daeMetaCMPolicy( container, parent, ordinal, minO, maxO ), _choiceNum(choiceNum) {} daeMetaChoice::~daeMetaChoice() {} daeElement *daeMetaChoice::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) { (void)offset; if ( _maxOccurs == -1 ) { //Needed to prevent infinate loops. If unbounded check to see if you have the child before just trying to place if ( findChild( child->getElementName() ) == NULL ) { return NULL; } } daeElement *retVal = NULL; daeTArray< daeCharArray *> *CMData = (daeTArray< daeCharArray *>*)_container->getMetaCMData()->getWritableMemory(parent); daeCharArray *myData = CMData->get( _choiceNum ); size_t count = myData->getCount(); for ( daeInt i = 0; ( i < _maxOccurs || _maxOccurs == -1 ); i++ ) { if ( (daeInt) count > i && myData->get(i) != -1 ) //choice has already been made { if ( _children[ myData->get(i) ]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) { retVal = child; ordinal = ordinal + _ordinalOffset; break; } //else //try to see if everything can be in a different choice //{ // daeElementRefArray childsInChoice; // _children[ myData->get(i) ]->getChildren( parent, childsInChoice ); // for ( size_t x = myData->get(i) +1; x < cnt; x++ ) // { // daeElementRefArray childsInNext; // _children[ x ]->getChildren( parent, childsInNext ); //If you get children in another choice then // //both choices can have the same type of children. // if ( childsInNext.getCount() == childsInChoice.getCount() ) // { // //if there are the same ammount of children then all present children can belong to both // //choices. Try to place the new child in this next choice. // if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) // { // retVal = child; // ordinal = ordinal + _ordinalOffset; // myData->set( i, (daeChar)x ); //change the choice to this new one // break; // } // } // } // if ( retVal != NULL ) break; //} } else //no choice has been made yet { size_t cnt = _children.getCount(); for ( size_t x = 0; x < cnt; x++ ) { if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) { retVal = child; ordinal = ordinal + _ordinalOffset; myData->append( (daeChar)x ); //you always place in the next available choice up to maxOccurs count ++; break; } } if ( retVal != NULL ) break; } } if ( retVal == NULL ) { if ( findChild( child->getElementName() ) == NULL ) { return NULL; } for ( daeInt i = 0; ( i < _maxOccurs || _maxOccurs == -1 ); i++ ) { daeElementRefArray childsInChoice; _children[ myData->get(i) ]->getChildren( parent, childsInChoice ); size_t cnt = _children.getCount(); for ( size_t x = myData->get(i) +1; x < cnt; x++ ) { daeElementRefArray childsInNext; _children[ x ]->getChildren( parent, childsInNext ); //If you get children in another choice then //both choices can have the same type of children. if ( childsInNext.getCount() == childsInChoice.getCount() ) { //if there are the same ammount of children then all present children can belong to both //choices. Try to place the new child in this next choice. if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) { retVal = child; ordinal = ordinal + _ordinalOffset; myData->set( i, (daeChar)x ); //change the choice to this new one break; } } } if ( retVal != NULL ) break; } } return retVal; } daeBool daeMetaChoice::removeElement( daeElement *parent, daeElement *child ) { size_t cnt = _children.getCount(); for ( size_t x = 0; x < cnt; x++ ) { if ( _children[x]->removeElement( parent, child ) ) { return true; } } return false; } daeMetaElement * daeMetaChoice::findChild( daeString elementName ) { daeMetaElement *me = NULL; size_t cnt = _children.getCount(); for ( size_t x = 0; x < cnt; x++ ) { me = _children[x]->findChild( elementName ); if ( me != NULL ) { return me; } } return NULL; } void daeMetaChoice::getChildren( daeElement *parent, daeElementRefArray &array ) { size_t cnt = _children.getCount(); for ( size_t x = 0; x < cnt; x++ ) { _children[x]->getChildren( parent, array ); } }