• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
daeMetaGroup(daeMetaElementAttribute * econ,daeMetaElement * container,daeMetaCMPolicy * parent,daeUInt ordinal,daeInt minO,daeInt maxO)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 
~daeMetaGroup()18 daeMetaGroup::~daeMetaGroup()
19 {
20 	if ( _elementContainer != NULL ) {
21 		delete _elementContainer;
22 	}
23 }
24 
placeElement(daeElement * parent,daeElement * child,daeUInt & ordinal,daeInt offset,daeElement * before,daeElement * after)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 
removeElement(daeElement * parent,daeElement * child)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 
findChild(daeString elementName)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 
getChildren(daeElement * parent,daeElementRefArray & array)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