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/daeMetaChoice.h> 10 #include <dae/daeMetaElement.h> 11 12 daeMetaChoice::daeMetaChoice( daeMetaElement *container, daeMetaCMPolicy *parent, daeUInt choiceNum, daeUInt ordinal, 13 daeInt minO, daeInt maxO) : daeMetaCMPolicy( container, parent, ordinal, minO, maxO ), _choiceNum(choiceNum) 14 {} 15 16 daeMetaChoice::~daeMetaChoice() 17 {} 18 19 daeElement *daeMetaChoice::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) { 20 (void)offset; 21 if ( _maxOccurs == -1 ) { 22 //Needed to prevent infinate loops. If unbounded check to see if you have the child before just trying to place 23 if ( findChild( child->getElementName() ) == NULL ) { 24 return NULL; 25 } 26 } 27 28 daeElement *retVal = NULL; 29 30 daeTArray< daeCharArray *> *CMData = (daeTArray< daeCharArray *>*)_container->getMetaCMData()->getWritableMemory(parent); 31 daeCharArray *myData = CMData->get( _choiceNum ); 32 size_t count = myData->getCount(); 33 34 for ( daeInt i = 0; ( i < _maxOccurs || _maxOccurs == -1 ); i++ ) 35 { 36 if ( (daeInt) count > i && myData->get(i) != -1 ) //choice has already been made 37 { 38 if ( _children[ myData->get(i) ]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) 39 { 40 retVal = child; 41 ordinal = ordinal + _ordinalOffset; 42 break; 43 } 44 //else //try to see if everything can be in a different choice 45 //{ 46 // daeElementRefArray childsInChoice; 47 // _children[ myData->get(i) ]->getChildren( parent, childsInChoice ); 48 // for ( size_t x = myData->get(i) +1; x < cnt; x++ ) 49 // { 50 // daeElementRefArray childsInNext; 51 // _children[ x ]->getChildren( parent, childsInNext ); //If you get children in another choice then 52 // //both choices can have the same type of children. 53 // if ( childsInNext.getCount() == childsInChoice.getCount() ) 54 // { 55 // //if there are the same ammount of children then all present children can belong to both 56 // //choices. Try to place the new child in this next choice. 57 // if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) 58 // { 59 // retVal = child; 60 // ordinal = ordinal + _ordinalOffset; 61 62 // myData->set( i, (daeChar)x ); //change the choice to this new one 63 // break; 64 // } 65 // } 66 // } 67 // if ( retVal != NULL ) break; 68 //} 69 } 70 else //no choice has been made yet 71 { 72 size_t cnt = _children.getCount(); 73 for ( size_t x = 0; x < cnt; x++ ) 74 { 75 if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) 76 { 77 retVal = child; 78 ordinal = ordinal + _ordinalOffset; 79 80 myData->append( (daeChar)x ); //you always place in the next available choice up to maxOccurs 81 count ++; 82 break; 83 } 84 } 85 if ( retVal != NULL ) break; 86 } 87 } 88 if ( retVal == NULL ) 89 { 90 if ( findChild( child->getElementName() ) == NULL ) { 91 return NULL; 92 } 93 for ( daeInt i = 0; ( i < _maxOccurs || _maxOccurs == -1 ); i++ ) 94 { 95 daeElementRefArray childsInChoice; 96 _children[ myData->get(i) ]->getChildren( parent, childsInChoice ); 97 size_t cnt = _children.getCount(); 98 for ( size_t x = myData->get(i) +1; x < cnt; x++ ) 99 { 100 daeElementRefArray childsInNext; 101 _children[ x ]->getChildren( parent, childsInNext ); //If you get children in another choice then 102 //both choices can have the same type of children. 103 if ( childsInNext.getCount() == childsInChoice.getCount() ) 104 { 105 //if there are the same ammount of children then all present children can belong to both 106 //choices. Try to place the new child in this next choice. 107 if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) 108 { 109 retVal = child; 110 ordinal = ordinal + _ordinalOffset; 111 112 myData->set( i, (daeChar)x ); //change the choice to this new one 113 break; 114 } 115 } 116 } 117 if ( retVal != NULL ) break; 118 } 119 } 120 return retVal; 121 } 122 123 daeBool daeMetaChoice::removeElement( daeElement *parent, daeElement *child ) { 124 size_t cnt = _children.getCount(); 125 for ( size_t x = 0; x < cnt; x++ ) { 126 if ( _children[x]->removeElement( parent, child ) ) { 127 return true; 128 } 129 } 130 return false; 131 } 132 133 daeMetaElement * daeMetaChoice::findChild( daeString elementName ) { 134 daeMetaElement *me = NULL; 135 size_t cnt = _children.getCount(); 136 for ( size_t x = 0; x < cnt; x++ ) { 137 me = _children[x]->findChild( elementName ); 138 if ( me != NULL ) { 139 return me; 140 } 141 } 142 return NULL; 143 } 144 145 void daeMetaChoice::getChildren( daeElement *parent, daeElementRefArray &array ) { 146 size_t cnt = _children.getCount(); 147 for ( size_t x = 0; x < cnt; x++ ) { 148 _children[x]->getChildren( parent, array ); 149 } 150 } 151 152