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
daeMetaChoice(daeMetaElement * container,daeMetaCMPolicy * parent,daeUInt choiceNum,daeUInt ordinal,daeInt minO,daeInt maxO)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
~daeMetaChoice()16 daeMetaChoice::~daeMetaChoice()
17 {}
18
placeElement(daeElement * parent,daeElement * child,daeUInt & ordinal,daeInt offset,daeElement * before,daeElement * after)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
removeElement(daeElement * parent,daeElement * child)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
findChild(daeString elementName)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
getChildren(daeElement * parent,daeElementRefArray & array)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