1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #include "CAttributes.h"
6 #include "CAttributeImpl.h"
7 #include "ITexture.h"
8 #include "IXMLWriter.h"
9 #include "IVideoDriver.h"
10 
11 namespace irr
12 {
13 namespace io
14 {
15 
CAttributes(video::IVideoDriver * driver)16 CAttributes::CAttributes(video::IVideoDriver* driver)
17 : Driver(driver)
18 {
19 	#ifdef _DEBUG
20 	setDebugName("CAttributes");
21 	#endif
22 
23 	if (Driver)
24 		Driver->grab();
25 }
26 
~CAttributes()27 CAttributes::~CAttributes()
28 {
29 	clear();
30 
31 	if (Driver)
32 		Driver->drop();
33 }
34 
35 
36 //! Removes all attributes
clear()37 void CAttributes::clear()
38 {
39 	for (u32 i=0; i<Attributes.size(); ++i)
40 		Attributes[i]->drop();
41 
42 	Attributes.clear();
43 }
44 
45 
46 //! Sets a string attribute.
47 //! \param attributeName: Name for the attribute
48 //! \param value: Value for the attribute. Set this to 0 to delete the attribute
setAttribute(const c8 * attributeName,const c8 * value)49 void CAttributes::setAttribute(const c8* attributeName, const c8* value)
50 {
51 	for (u32 i=0; i<Attributes.size(); ++i)
52 		if (Attributes[i]->Name == attributeName)
53 		{
54 			if (!value)
55 			{
56 				Attributes[i]->drop();
57 				Attributes.erase(i);
58 			}
59 			else
60 				Attributes[i]->setString(value);
61 
62 			return;
63 		}
64 
65 	if (value)
66 	{
67 		Attributes.push_back(new CStringAttribute(attributeName, value));
68 	}
69 }
70 
71 //! Gets a string attribute.
72 //! \param attributeName: Name of the attribute to get.
73 //! \return Returns value of the attribute previously set by setStringAttribute()
74 //! or 0 if attribute is not set.
getAttributeAsString(const c8 * attributeName)75 core::stringc CAttributes::getAttributeAsString(const c8* attributeName)
76 {
77 	core::stringc str;
78 
79 	IAttribute* att = getAttributeP(attributeName);
80 	if (att)
81 		return att->getString();
82 	else
83 		return str;
84 }
85 
86 //! Gets a string attribute.
87 //! \param attributeName: Name of the attribute to get.
88 //! \param target: Buffer where the string is copied to.
getAttributeAsString(const c8 * attributeName,char * target)89 void CAttributes::getAttributeAsString(const c8* attributeName, char* target)
90 {
91 	IAttribute* att = getAttributeP(attributeName);
92 	if (att)
93 	{
94 		core::stringc str = att->getString();
95 		strcpy(target,str.c_str());
96 	}
97 	else
98 		target[0] = 0;
99 }
100 
101 //! Returns string attribute value by index.
102 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsString(s32 index)103 core::stringc CAttributes::getAttributeAsString(s32 index)
104 {
105 	core::stringc str;
106 
107 	if ((u32)index < Attributes.size())
108 		return Attributes[index]->getString();
109 
110 	return str;
111 }
112 
113 
114 //! Sets a string attribute.
115 //! \param attributeName: Name for the attribute
116 //! \param value: Value for the attribute. Set this to 0 to delete the attribute
setAttribute(const c8 * attributeName,const wchar_t * value)117 void CAttributes::setAttribute(const c8* attributeName, const wchar_t* value)
118 {
119 	for (u32 i=0; i<Attributes.size(); ++i)
120 	{
121 		if (Attributes[i]->Name == attributeName)
122 		{
123 			if (!value)
124 			{
125 				Attributes[i]->drop();
126 				Attributes.erase(i);
127 			}
128 			else
129 				Attributes[i]->setString(value);
130 
131 			return;
132 		}
133 	}
134 
135 	if (value)
136 	{
137 		Attributes.push_back(new CStringAttribute(attributeName, value));
138 	}
139 }
140 
141 //! Gets a string attribute.
142 //! \param attributeName: Name of the attribute to get.
143 //! \return Returns value of the attribute previously set by setStringAttribute()
144 //! or 0 if attribute is not set.
getAttributeAsStringW(const c8 * attributeName)145 core::stringw CAttributes::getAttributeAsStringW(const c8* attributeName)
146 {
147 	core::stringw str;
148 
149 	IAttribute* att = getAttributeP(attributeName);
150 	if (att)
151 		str = att->getStringW();
152 
153 	return str;
154 }
155 
156 //! Gets a string attribute.
157 //! \param attributeName: Name of the attribute to get.
158 //! \param target: Buffer where the string is copied to.
getAttributeAsStringW(const c8 * attributeName,wchar_t * target)159 void CAttributes::getAttributeAsStringW(const c8* attributeName, wchar_t* target)
160 {
161 	IAttribute* att = getAttributeP(attributeName);
162 	if (att)
163 	{
164 		core::stringw str = att->getStringW();
165 		wcscpy(target,str.c_str());
166 	}
167 	else
168 		target[0] = 0;
169 }
170 
171 //! Returns string attribute value by index.
172 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsStringW(s32 index)173 core::stringw CAttributes::getAttributeAsStringW(s32 index)
174 {
175 
176 	if ((u32)index < Attributes.size())
177 		return Attributes[index]->getStringW();
178 	else
179 		return core::stringw();
180 }
181 
182 
183 //! Adds an attribute as an array of wide strings
addArray(const c8 * attributeName,const core::array<core::stringw> & value)184 void CAttributes::addArray(const c8* attributeName, const core::array<core::stringw>& value)
185 {
186 	Attributes.push_back(new CStringWArrayAttribute(attributeName, value));
187 }
188 
189 //! Sets an attribute value as an array of wide strings.
setAttribute(const c8 * attributeName,const core::array<core::stringw> & value)190 void CAttributes::setAttribute(const c8* attributeName, const core::array<core::stringw>& value)
191 {
192 	IAttribute* att = getAttributeP(attributeName);
193 	if (att)
194 		att->setArray(value);
195 	else
196 	{
197 		Attributes.push_back(new CStringWArrayAttribute(attributeName, value));
198 	}
199 }
200 
201 //! Gets an attribute as an array of wide strings.
getAttributeAsArray(const c8 * attributeName)202 core::array<core::stringw> CAttributes::getAttributeAsArray(const c8* attributeName)
203 {
204 	IAttribute* att = getAttributeP(attributeName);
205 	if (att)
206 		return att->getArray();
207 	else
208 		return core::array<core::stringw>();
209 }
210 
211 //! Returns attribute value as an array of wide strings by index.
getAttributeAsArray(s32 index)212 core::array<core::stringw> CAttributes::getAttributeAsArray(s32 index)
213 {
214 	core::array<core::stringw> ret;
215 
216 	if (index >= 0 && index < (s32)Attributes.size())
217 		ret = Attributes[index]->getArray();
218 
219 	return ret;
220 }
221 
222 //! Sets an attribute as an array of wide strings
setAttribute(s32 index,const core::array<core::stringw> & value)223 void CAttributes::setAttribute(s32 index, const core::array<core::stringw>& value)
224 {
225 	if (index >= 0 && index < (s32)Attributes.size() )
226 		Attributes[index]->setArray(value);
227 }
228 
229 
230 
231 
232 //! Returns attribute index from name, -1 if not found
findAttribute(const c8 * attributeName) const233 s32 CAttributes::findAttribute(const c8* attributeName) const
234 {
235 	for (u32 i=0; i<Attributes.size(); ++i)
236 		if (Attributes[i]->Name == attributeName)
237 			return i;
238 
239 	return -1;
240 }
241 
242 
getAttributeP(const c8 * attributeName) const243 IAttribute* CAttributes::getAttributeP(const c8* attributeName) const
244 {
245 	for (u32 i=0; i<Attributes.size(); ++i)
246 		if (Attributes[i]->Name == attributeName)
247 			return Attributes[i];
248 
249 	return 0;
250 }
251 
252 
253 //! Sets a attribute as boolean value
setAttribute(const c8 * attributeName,bool value)254 void CAttributes::setAttribute(const c8* attributeName, bool value)
255 {
256 	IAttribute* att = getAttributeP(attributeName);
257 	if (att)
258 		att->setBool(value);
259 	else
260 	{
261 		Attributes.push_back(new CBoolAttribute(attributeName, value));
262 	}
263 }
264 
265 //! Gets a attribute as boolean value
266 //! \param attributeName: Name of the attribute to get.
267 //! \return Returns value of the attribute previously set by setAttribute() as bool
268 //! or 0 if attribute is not set.
getAttributeAsBool(const c8 * attributeName)269 bool CAttributes::getAttributeAsBool(const c8* attributeName)
270 {
271 	bool ret = false;
272 
273 	IAttribute* att = getAttributeP(attributeName);
274 	if (att)
275 		ret = att->getBool();
276 
277 	_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
278 	return ret;
279 }
280 
281 //! Sets a attribute as integer value
setAttribute(const c8 * attributeName,s32 value)282 void CAttributes::setAttribute(const c8* attributeName, s32 value)
283 {
284 	IAttribute* att = getAttributeP(attributeName);
285 	if (att)
286 		att->setInt(value);
287 	else
288 	{
289 		Attributes.push_back(new CIntAttribute(attributeName, value));
290 	}
291 }
292 
293 //! Gets a attribute as integer value
294 //! \param attributeName: Name of the attribute to get.
295 //! \return Returns value of the attribute previously set by setAttribute() as integer
296 //! or 0 if attribute is not set.
getAttributeAsInt(const c8 * attributeName) const297 s32 CAttributes::getAttributeAsInt(const c8* attributeName) const
298 {
299 	IAttribute* att = getAttributeP(attributeName);
300 	if (att)
301 		return att->getInt();
302 	else
303 		return 0;
304 }
305 
306 //! Sets a attribute as float value
setAttribute(const c8 * attributeName,f32 value)307 void CAttributes::setAttribute(const c8* attributeName, f32 value)
308 {
309 	IAttribute* att = getAttributeP(attributeName);
310 	if (att)
311 		att->setFloat(value);
312 	else
313 		Attributes.push_back(new CFloatAttribute(attributeName, value));
314 }
315 
316 //! Gets a attribute as integer value
317 //! \param attributeName: Name of the attribute to get.
318 //! \return Returns value of the attribute previously set by setAttribute() as float value
319 //! or 0 if attribute is not set.
getAttributeAsFloat(const c8 * attributeName)320 f32 CAttributes::getAttributeAsFloat(const c8* attributeName)
321 {
322 	IAttribute* att = getAttributeP(attributeName);
323 	if (att)
324 		return att->getFloat();
325 
326 	return 0.f;
327 }
328 
329 //! Sets a attribute as color
setAttribute(const c8 * attributeName,video::SColor value)330 void CAttributes::setAttribute(const c8* attributeName, video::SColor value)
331 {
332 	IAttribute* att = getAttributeP(attributeName);
333 	if (att)
334 		att->setColor(value);
335 	else
336 		Attributes.push_back(new CColorAttribute(attributeName, value));
337 }
338 
339 //! Gets an attribute as color
340 //! \param attributeName: Name of the attribute to get.
341 //! \return Returns value of the attribute previously set by setAttribute()
getAttributeAsColor(const c8 * attributeName)342 video::SColor CAttributes::getAttributeAsColor(const c8* attributeName)
343 {
344 	video::SColor ret(0);
345 
346 	IAttribute* att = getAttributeP(attributeName);
347 	if (att)
348 		ret = att->getColor();
349 
350 	return ret;
351 }
352 
353 //! Sets a attribute as floating point color
setAttribute(const c8 * attributeName,video::SColorf value)354 void CAttributes::setAttribute(const c8* attributeName, video::SColorf value)
355 {
356 	IAttribute* att = getAttributeP(attributeName);
357 	if (att)
358 		att->setColor(value);
359 	else
360 		Attributes.push_back(new CColorfAttribute(attributeName, value));
361 }
362 
363 //! Gets an attribute as floating point color
364 //! \param attributeName: Name of the attribute to get.
365 //! \return Returns value of the attribute previously set by setAttribute()
getAttributeAsColorf(const c8 * attributeName)366 video::SColorf CAttributes::getAttributeAsColorf(const c8* attributeName)
367 {
368 	IAttribute* att = getAttributeP(attributeName);
369 	if (att)
370 		return att->getColorf();
371 	else
372 		return video::SColorf();
373 }
374 
375 //! Sets a attribute as 2d position
setAttribute(const c8 * attributeName,core::position2di value)376 void CAttributes::setAttribute(const c8* attributeName, core::position2di value)
377 {
378 	IAttribute* att = getAttributeP(attributeName);
379 	if (att)
380 		att->setPosition(value);
381 	else
382 		Attributes.push_back(new CPosition2DAttribute(attributeName, value));
383 }
384 
385 //! Gets an attribute as 2d position
386 //! \param attributeName: Name of the attribute to get.
387 //! \return Returns value of the attribute previously set by setAttribute()
getAttributeAsPosition2d(const c8 * attributeName)388 core::position2di CAttributes::getAttributeAsPosition2d(const c8* attributeName)
389 {
390 	IAttribute* att = getAttributeP(attributeName);
391 	if (att)
392 		return att->getPosition();
393 	else
394 		return core::position2di();
395 }
396 
397 //! Sets a attribute as rectangle
setAttribute(const c8 * attributeName,core::rect<s32> value)398 void CAttributes::setAttribute(const c8* attributeName, core::rect<s32> value)
399 {
400 	IAttribute* att = getAttributeP(attributeName);
401 	if (att)
402 		att->setRect(value);
403 	else
404 		Attributes.push_back(new CRectAttribute(attributeName, value));
405 }
406 
407 //! Gets an attribute as rectangle
408 //! \param attributeName: Name of the attribute to get.
409 //! \return Returns value of the attribute previously set by setAttribute()
getAttributeAsRect(const c8 * attributeName)410 core::rect<s32> CAttributes::getAttributeAsRect(const c8* attributeName)
411 {
412 	IAttribute* att = getAttributeP(attributeName);
413 	if (att)
414 		return att->getRect();
415 	else
416 		return core::rect<s32>();
417 }
418 
419 //! Sets a attribute as dimension2d
setAttribute(const c8 * attributeName,core::dimension2d<u32> value)420 void CAttributes::setAttribute(const c8* attributeName, core::dimension2d<u32> value)
421 {
422 	IAttribute* att = getAttributeP(attributeName);
423 	if (att)
424 		att->setDimension2d(value);
425 	else
426 		Attributes.push_back(new CDimension2dAttribute(attributeName, value));
427 }
428 
429 //! Gets an attribute as dimension2d
430 //! \param attributeName: Name of the attribute to get.
431 //! \return Returns value of the attribute previously set by setAttribute()
getAttributeAsDimension2d(const c8 * attributeName)432 core::dimension2d<u32> CAttributes::getAttributeAsDimension2d(const c8* attributeName)
433 {
434 	IAttribute* att = getAttributeP(attributeName);
435 	if (att)
436 		return att->getDimension2d();
437 	else
438 		return core::dimension2d<u32>();
439 }
440 
441 //! Sets a attribute as vector
setAttribute(const c8 * attributeName,core::vector3df value)442 void CAttributes::setAttribute(const c8* attributeName, core::vector3df value)
443 {
444 	IAttribute* att = getAttributeP(attributeName);
445 	if (att)
446 		att->setVector(value);
447 	else
448 		Attributes.push_back(new CVector3DAttribute(attributeName, value));
449 }
450 
451 //! Sets a attribute as vector
setAttribute(const c8 * attributeName,core::vector2df value)452 void CAttributes::setAttribute(const c8* attributeName, core::vector2df value)
453 {
454 	IAttribute* att = getAttributeP(attributeName);
455 	if (att)
456 		att->setVector2d(value);
457 	else
458 		Attributes.push_back(new CVector2DAttribute(attributeName, value));
459 }
460 
461 //! Gets an attribute as vector
462 //! \param attributeName: Name of the attribute to get.
463 //! \return Returns value of the attribute previously set by setAttribute()
getAttributeAsVector3d(const c8 * attributeName)464 core::vector3df CAttributes::getAttributeAsVector3d(const c8* attributeName)
465 {
466 	IAttribute* att = getAttributeP(attributeName);
467 	if (att)
468 		return att->getVector();
469 	else
470 		return core::vector3df();
471 }
472 
473 //! Gets an attribute as vector
getAttributeAsVector2d(const c8 * attributeName)474 core::vector2df CAttributes::getAttributeAsVector2d(const c8* attributeName)
475 {
476 	IAttribute* att = getAttributeP(attributeName);
477 	if (att)
478 		return att->getVector2d();
479 	else
480 		return core::vector2df();
481 }
482 
483 //! Sets an attribute as binary data
setAttribute(const c8 * attributeName,void * data,s32 dataSizeInBytes)484 void CAttributes::setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes )
485 {
486 	IAttribute* att = getAttributeP(attributeName);
487 	if (att)
488 		att->setBinary(data, dataSizeInBytes);
489 	else
490 		Attributes.push_back(new CBinaryAttribute(attributeName, data, dataSizeInBytes));
491 }
492 
493 //! Gets an attribute as binary data
494 //! \param attributeName: Name of the attribute to get.
getAttributeAsBinaryData(const c8 * attributeName,void * outData,s32 maxSizeInBytes)495 void CAttributes::getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes)
496 {
497 	IAttribute* att = getAttributeP(attributeName);
498 	if (att)
499 		att->getBinary(outData, maxSizeInBytes);
500 }
501 
502 //! Sets an attribute as enumeration
setAttribute(const c8 * attributeName,const char * enumValue,const char * const * enumerationLiterals)503 void CAttributes::setAttribute(const c8* attributeName, const char* enumValue, const char* const* enumerationLiterals)
504 {
505 	IAttribute* att = getAttributeP(attributeName);
506 	if (att)
507 		att->setEnum(enumValue, enumerationLiterals);
508 	else
509 		Attributes.push_back(new CEnumAttribute(attributeName, enumValue, enumerationLiterals));
510 }
511 
512 //! Gets an attribute as enumeration
513 //! \param attributeName: Name of the attribute to get.
514 //! \return Returns value of the attribute previously set by setAttribute()
getAttributeAsEnumeration(const c8 * attributeName)515 const char* CAttributes::getAttributeAsEnumeration(const c8* attributeName)
516 {
517 	IAttribute* att = getAttributeP(attributeName);
518 	if (att)
519 		return att->getEnum();
520 	else
521 		return 0;
522 }
523 
524 //! Gets an attribute as enumeration
getAttributeAsEnumeration(const c8 * attributeName,const char * const * enumerationLiteralsToUse)525 s32 CAttributes::getAttributeAsEnumeration(const c8* attributeName, const char* const* enumerationLiteralsToUse)
526 {
527 	IAttribute* att = getAttributeP(attributeName);
528 
529 	if (enumerationLiteralsToUse && att)
530 	{
531 		const char* value = att->getEnum();
532 		if (value)
533 		{
534 			for (s32 i=0; enumerationLiteralsToUse[i]; ++i)
535 				if (!strcmp(value, enumerationLiteralsToUse[i]))
536 					return i;
537 		}
538 	}
539 
540 	return -1;
541 }
542 
543 //! Gets the list of enumeration literals of an enumeration attribute
544 //! \param attributeName: Name of the attribute to get.
getAttributeEnumerationLiteralsOfEnumeration(const c8 * attributeName,core::array<core::stringc> & outLiterals)545 void CAttributes::getAttributeEnumerationLiteralsOfEnumeration(const c8* attributeName, core::array<core::stringc>& outLiterals)
546 {
547 	IAttribute* att = getAttributeP(attributeName);
548 
549 	if (att && att->getType() == EAT_ENUM)
550 		outLiterals = ((CEnumAttribute*)att)->EnumLiterals;
551 }
552 
553 //! Sets an attribute as texture reference
setAttribute(const c8 * attributeName,video::ITexture * value,const io::path & filename)554 void CAttributes::setAttribute(const c8* attributeName, video::ITexture* value, const io::path& filename)
555 {
556 	IAttribute* att = getAttributeP(attributeName);
557 	if (att)
558 		att->setTexture(value, filename);
559 	else
560 		Attributes.push_back(new CTextureAttribute(attributeName, value, Driver, filename));
561 }
562 
563 
564 //! Gets an attribute as texture reference
565 //! \param attributeName: Name of the attribute to get.
getAttributeAsTexture(const c8 * attributeName)566 video::ITexture* CAttributes::getAttributeAsTexture(const c8* attributeName)
567 {
568 	IAttribute* att = getAttributeP(attributeName);
569 	if (att)
570 		return att->getTexture();
571 	else
572 		return 0;
573 }
574 
575 //! Gets an attribute as texture reference
576 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsTexture(s32 index)577 video::ITexture* CAttributes::getAttributeAsTexture(s32 index)
578 {
579 	if ((u32)index < Attributes.size())
580 		return Attributes[index]->getTexture();
581 	else
582 		return 0;
583 }
584 
585 
586 //! Returns amount of string attributes set in this scene manager.
getAttributeCount() const587 u32 CAttributes::getAttributeCount() const
588 {
589 	return Attributes.size();
590 }
591 
592 //! Returns string attribute name by index.
593 //! \param index: Index value, must be between 0 and getStringAttributeCount()-1.
getAttributeName(s32 index)594 const c8* CAttributes::getAttributeName(s32 index)
595 {
596 	if ((u32)index >= Attributes.size())
597 		return 0;
598 
599 	return Attributes[index]->Name.c_str();
600 }
601 
602 //! Returns the type of an attribute
getAttributeType(const c8 * attributeName)603 E_ATTRIBUTE_TYPE CAttributes::getAttributeType(const c8* attributeName)
604 {
605 	E_ATTRIBUTE_TYPE ret = EAT_UNKNOWN;
606 
607 	IAttribute* att = getAttributeP(attributeName);
608 	if (att)
609 		ret = att->getType();
610 
611 	return ret;
612 }
613 
614 //! Returns attribute type by index.
615 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeType(s32 index)616 E_ATTRIBUTE_TYPE CAttributes::getAttributeType(s32 index)
617 {
618 	if ((u32)index >= Attributes.size())
619 		return EAT_UNKNOWN;
620 
621 	return Attributes[index]->getType();
622 }
623 
624 //! Returns the type of an attribute
getAttributeTypeString(const c8 * attributeName)625 const wchar_t* CAttributes::getAttributeTypeString(const c8* attributeName)
626 {
627 	IAttribute* att = getAttributeP(attributeName);
628 	if (att)
629 		return att->getTypeString();
630 	else
631 		return L"unknown";
632 }
633 
634 //! Returns attribute type string by index.
635 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeTypeString(s32 index)636 const wchar_t* CAttributes::getAttributeTypeString(s32 index)
637 {
638 	if ((u32)index >= Attributes.size())
639 		return L"unknown";
640 
641 	return Attributes[index]->getTypeString();
642 }
643 
644 //! Gets an attribute as boolean value
645 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsBool(s32 index)646 bool CAttributes::getAttributeAsBool(s32 index)
647 {
648 	bool ret = false;
649 
650 	if ((u32)index < Attributes.size())
651 		ret = Attributes[index]->getBool();
652 
653 	_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
654 	return ret;
655 }
656 
657 //! Gets an attribute as integer value
658 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsInt(s32 index) const659 s32 CAttributes::getAttributeAsInt(s32 index) const
660 {
661 	if ((u32)index < Attributes.size())
662 		return Attributes[index]->getInt();
663 	else
664 		return 0;
665 }
666 
667 //! Gets an attribute as float value
668 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsFloat(s32 index)669 f32 CAttributes::getAttributeAsFloat(s32 index)
670 {
671 	if ((u32)index < Attributes.size())
672 		return Attributes[index]->getFloat();
673 	else
674 		return 0.f;
675 }
676 
677 //! Gets an attribute as color
678 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsColor(s32 index)679 video::SColor CAttributes::getAttributeAsColor(s32 index)
680 {
681 	video::SColor ret(0);
682 
683 	if ((u32)index < Attributes.size())
684 		ret = Attributes[index]->getColor();
685 
686 	return ret;
687 }
688 
689 //! Gets an attribute as floating point color
690 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsColorf(s32 index)691 video::SColorf CAttributes::getAttributeAsColorf(s32 index)
692 {
693 	if ((u32)index < Attributes.size())
694 		return Attributes[index]->getColorf();
695 
696 	return video::SColorf();
697 }
698 
699 //! Gets an attribute as 3d vector
700 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsVector3d(s32 index)701 core::vector3df CAttributes::getAttributeAsVector3d(s32 index)
702 {
703 	if ((u32)index < Attributes.size())
704 		return Attributes[index]->getVector();
705 	else
706 		return core::vector3df();
707 }
708 
709 //! Gets an attribute as 2d vector
getAttributeAsVector2d(s32 index)710 core::vector2df CAttributes::getAttributeAsVector2d(s32 index)
711 {
712 	if ((u32)index < Attributes.size())
713 		return Attributes[index]->getVector2d();
714 	else
715 		return core::vector2df();
716 }
717 
718 //! Gets an attribute as position2d
719 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsPosition2d(s32 index)720 core::position2di CAttributes::getAttributeAsPosition2d(s32 index)
721 {
722 	if ((u32)index < Attributes.size())
723 		return Attributes[index]->getPosition();
724 	else
725 		return core::position2di();
726 }
727 
728 //! Gets an attribute as rectangle
729 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsRect(s32 index)730 core::rect<s32>  CAttributes::getAttributeAsRect(s32 index)
731 {
732 	if ((u32)index < Attributes.size())
733 		return Attributes[index]->getRect();
734 	else
735 		return core::rect<s32>();
736 }
737 
738 //! Gets an attribute as dimension2d
739 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsDimension2d(s32 index)740 core::dimension2d<u32>  CAttributes::getAttributeAsDimension2d(s32 index)
741 {
742 	if ((u32)index < Attributes.size())
743 		return Attributes[index]->getDimension2d();
744 	else
745 		return core::dimension2d<u32>();
746 }
747 
748 
749 //! Gets an attribute as binary data
750 ///! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsBinaryData(s32 index,void * outData,s32 maxSizeInBytes)751 void CAttributes::getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes)
752 {
753 	if ((u32)index < Attributes.size())
754 		Attributes[index]->getBinary(outData, maxSizeInBytes);
755 }
756 
757 
758 //! Gets an attribute as enumeration
759 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsEnumeration(s32 index)760 const char* CAttributes::getAttributeAsEnumeration(s32 index)
761 {
762 	if ((u32)index < Attributes.size())
763 		return Attributes[index]->getEnum();
764 	else
765 		return 0;
766 }
767 
768 
769 //! Gets an attribute as enumeration
770 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsEnumeration(s32 index,const char * const * enumerationLiteralsToUse)771 s32 CAttributes::getAttributeAsEnumeration(s32 index, const char* const* enumerationLiteralsToUse)
772 {
773 	if ((u32)index < Attributes.size())
774 	{
775 		IAttribute* att = Attributes[index];
776 
777 		if (enumerationLiteralsToUse && att)
778 		{
779 			const char* value = att->getEnum();
780 			if (value)
781 			{
782 				for (s32 i=0; enumerationLiteralsToUse[i]; ++i)
783 					if (!strcmp(value, enumerationLiteralsToUse[i]))
784 						return i;
785 			}
786 		}
787 	}
788 
789 	return -1;
790 }
791 
792 //! Gets the list of enumeration literals of an enumeration attribute
793 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeEnumerationLiteralsOfEnumeration(s32 index,core::array<core::stringc> & outLiterals)794 void CAttributes::getAttributeEnumerationLiteralsOfEnumeration(s32 index, core::array<core::stringc>& outLiterals)
795 {
796 	if ((u32)index < Attributes.size() &&
797 			Attributes[index]->getType() == EAT_ENUM)
798 		outLiterals = ((CEnumAttribute*)Attributes[index])->EnumLiterals;
799 }
800 
801 
802 //! Adds an attribute as integer
addInt(const c8 * attributeName,s32 value)803 void CAttributes::addInt(const c8* attributeName, s32 value)
804 {
805 	Attributes.push_back(new CIntAttribute(attributeName, value));
806 }
807 
808 //! Adds an attribute as float
addFloat(const c8 * attributeName,f32 value)809 void CAttributes::addFloat(const c8* attributeName, f32 value)
810 {
811 	Attributes.push_back(new CFloatAttribute(attributeName, value));
812 }
813 
814 //! Adds an attribute as string
addString(const c8 * attributeName,const char * value)815 void CAttributes::addString(const c8* attributeName, const char* value)
816 {
817 	Attributes.push_back(new CStringAttribute(attributeName, value));
818 }
819 
820 //! Adds an attribute as wchar string
addString(const c8 * attributeName,const wchar_t * value)821 void CAttributes::addString(const c8* attributeName, const wchar_t* value)
822 {
823 	Attributes.push_back(new CStringAttribute(attributeName, value));
824 }
825 
826 //! Adds an attribute as bool
addBool(const c8 * attributeName,bool value)827 void CAttributes::addBool(const c8* attributeName, bool value)
828 {
829 	Attributes.push_back(new CBoolAttribute(attributeName, value));
830 }
831 
832 //! Adds an attribute as enum
addEnum(const c8 * attributeName,const char * enumValue,const char * const * enumerationLiterals)833 void CAttributes::addEnum(const c8* attributeName, const char* enumValue, const char* const* enumerationLiterals)
834 {
835 	Attributes.push_back(new CEnumAttribute(attributeName, enumValue, enumerationLiterals));
836 }
837 
838 //! Adds an attribute as enum
addEnum(const c8 * attributeName,s32 enumValue,const char * const * enumerationLiterals)839 void CAttributes::addEnum(const c8* attributeName, s32 enumValue, const char* const* enumerationLiterals)
840 {
841 	addEnum(attributeName, "", enumerationLiterals);
842 	Attributes.getLast()->setInt(enumValue);
843 }
844 
845 //! Adds an attribute as color
addColor(const c8 * attributeName,video::SColor value)846 void CAttributes::addColor(const c8* attributeName, video::SColor value)
847 {
848 	Attributes.push_back(new CColorAttribute(attributeName, value));
849 }
850 
851 //! Adds an attribute as floating point color
addColorf(const c8 * attributeName,video::SColorf value)852 void CAttributes::addColorf(const c8* attributeName, video::SColorf value)
853 {
854 	Attributes.push_back(new CColorfAttribute(attributeName, value));
855 }
856 
857 //! Adds an attribute as 3d vector
addVector3d(const c8 * attributeName,core::vector3df value)858 void CAttributes::addVector3d(const c8* attributeName, core::vector3df value)
859 {
860 	Attributes.push_back(new CVector3DAttribute(attributeName, value));
861 }
862 
863 //! Adds an attribute as 2d vector
addVector2d(const c8 * attributeName,core::vector2df value)864 void CAttributes::addVector2d(const c8* attributeName, core::vector2df value)
865 {
866 	Attributes.push_back(new CVector2DAttribute(attributeName, value));
867 }
868 
869 
870 //! Adds an attribute as 2d position
addPosition2d(const c8 * attributeName,core::position2di value)871 void CAttributes::addPosition2d(const c8* attributeName, core::position2di value)
872 {
873 	Attributes.push_back(new CPosition2DAttribute(attributeName, value));
874 }
875 
876 //! Adds an attribute as rectangle
addRect(const c8 * attributeName,core::rect<s32> value)877 void CAttributes::addRect(const c8* attributeName, core::rect<s32> value)
878 {
879 	Attributes.push_back(new CRectAttribute(attributeName, value));
880 }
881 
882 //! Adds an attribute as dimension2d
addDimension2d(const c8 * attributeName,core::dimension2d<u32> value)883 void CAttributes::addDimension2d(const c8* attributeName, core::dimension2d<u32> value)
884 {
885 	Attributes.push_back(new CDimension2dAttribute(attributeName, value));
886 }
887 
888 //! Adds an attribute as binary data
addBinary(const c8 * attributeName,void * data,s32 dataSizeInBytes)889 void CAttributes::addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes)
890 {
891 	Attributes.push_back(new CBinaryAttribute(attributeName, data, dataSizeInBytes));
892 }
893 
894 //! Adds an attribute as texture reference
addTexture(const c8 * attributeName,video::ITexture * texture,const io::path & filename)895 void CAttributes::addTexture(const c8* attributeName, video::ITexture* texture, const io::path& filename)
896 {
897 	Attributes.push_back(new CTextureAttribute(attributeName, texture, Driver, filename));
898 }
899 
900 //! Returns if an attribute with a name exists
existsAttribute(const c8 * attributeName)901 bool CAttributes::existsAttribute(const c8* attributeName)
902 {
903 	return getAttributeP(attributeName) != 0;
904 }
905 
906 //! Sets an attribute value as string.
907 //! \param attributeName: Name for the attribute
setAttribute(s32 index,const c8 * value)908 void CAttributes::setAttribute(s32 index, const c8* value)
909 {
910 	if ((u32)index < Attributes.size())
911 		Attributes[index]->setString(value);
912 }
913 
914 //! Sets an attribute value as string.
915 //! \param attributeName: Name for the attribute
setAttribute(s32 index,const wchar_t * value)916 void CAttributes::setAttribute(s32 index, const wchar_t* value)
917 {
918 	if ((u32)index < Attributes.size())
919 		Attributes[index]->setString(value);
920 }
921 
922 //! Sets an attribute as boolean value
setAttribute(s32 index,bool value)923 void CAttributes::setAttribute(s32 index, bool value)
924 {
925 	if ((u32)index < Attributes.size())
926 		Attributes[index]->setBool(value);
927 }
928 
929 //! Sets an attribute as integer value
setAttribute(s32 index,s32 value)930 void CAttributes::setAttribute(s32 index, s32 value)
931 {
932 	if ((u32)index < Attributes.size())
933 		Attributes[index]->setInt(value);
934 }
935 
936 //! Sets a attribute as float value
setAttribute(s32 index,f32 value)937 void CAttributes::setAttribute(s32 index, f32 value)
938 {
939 	if ((u32)index < Attributes.size())
940 		Attributes[index]->setFloat(value);
941 }
942 
943 //! Sets a attribute as color
setAttribute(s32 index,video::SColor color)944 void CAttributes::setAttribute(s32 index, video::SColor color)
945 {
946 	if ((u32)index < Attributes.size())
947 		Attributes[index]->setColor(color);
948 }
949 
950 //! Sets a attribute as floating point color
setAttribute(s32 index,video::SColorf color)951 void CAttributes::setAttribute(s32 index, video::SColorf color)
952 {
953 	if ((u32)index < Attributes.size())
954 		Attributes[index]->setColor(color);
955 }
956 
957 //! Sets a attribute as vector
setAttribute(s32 index,core::vector3df v)958 void CAttributes::setAttribute(s32 index, core::vector3df v)
959 {
960 	if ((u32)index < Attributes.size())
961 		Attributes[index]->setVector(v);
962 }
963 
964 //! Sets a attribute as vector
setAttribute(s32 index,core::vector2df v)965 void CAttributes::setAttribute(s32 index, core::vector2df v)
966 {
967 	if ((u32)index < Attributes.size())
968 		Attributes[index]->setVector2d(v);
969 }
970 
971 //! Sets a attribute as position
setAttribute(s32 index,core::position2di v)972 void CAttributes::setAttribute(s32 index, core::position2di v)
973 {
974 	if ((u32)index < Attributes.size())
975 		Attributes[index]->setPosition(v);
976 }
977 
978 //! Sets a attribute as rectangle
setAttribute(s32 index,core::rect<s32> v)979 void CAttributes::setAttribute(s32 index, core::rect<s32> v)
980 {
981 	if ((u32)index < Attributes.size())
982 		Attributes[index]->setRect(v);
983 }
984 
985 //! Sets a attribute as dimension2d
setAttribute(s32 index,core::dimension2d<u32> v)986 void CAttributes::setAttribute(s32 index, core::dimension2d<u32> v)
987 {
988 	if ((u32)index < Attributes.size())
989 		Attributes[index]->setDimension2d(v);
990 }
991 
992 //! Sets an attribute as binary data
setAttribute(s32 index,void * data,s32 dataSizeInBytes)993 void CAttributes::setAttribute(s32 index, void* data, s32 dataSizeInBytes )
994 {
995 	if ((u32)index < Attributes.size())
996 		Attributes[index]->setBinary(data, dataSizeInBytes);
997 }
998 
999 
1000 //! Sets an attribute as enumeration
setAttribute(s32 index,const char * enumValue,const char * const * enumerationLiterals)1001 void CAttributes::setAttribute(s32 index, const char* enumValue, const char* const* enumerationLiterals)
1002 {
1003 	if ((u32)index < Attributes.size())
1004 		Attributes[index]->setEnum(enumValue, enumerationLiterals);
1005 }
1006 
1007 
1008 //! Sets an attribute as texture reference
setAttribute(s32 index,video::ITexture * texture,const io::path & filename)1009 void CAttributes::setAttribute(s32 index, video::ITexture* texture, const io::path& filename)
1010 {
1011 	if ((u32)index < Attributes.size())
1012 		Attributes[index]->setTexture(texture, filename);
1013 }
1014 
1015 
1016 //! Adds an attribute as matrix
addMatrix(const c8 * attributeName,const core::matrix4 & v)1017 void CAttributes::addMatrix(const c8* attributeName, const core::matrix4& v)
1018 {
1019 	Attributes.push_back(new CMatrixAttribute(attributeName, v));
1020 }
1021 
1022 
1023 //! Sets an attribute as matrix
setAttribute(const c8 * attributeName,const core::matrix4 & v)1024 void CAttributes::setAttribute(const c8* attributeName, const core::matrix4& v)
1025 {
1026 	IAttribute* att = getAttributeP(attributeName);
1027 	if (att)
1028 		att->setMatrix(v);
1029 	else
1030 		Attributes.push_back(new CMatrixAttribute(attributeName, v));
1031 }
1032 
1033 //! Gets an attribute as a matrix4
getAttributeAsMatrix(const c8 * attributeName)1034 core::matrix4 CAttributes::getAttributeAsMatrix(const c8* attributeName)
1035 {
1036 	IAttribute* att = getAttributeP(attributeName);
1037 	if (att)
1038 		return att->getMatrix();
1039 	else
1040 		return core::matrix4();
1041 
1042 }
1043 
1044 //! Gets an attribute as matrix
getAttributeAsMatrix(s32 index)1045 core::matrix4 CAttributes::getAttributeAsMatrix(s32 index)
1046 {
1047 	if ((u32)index < Attributes.size())
1048 		return Attributes[index]->getMatrix();
1049 	else
1050 		return core::matrix4();
1051 }
1052 
1053 //! Sets an attribute as matrix
setAttribute(s32 index,const core::matrix4 & v)1054 void CAttributes::setAttribute(s32 index, const core::matrix4& v)
1055 {
1056 	if ((u32)index < Attributes.size())
1057 		Attributes[index]->setMatrix(v);
1058 }
1059 
1060 
1061 //! Adds an attribute as quaternion
addQuaternion(const c8 * attributeName,core::quaternion v)1062 void CAttributes::addQuaternion(const c8* attributeName, core::quaternion v)
1063 {
1064 	Attributes.push_back(new CQuaternionAttribute(attributeName, v));
1065 }
1066 
1067 
1068 //! Sets an attribute as quaternion
setAttribute(const c8 * attributeName,core::quaternion v)1069 void CAttributes::setAttribute(const c8* attributeName, core::quaternion v)
1070 {
1071 	IAttribute* att = getAttributeP(attributeName);
1072 	if (att)
1073 		att->setQuaternion(v);
1074 	else
1075 	{
1076 		Attributes.push_back(new CQuaternionAttribute(attributeName, v));
1077 	}
1078 }
1079 
1080 //! Gets an attribute as a quaternion
getAttributeAsQuaternion(const c8 * attributeName)1081 core::quaternion CAttributes::getAttributeAsQuaternion(const c8* attributeName)
1082 {
1083 	core::quaternion ret(0,1,0, 0);
1084 
1085 	IAttribute* att = getAttributeP(attributeName);
1086 	if (att)
1087 		ret = att->getQuaternion();
1088 
1089 	return ret;
1090 }
1091 
1092 //! Gets an attribute as quaternion
getAttributeAsQuaternion(s32 index)1093 core::quaternion CAttributes::getAttributeAsQuaternion(s32 index)
1094 {
1095 	core::quaternion ret(0,1,0, 0);
1096 
1097 	if (index >= 0 && index < (s32)Attributes.size())
1098 		ret = Attributes[index]->getQuaternion();
1099 
1100 	return ret;
1101 }
1102 
1103 //! Sets an attribute as quaternion
setAttribute(s32 index,core::quaternion v)1104 void CAttributes::setAttribute(s32 index, core::quaternion v)
1105 {
1106 if (index >= 0 && index < (s32)Attributes.size() )
1107 		Attributes[index]->setQuaternion(v);
1108 }
1109 
1110 //! Adds an attribute as axis aligned bounding box
addBox3d(const c8 * attributeName,core::aabbox3df v)1111 void CAttributes::addBox3d(const c8* attributeName, core::aabbox3df v)
1112 {
1113 	Attributes.push_back(new CBBoxAttribute(attributeName, v));
1114 }
1115 
1116 //! Sets an attribute as axis aligned bounding box
setAttribute(const c8 * attributeName,core::aabbox3df v)1117 void CAttributes::setAttribute(const c8* attributeName, core::aabbox3df v)
1118 {
1119 	IAttribute* att = getAttributeP(attributeName);
1120 	if (att)
1121 		att->setBBox(v);
1122 	else
1123 	{
1124 		Attributes.push_back(new CBBoxAttribute(attributeName, v));
1125 	}
1126 }
1127 
1128 //! Gets an attribute as a axis aligned bounding box
getAttributeAsBox3d(const c8 * attributeName)1129 core::aabbox3df CAttributes::getAttributeAsBox3d(const c8* attributeName)
1130 {
1131 	core::aabbox3df ret(0,0,0, 0,0,0);
1132 
1133 	IAttribute* att = getAttributeP(attributeName);
1134 	if (att)
1135 		ret = att->getBBox();
1136 
1137 	return ret;
1138 }
1139 
1140 //! Gets an attribute as axis aligned bounding box
getAttributeAsBox3d(s32 index)1141 core::aabbox3df CAttributes::getAttributeAsBox3d(s32 index)
1142 {
1143 	core::aabbox3df ret(0,0,0, 0,0,0);
1144 
1145 	if (index >= 0 && index < (s32)Attributes.size())
1146 		ret = Attributes[index]->getBBox();
1147 
1148 	return ret;
1149 }
1150 
1151 //! Sets an attribute as axis aligned bounding box
setAttribute(s32 index,core::aabbox3df v)1152 void CAttributes::setAttribute(s32 index, core::aabbox3df v)
1153 {
1154 if (index >= 0 && index < (s32)Attributes.size() )
1155 		Attributes[index]->setBBox(v);
1156 }
1157 
1158 //! Adds an attribute as 3d plane
addPlane3d(const c8 * attributeName,core::plane3df v)1159 void CAttributes::addPlane3d(const c8* attributeName, core::plane3df v)
1160 {
1161 	Attributes.push_back(new CPlaneAttribute(attributeName, v));
1162 }
1163 
1164 //! Sets an attribute as 3d plane
setAttribute(const c8 * attributeName,core::plane3df v)1165 void CAttributes::setAttribute(const c8* attributeName, core::plane3df v)
1166 {
1167 	IAttribute* att = getAttributeP(attributeName);
1168 	if (att)
1169 		att->setPlane(v);
1170 	else
1171 	{
1172 		Attributes.push_back(new CPlaneAttribute(attributeName, v));
1173 	}
1174 }
1175 
1176 //! Gets an attribute as a 3d plane
getAttributeAsPlane3d(const c8 * attributeName)1177 core::plane3df CAttributes::getAttributeAsPlane3d(const c8* attributeName)
1178 {
1179 	core::plane3df ret(0,0,0, 0,1,0);
1180 
1181 	IAttribute* att = getAttributeP(attributeName);
1182 	if (att)
1183 		ret = att->getPlane();
1184 
1185 	return ret;
1186 }
1187 
1188 //! Gets an attribute as 3d plane
getAttributeAsPlane3d(s32 index)1189 core::plane3df CAttributes::getAttributeAsPlane3d(s32 index)
1190 {
1191 	core::plane3df ret(0,0,0, 0,1,0);
1192 
1193 	if (index >= 0 && index < (s32)Attributes.size())
1194 		ret = Attributes[index]->getPlane();
1195 
1196 	return ret;
1197 }
1198 
1199 //! Sets an attribute as 3d plane
setAttribute(s32 index,core::plane3df v)1200 void CAttributes::setAttribute(s32 index, core::plane3df v)
1201 {
1202 	if (index >= 0 && index < (s32)Attributes.size() )
1203 		Attributes[index]->setPlane(v);
1204 }
1205 
1206 //! Adds an attribute as 3d triangle
addTriangle3d(const c8 * attributeName,core::triangle3df v)1207 void CAttributes::addTriangle3d(const c8* attributeName, core::triangle3df v)
1208 {
1209 	Attributes.push_back(new CTriangleAttribute(attributeName, v));
1210 }
1211 
1212 //! Sets an attribute as 3d triangle
setAttribute(const c8 * attributeName,core::triangle3df v)1213 void CAttributes::setAttribute(const c8* attributeName, core::triangle3df v)
1214 {
1215 	IAttribute* att = getAttributeP(attributeName);
1216 	if (att)
1217 		att->setTriangle(v);
1218 	else
1219 	{
1220 		Attributes.push_back(new CTriangleAttribute(attributeName, v));
1221 	}
1222 }
1223 
1224 //! Gets an attribute as a 3d triangle
getAttributeAsTriangle3d(const c8 * attributeName)1225 core::triangle3df CAttributes::getAttributeAsTriangle3d(const c8* attributeName)
1226 {
1227 	core::triangle3df ret;
1228 	ret.pointA = ret.pointB = ret.pointC = core::vector3df(0,0,0);
1229 
1230 	IAttribute* att = getAttributeP(attributeName);
1231 	if (att)
1232 		ret = att->getTriangle();
1233 
1234 	return ret;
1235 }
1236 
1237 //! Gets an attribute as 3d triangle
getAttributeAsTriangle3d(s32 index)1238 core::triangle3df CAttributes::getAttributeAsTriangle3d(s32 index)
1239 {
1240 	core::triangle3df ret;
1241 	ret.pointA = ret.pointB = ret.pointC = core::vector3df(0,0,0);
1242 
1243 	if (index >= 0 && index < (s32)Attributes.size())
1244 		ret = Attributes[index]->getTriangle();
1245 
1246 	return ret;
1247 }
1248 
1249 //! Sets an attribute as 3d triangle
setAttribute(s32 index,core::triangle3df v)1250 void CAttributes::setAttribute(s32 index, core::triangle3df v)
1251 {
1252 	if (index >= 0 && index < (s32)Attributes.size() )
1253 		Attributes[index]->setTriangle(v);
1254 }
1255 
1256 //! Adds an attribute as a 2d line
addLine2d(const c8 * attributeName,core::line2df v)1257 void CAttributes::addLine2d(const c8* attributeName, core::line2df v)
1258 {
1259 	Attributes.push_back(new CLine2dAttribute(attributeName, v));
1260 }
1261 
1262 //! Sets an attribute as a 2d line
setAttribute(const c8 * attributeName,core::line2df v)1263 void CAttributes::setAttribute(const c8* attributeName, core::line2df v)
1264 {
1265 	IAttribute* att = getAttributeP(attributeName);
1266 	if (att)
1267 		att->setLine2d(v);
1268 	else
1269 	{
1270 		Attributes.push_back(new CLine2dAttribute(attributeName, v));
1271 	}
1272 }
1273 
1274 //! Gets an attribute as a 2d line
getAttributeAsLine2d(const c8 * attributeName)1275 core::line2df CAttributes::getAttributeAsLine2d(const c8* attributeName)
1276 {
1277 	core::line2df ret(0,0, 0,0);
1278 
1279 	IAttribute* att = getAttributeP(attributeName);
1280 	if (att)
1281 		ret = att->getLine2d();
1282 
1283 	return ret;
1284 }
1285 
1286 //! Gets an attribute as a 2d line
getAttributeAsLine2d(s32 index)1287 core::line2df CAttributes::getAttributeAsLine2d(s32 index)
1288 {
1289 	core::line2df ret(0,0, 0,0);
1290 
1291 	if (index >= 0 && index < (s32)Attributes.size())
1292 		ret = Attributes[index]->getLine2d();
1293 
1294 	return ret;
1295 }
1296 
1297 //! Sets an attribute as a 2d line
setAttribute(s32 index,core::line2df v)1298 void CAttributes::setAttribute(s32 index, core::line2df v)
1299 {
1300 	if (index >= 0 && index < (s32)Attributes.size() )
1301 		Attributes[index]->setLine2d(v);
1302 }
1303 
1304 //! Adds an attribute as a 3d line
addLine3d(const c8 * attributeName,core::line3df v)1305 void CAttributes::addLine3d(const c8* attributeName, core::line3df v)
1306 {
1307 	Attributes.push_back(new CLine3dAttribute(attributeName, v));
1308 }
1309 
1310 //! Sets an attribute as a 3d line
setAttribute(const c8 * attributeName,core::line3df v)1311 void CAttributes::setAttribute(const c8* attributeName, core::line3df v)
1312 {
1313 	IAttribute* att = getAttributeP(attributeName);
1314 	if (att)
1315 		att->setLine3d(v);
1316 	else
1317 	{
1318 		Attributes.push_back(new CLine3dAttribute(attributeName, v));
1319 	}
1320 }
1321 
1322 //! Gets an attribute as a 3d line
getAttributeAsLine3d(const c8 * attributeName)1323 core::line3df CAttributes::getAttributeAsLine3d(const c8* attributeName)
1324 {
1325 	core::line3df ret(0,0,0, 0,0,0);
1326 
1327 	IAttribute* att = getAttributeP(attributeName);
1328 	if (att)
1329 		ret = att->getLine3d();
1330 
1331 	return ret;
1332 }
1333 
1334 //! Gets an attribute as a 3d line
getAttributeAsLine3d(s32 index)1335 core::line3df CAttributes::getAttributeAsLine3d(s32 index)
1336 {
1337 	core::line3df ret(0,0,0, 0,0,0);
1338 
1339 	if (index >= 0 && index < (s32)Attributes.size())
1340 		ret = Attributes[index]->getLine3d();
1341 
1342 	return ret;
1343 }
1344 
1345 //! Sets an attribute as a 3d line
setAttribute(s32 index,core::line3df v)1346 void CAttributes::setAttribute(s32 index, core::line3df v)
1347 {
1348 	if (index >= 0 && index < (s32)Attributes.size() )
1349 		Attributes[index]->setLine3d(v);
1350 
1351 }
1352 
1353 
1354 //! Adds an attribute as user pointner
addUserPointer(const c8 * attributeName,void * userPointer)1355 void CAttributes::addUserPointer(const c8* attributeName, void* userPointer)
1356 {
1357 	Attributes.push_back(new CUserPointerAttribute(attributeName, userPointer));
1358 }
1359 
1360 //! Sets an attribute as user pointer
setAttribute(const c8 * attributeName,void * userPointer)1361 void CAttributes::setAttribute(const c8* attributeName, void* userPointer)
1362 {
1363 	IAttribute* att = getAttributeP(attributeName);
1364 	if (att)
1365 		att->setUserPointer(userPointer);
1366 	else
1367 	{
1368 		Attributes.push_back(new CUserPointerAttribute(attributeName, userPointer));
1369 	}
1370 }
1371 
1372 //! Gets an attribute as user pointer
1373 //! \param attributeName: Name of the attribute to get.
getAttributeAsUserPointer(const c8 * attributeName)1374 void* CAttributes::getAttributeAsUserPointer(const c8* attributeName)
1375 {
1376 	void* value = 0;
1377 
1378 	IAttribute* att = getAttributeP(attributeName);
1379 	if (att)
1380 		value = att->getUserPointer();
1381 
1382 	return value;
1383 }
1384 
1385 //! Gets an attribute as user pointer
1386 //! \param index: Index value, must be between 0 and getAttributeCount()-1.
getAttributeAsUserPointer(s32 index)1387 void* CAttributes::getAttributeAsUserPointer(s32 index)
1388 {
1389 	void* value = 0;
1390 
1391 	if (index >= 0 && index < (s32)Attributes.size())
1392         value = Attributes[index]->getUserPointer();
1393 
1394 	return value;
1395 }
1396 
1397 //! Sets an attribute as user pointer
setAttribute(s32 index,void * userPointer)1398 void CAttributes::setAttribute(s32 index, void* userPointer)
1399 {
1400 	if (index >= 0 && index < (s32)Attributes.size() )
1401 		Attributes[index]->setUserPointer(userPointer);
1402 }
1403 
1404 
1405 //! Reads attributes from a xml file.
1406 //! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'.
1407 //! IF set to false, the first appearing list attributes are read.
read(io::IXMLReader * reader,bool readCurrentElementOnly,const wchar_t * nonDefaultElementName)1408 bool CAttributes::read(io::IXMLReader* reader, bool readCurrentElementOnly,
1409 					    const wchar_t* nonDefaultElementName)
1410 {
1411 	if (!reader)
1412 		return false;
1413 
1414 	clear();
1415 
1416 	core::stringw elementName = L"attributes";
1417 	if (nonDefaultElementName)
1418 		elementName = nonDefaultElementName;
1419 
1420 	if (readCurrentElementOnly)
1421 	{
1422 		if (elementName != reader->getNodeName())
1423 			return false;
1424 	}
1425 
1426 	while(reader->read())
1427 	{
1428 		switch(reader->getNodeType())
1429 		{
1430 		case io::EXN_ELEMENT:
1431 			readAttributeFromXML(reader);
1432 			break;
1433 		case io::EXN_ELEMENT_END:
1434 			if (elementName == reader->getNodeName())
1435 				return true;
1436 			break;
1437 		default:
1438 			break;
1439 		}
1440 	}
1441 
1442 	return true;
1443 }
1444 
1445 
readAttributeFromXML(io::IXMLReader * reader)1446 void CAttributes::readAttributeFromXML(io::IXMLReader* reader)
1447 {
1448 	core::stringw element = reader->getNodeName();
1449 	core::stringc name = reader->getAttributeValue(L"name");
1450 
1451 	if (element == L"enum")
1452 	{
1453 		addEnum(name.c_str(), 0, 0);
1454 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1455 	}
1456 	else
1457 	if (element == L"binary")
1458 	{
1459 		addBinary(name.c_str(), 0, 0);
1460 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1461 	}
1462 	else
1463 	if (element == L"color")
1464 	{
1465 		addColor(name.c_str(), video::SColor());
1466 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1467 	}
1468 	else
1469 	if (element == L"colorf")
1470 	{
1471 		addColorf(name.c_str(), video::SColorf());
1472 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1473 	}
1474 	else
1475 	if (element == L"float")
1476 	{
1477 		addFloat(name.c_str(), 0);
1478 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1479 	}
1480 	else
1481 	if (element == L"int")
1482 	{
1483 		addInt(name.c_str(), 0);
1484 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1485 	}
1486 	else
1487 	if (element == L"bool")
1488 	{
1489 		addBool(name.c_str(), 0);
1490 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1491 	}
1492 	else
1493 	if (element == L"string")
1494 	{
1495 		addString(name.c_str(), L"");
1496 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1497 	}
1498 	else
1499 	if (element == L"texture")
1500 	{
1501 		addTexture(name.c_str(), 0);
1502 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1503 	}
1504 	else
1505 	if (element == L"vector3d")
1506 	{
1507 		addVector3d(name.c_str(), core::vector3df());
1508 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1509 	}
1510 	else
1511 	if (element == L"vector2d")
1512 	{
1513 		addVector2d(name.c_str(), core::vector2df());
1514 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1515 	}
1516 	else
1517 	if (element == L"position")
1518 	{
1519 		addPosition2d(name.c_str(), core::position2di());
1520 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1521 	}
1522 	else
1523 	if (element == L"rect")
1524 	{
1525 		addRect(name.c_str(), core::rect<s32>());
1526 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1527 	}
1528 	else
1529 	if (element == L"matrix")
1530 	{
1531 		addMatrix(name.c_str(), core::matrix4());
1532 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1533 	}
1534 	else
1535 	if (element == L"quaternion")
1536 	{
1537 		addQuaternion(name.c_str(), core::quaternion());
1538 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1539 	}
1540 	else
1541 	if (element == L"box3d")
1542 	{
1543 		addBox3d(name.c_str(), core::aabbox3df());
1544 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1545 	}
1546 	else
1547 	if (element == L"plane")
1548 	{
1549 		addPlane3d(name.c_str(), core::plane3df());
1550 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1551 	}
1552 	else
1553 	if (element == L"triangle")
1554 	{
1555 		addTriangle3d(name.c_str(), core::triangle3df());
1556 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1557 	}
1558 	else
1559 	if (element == L"line2d")
1560 	{
1561 		addLine2d(name.c_str(), core::line2df());
1562 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1563 	}
1564 	else
1565 	if (element == L"line3d")
1566 	{
1567 		addLine3d(name.c_str(), core::line3df());
1568 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1569 	}
1570 	else
1571 	if (element == L"stringwarray")
1572 	{
1573 		core::array<core::stringw> tmpArray;
1574 
1575 		s32 count = reader->getAttributeValueAsInt(L"count");
1576 		s32 n=0;
1577 		const core::stringw tmpName(L"value");
1578 		for (; n<count; ++n)
1579 		{
1580 			tmpArray.push_back(reader->getAttributeValue((tmpName+core::stringw(n)).c_str()));
1581 		}
1582 		addArray(name.c_str(),tmpArray);
1583 	}
1584 	else
1585 	if (element == L"userPointer")
1586 	{
1587 		// It's debatable if a pointer should be set or not, but it's more likely that adding it now would wreck user-applications.
1588 		// Also it probably doesn't makes sense setting this to a value when it comes from file.
1589 	}
1590 	else
1591 	if (element == L"dimension2d")
1592 	{
1593 		addDimension2d(name.c_str(), core::dimension2d<u32>());
1594 		Attributes.getLast()->setString(reader->getAttributeValue(L"value"));
1595 	}
1596 }
1597 
1598 //! Write these attributes into a xml file
write(io::IXMLWriter * writer,bool writeXMLHeader,const wchar_t * nonDefaultElementName)1599 bool CAttributes::write(io::IXMLWriter* writer, bool writeXMLHeader,
1600 						const wchar_t* nonDefaultElementName)
1601 {
1602 	if (!writer)
1603 		return false;
1604 
1605 	if (writeXMLHeader)
1606 		writer->writeXMLHeader();
1607 
1608 	core::stringw elementName = L"attributes";
1609 	if (nonDefaultElementName)
1610 		elementName = nonDefaultElementName;
1611 
1612 	writer->writeElement(elementName.c_str(), false);
1613 	writer->writeLineBreak();
1614 
1615 	s32 i=0;
1616 	for (; i<(s32)Attributes.size(); ++i)
1617 	{
1618 		if ( Attributes[i]->getType() == EAT_STRINGWARRAY )
1619 		{
1620 			core::array<core::stringw> arraynames, arrayvalues;
1621 			core::array<core::stringw> arrayinput = Attributes[i]->getArray();
1622 
1623 			// build arrays
1624 
1625 			// name
1626 			arraynames.push_back(core::stringw(L"name"));
1627 			arrayvalues.push_back(core::stringw(Attributes[i]->Name.c_str()) );
1628 
1629 			// count
1630 			arraynames.push_back(core::stringw(L"count"));
1631 			arrayvalues.push_back(core::stringw((s32)arrayinput.size()));
1632 
1633 			// array...
1634 			u32 n=0;
1635 			const core::stringw tmpName(L"value");
1636 			for (; n < arrayinput.size(); ++n)
1637 			{
1638 				arraynames.push_back((tmpName+core::stringw(n)).c_str());
1639 				arrayvalues.push_back(arrayinput[n]);
1640 			}
1641 
1642 			// write them
1643 			writer->writeElement( Attributes[i]->getTypeString(), true, arraynames, arrayvalues);
1644 		}
1645 		else
1646 		{
1647 			writer->writeElement(
1648 				Attributes[i]->getTypeString(), true,
1649 				L"name", core::stringw(Attributes[i]->Name.c_str()).c_str(),
1650 				L"value", Attributes[i]->getStringW().c_str() );
1651 		}
1652 
1653 		writer->writeLineBreak();
1654 	}
1655 
1656 	writer->writeClosingTag(elementName.c_str());
1657 	writer->writeLineBreak();
1658 
1659 	return true;
1660 }
1661 
1662 
1663 } // end namespace io
1664 } // end namespace irr
1665 
1666