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