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