• 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.h>
10 #include <dae/daeMetaElement.h>
11 #include <dae/daeElement.h>
12 #include <dae/daeDocument.h>
13 #include <dae/domAny.h>
14 #include <dae/daeMetaCMPolicy.h>
15 #include <dae/daeMetaElementAttribute.h>
16 
17 daeElementRef
create()18 daeMetaElement::create()
19 {
20 	daeElementRef ret =  (*_createFunc)(dae);
21 	ret->setup(this);
22 
23 	return ret;
24 }
25 
26 daeElementRef
create(daeString s)27 daeMetaElement::create(daeString s)
28 {
29 	daeMetaElement* me = NULL;
30 	if ( strcmp( s, _name ) == 0 ) {
31 		//looking for this meta
32 		me = this;
33 	}
34 	else if ( _contentModel != NULL ) {
35 		me = _contentModel->findChild(s);
36 	}
37 	if (me != NULL) {
38 		daeElementRef ret = me->create();
39 		if ( strcmp(s, me->getName() ) != 0 ) {
40 			ret->setElementName(s);
41 		}
42 		return ret;
43 	}
44 	if ( getAllowsAny() ) {
45 		daeElementRef ret = domAny::registerElement(dae)->create();
46 		ret->setElementName(s);
47 		return ret;
48 	}
49 	return NULL;
50 }
51 
daeMetaElement(DAE & dae)52 daeMetaElement::daeMetaElement(DAE& dae) : dae(dae)
53 {
54 	_name = "noname";
55 	_createFunc = NULL;
56 	_elementSize = sizeof(daeElement);
57 	_metaValue = NULL;
58 	_metaContents = NULL;
59 	_metaContentsOrder = NULL; // sthomas
60 	_metaID = NULL;
61 	_isTrackableForQueries = true;
62 	_usesStringContents = false;
63 	_isTransparent = false;
64 	_isAbstract = false;
65 	_allowsAny = false;
66 	_innerClass = false;
67 	_contentModel = NULL;
68 	_metaCMData = NULL;
69 	_numMetaChoices = 0;
70 }
71 
~daeMetaElement()72 daeMetaElement::~daeMetaElement()
73 {
74 	delete _metaContents;
75 	delete _contentModel;
76 	delete _metaContentsOrder;
77 	delete _metaCMData;
78 }
79 
getDAE()80 DAE* daeMetaElement::getDAE() {
81 	return &dae;
82 }
83 
setCMRoot(daeMetaCMPolicy * cm)84 void daeMetaElement::setCMRoot( daeMetaCMPolicy *cm )
85 {
86 	if (_contentModel)
87 		delete _contentModel;
88 	_contentModel = cm;
89 }
90 
91 void
addContents(daeInt offset)92 daeMetaElement::addContents(daeInt offset)
93 {
94 	daeMetaElementArrayAttribute* meaa = new daeMetaElementArrayAttribute( this, NULL, 0, 1, -1 );
95 	meaa->setType(dae.getAtomicTypes().get("element"));
96 	meaa->setName("contents");
97 	meaa->setOffset(offset);
98 	meaa->setContainer( this);
99 	_metaContents = meaa;
100 }
101 void
addContentsOrder(daeInt offset)102 daeMetaElement::addContentsOrder(daeInt offset)
103 {
104 	daeMetaArrayAttribute* meaa = new daeMetaArrayAttribute();
105 	meaa->setType(dae.getAtomicTypes().get("uint"));
106 	meaa->setName("contentsOrder");
107 	meaa->setOffset(offset);
108 	meaa->setContainer( this);
109 
110     if (_metaContentsOrder)
111         delete _metaContentsOrder;
112 
113 	_metaContentsOrder = meaa;
114 }
115 
addCMDataArray(daeInt offset,daeUInt numChoices)116 void daeMetaElement::addCMDataArray(daeInt offset, daeUInt numChoices)
117 {
118 	daeMetaArrayAttribute* meaa = new daeMetaArrayAttribute();
119 	meaa->setType(dae.getAtomicTypes().get("int"));
120 	meaa->setName("CMData");
121 	meaa->setOffset(offset);
122 	meaa->setContainer( this);
123 
124     if (_metaCMData)
125         delete _metaCMData;
126 
127 	_metaCMData = meaa;
128 
129 	_numMetaChoices = numChoices;
130 }
131 
132 
133 /*void
134 daeMetaElement::appendArrayElement(daeMetaElement* element, daeInt offset, daeString name)
135 {
136 	daeMetaElementArrayAttribute* meaa = new daeMetaElementArrayAttribute;
137 	meaa->setType(daeAtomicType::get("element"));
138 	if ( name ) {
139 		meaa->setName(name);
140 	}
141 	else {
142 		meaa->setName(element->getName());
143 	}
144 	meaa->setOffset(offset);
145 	meaa->setContainer(this);
146 	meaa->setElementType( element);
147 	_metaElements.append(meaa);
148 }
149 void
150 daeMetaElement::appendElement(daeMetaElement* element, daeInt offset, daeString name)
151 {
152 	daeMetaElementAttribute* meaa = new daeMetaElementAttribute;
153 	meaa->setType(daeAtomicType::get("element"));
154 	if ( name ) {
155 		meaa->setName(name);
156 	}
157 	else {
158 		meaa->setName(element->getName());
159 	}
160 	meaa->setOffset( offset);
161 	meaa->setContainer( this );
162 	meaa->setElementType( element );
163 	_metaElements.append(meaa);
164 }*/
165 
166 void
appendAttribute(daeMetaAttribute * attr)167 daeMetaElement::appendAttribute(daeMetaAttribute* attr)
168 {
169 	if (attr == NULL)
170 		return;
171 
172 	if (strcmp(attr->getName(),"_value") == 0) {
173 		_metaValue = attr;
174 	}
175 	else
176 		_metaAttributes.append(attr);
177 
178 	if ((attr->getName() != NULL) &&
179 		(strcmp(attr->getName(),"id") == 0)) {
180 		_metaID = attr;
181 		_isTrackableForQueries = true;
182 	}
183 }
184 
185 void
validate()186 daeMetaElement::validate()
187 {
188 	if (_elementSize == 0)
189 	{
190 		daeInt place=0;
191 		unsigned int i;
192 		for(i=0;i<_metaAttributes.getCount();i++) {
193 			place += _metaAttributes[i]->getSize();
194 			int align = _metaAttributes[i]->getAlignment();
195 			place += align;
196 			place &= (~(align-1));
197 		}
198 		_elementSize = place;
199 	}
200 }
201 
202 daeMetaAttribute*
getMetaAttribute(daeString s)203 daeMetaElement::getMetaAttribute(daeString s)
204 {
205 	int cnt = (int)_metaAttributes.getCount();
206 	int i;
207 	for(i=0;i<cnt;i++)
208 		if (strcmp(_metaAttributes[i]->getName(),s) == 0)
209 			return _metaAttributes[i];
210 	return NULL;
211 }
212 
213 
214 // void daeMetaElement::releaseMetas()
215 // {
216 // 	_metas().clear();
217 // 	size_t count = _classMetaPointers().getCount();
218 // 	for ( size_t i = 0; i < count; i++ )
219 // 	{
220 // 		*(_classMetaPointers()[i]) = NULL;
221 // 	}
222 // 	_classMetaPointers().clear();
223 // 	if (mera)
224 // 	{
225 // 		delete mera;
226 // 		mera = NULL;
227 // 	}
228 // 	if (mes)
229 // 	{
230 // 		delete mes;
231 // 		mes = NULL;
232 // 	}
233 // }
234 
place(daeElement * parent,daeElement * child,daeUInt * ordinal)235 daeBool daeMetaElement::place(daeElement *parent, daeElement *child, daeUInt *ordinal )
236 {
237 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
238 		return false;
239 	}
240 	daeUInt ord;
241 	daeElement *retVal = _contentModel->placeElement( parent, child, ord );
242 	if ( retVal != NULL ) {
243 		//update document pointer
244 		child->setDocument( parent->getDocument() );
245 		retVal->setDocument( parent->getDocument() );
246 		//add to _contents array
247 		if (_metaContents != NULL) {
248 			daeElementRefArray* contents =
249 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
250 			daeUIntArray* contentsOrder =
251 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
252 			daeBool needsAppend = true;
253 			size_t cnt = contentsOrder->getCount();
254 			for ( size_t x = 0; x < cnt; x++ ) {
255 				if ( contentsOrder->get(x) > ord ) {
256 					contents->insertAt( x, retVal );
257 					contentsOrder->insertAt( x, ord );
258 					needsAppend = false;
259 					break;
260 				}
261 			}
262 			if ( needsAppend ) {
263 				contents->append(retVal);
264 				contentsOrder->append( ord );
265 			}
266 		}
267 		if ( ordinal != NULL ) {
268 			*ordinal = ord;
269 		}
270 	}
271 	return retVal!=NULL;
272 }
273 
placeAt(daeInt index,daeElement * parent,daeElement * child)274 daeBool daeMetaElement::placeAt( daeInt index, daeElement *parent, daeElement *child )
275 {
276 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this || index < 0 ) {
277 		return false;
278 	}
279 	daeUInt ord;
280 	daeElement *retVal = _contentModel->placeElement( parent, child, ord );
281 	if ( retVal != NULL ) {
282 		//add to _contents array
283 		if (_metaContents != NULL) {
284 			daeElementRefArray* contents =
285 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
286 			daeUIntArray* contentsOrder =
287 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
288 			daeBool validLoc;
289 			if ( index > 0 ) {
290 				validLoc = contentsOrder->get(index) >= ord && contentsOrder->get(index) <= ord;
291 			}
292 			else {
293 				if ( contentsOrder->getCount() == 0 ) {
294 					validLoc = true;
295 				}
296 				else {
297 					validLoc = contentsOrder->get(index) >= ord;
298 				}
299 			}
300 			if ( validLoc ) {
301 				contents->insertAt( index, retVal );
302 				contentsOrder->insertAt( index, ord );
303 			}
304 			else {
305 				_contentModel->removeElement( parent, retVal );
306 				retVal = NULL;
307 			}
308 		}
309 	}
310 	if ( retVal != NULL ) {
311 		//update document pointer
312 		child->setDocument( parent->getDocument() );
313 		retVal->setDocument( parent->getDocument() );
314 	}
315 	return retVal!=NULL;
316 }
317 
placeBefore(daeElement * marker,daeElement * parent,daeElement * child,daeUInt * ordinal)318 daeBool daeMetaElement::placeBefore( daeElement *marker, daeElement *parent, daeElement *child, daeUInt *ordinal )
319 {
320 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
321 		return false;
322 	}
323 	daeUInt ord;
324 	daeElement *retVal = _contentModel->placeElement( parent, child, ord, 0, marker, NULL );
325 	if ( retVal != NULL ) {
326 		//add to _contents array
327 		if (_metaContents != NULL) {
328 			daeElementRefArray* contents =
329 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
330 			daeUIntArray* contentsOrder =
331 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
332 			size_t index(0);
333 			daeBool validLoc = false;
334 			if ( contents->find( marker, index ) == DAE_OK ) {
335 				if ( index > 0 ) {
336 					daeUInt gt = contentsOrder->get(index-1);
337 					daeUInt lt = contentsOrder->get(index);
338 					validLoc = gt <= ord && lt >= ord;
339 				}
340 				else {
341 					validLoc = contentsOrder->get(index) >= ord;
342 				}
343 			}
344 			if ( validLoc ) {
345 				contents->insertAt( index, retVal );
346 				contentsOrder->insertAt( index, ord );
347 				if ( ordinal != NULL ) {
348 					*ordinal = ord;
349 				}
350 			}
351 			else {
352 				_contentModel->removeElement( parent, retVal );
353 				retVal = NULL;
354 			}
355 		}
356 	}
357 	if ( retVal != NULL ) {
358 		//update document pointer
359 		child->setDocument( parent->getDocument() );
360 		retVal->setDocument( parent->getDocument() );
361 	}
362 	return retVal!=NULL;
363 }
364 
placeAfter(daeElement * marker,daeElement * parent,daeElement * child,daeUInt * ordinal)365 daeBool daeMetaElement::placeAfter( daeElement *marker, daeElement *parent, daeElement *child, daeUInt *ordinal )
366 {
367 	if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
368 		return false;
369 	}
370 	daeUInt ord;
371 	daeElement *retVal = _contentModel->placeElement( parent, child, ord, 0, NULL, marker );
372 	if ( retVal != NULL ) {
373 		//add to _contents array
374 		if (_metaContents != NULL) {
375 			daeElementRefArray* contents =
376 				(daeElementRefArray*)_metaContents->getWritableMemory(parent);
377 			daeUIntArray* contentsOrder =
378 				(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
379 			size_t index(0);
380 			daeBool validLoc = false;
381 			if ( contents->find( marker, index ) == DAE_OK ) {
382 				if ( index < contentsOrder->getCount()-1 ) {
383 					validLoc = contentsOrder->get(index) <= ord && contentsOrder->get(index+1) >= ord;
384 				}
385 				else {
386 					validLoc = contentsOrder->get(index) <= ord;
387 				}
388 			}
389 			if ( validLoc ) {
390 				contents->insertAt( index+1, retVal );
391 				contentsOrder->insertAt( index+1, ord );
392 				if ( ordinal != NULL ) {
393 					*ordinal = ord;
394 				}
395 			}
396 			else {
397 				_contentModel->removeElement( parent, retVal );
398 				retVal = NULL;
399 			}
400 		}
401 	}
402 	if ( retVal != NULL ) {
403 		//update document pointer
404 		child->setDocument( parent->getDocument() );
405 		retVal->setDocument( parent->getDocument() );
406 	}
407 	return retVal!=NULL;
408 }
409 
remove(daeElement * parent,daeElement * child)410 daeBool daeMetaElement::remove(daeElement *parent, daeElement *child)
411 {
412 	if ( parent->getMeta() != this ) {
413 		return false;
414 	}
415 	//prevent child from being deleted
416 	daeElementRef el( child );
417 	if ( _contentModel->removeElement( parent, child ) ) {
418 		if ( _metaContents != NULL)
419 		{
420 			daeElementRefArray* contents = (daeElementRefArray*)_metaContents->getWritableMemory(parent);
421 			daeUIntArray* contentsOrder = (daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
422 			size_t idx(0);
423 			if ( contents->remove(child, &idx) == DAE_OK ) {
424 				contentsOrder->removeIndex( idx );
425 			}
426 		}
427 		if ( child->getDocument() ) {
428 			child->getDocument()->removeElement( child );
429 		}
430 
431 		// Clear the child's parent pointer
432 		child->setParentElement( NULL );
433 
434 		return true;
435 	}
436 	return false;
437 }
438 
getChildren(daeElement * parent,daeElementRefArray & array)439 void daeMetaElement::getChildren( daeElement* parent, daeElementRefArray &array )
440 {
441 	if ( parent->getMeta() != this ) {
442 		return;
443 	}
444 	if ( _metaContents != NULL ) {
445 		daeElementRefArray* contents = (daeElementRefArray*)_metaContents->getWritableMemory(parent);
446 		for ( size_t x = 0; x < contents->getCount(); x++ ) {
447 			array.append( contents->get(x) );
448 		}
449 	}
450 	else if ( _contentModel != NULL ) {
451 		_contentModel->getChildren( parent, array );
452 	}
453 }
454 
455 // daeMetaElementRefArray &daeMetaElement::_metas()
456 // {
457 // 	if (!mera)
458 // 	{
459 // 		mera = new daeMetaElementRefArray();
460 // 	}
461 // 	return *mera;
462 // }
463 
464 // daeTArray< daeMetaElement** > &daeMetaElement::_classMetaPointers()
465 // {
466 // 	if (!mes)
467 // 	{
468 // 		mes = new daeTArray< daeMetaElement** >();
469 // 	}
470 // 	return *mes;
471 // }
472 
473