1 /*
2 	Copyright (C) 2005-2007 Feeling Software Inc.
3 	Portions of the code are:
4 	Copyright (C) 2005-2007 Sony Computer Entertainment America
5 
6 	MIT License: http://www.opensource.org/licenses/mit-license.php
7 */
8 
9 /**
10 	@file FCDExtra.h
11 	This file contains the FCDExtra class and its sub-classes:
12 	FCDENode, FCDETechnique and FCDEAttribute.
13 */
14 
15 #ifndef _FCD_EXTRA_H_
16 #define _FCD_EXTRA_H_
17 
18 #ifndef __FCD_OBJECT_H_
19 #include "FCDocument/FCDObject.h"
20 #endif // __FCD_OBJECT_H_
21 #ifndef _FU_PARAMETER_H_
22 #include "FUtils/FUParameter.h"
23 #endif // _FU_PARAMETER_H_
24 
25 class FCDAnimated;
26 class FCDAnimatedCustom;
27 class FCDEAttribute;
28 class FCDETechnique;
29 class FCDEType;
30 class FCDENode;
31 
32 typedef fm::pvector<FCDENode> FCDENodeList; /**< A dynamically-sized list of extra tree nodes. */
33 
34 /**
35 	A COLLADA extra tree.
36 
37 	An extra tree contains the user-defined COLLADA information
38 	contained within \<extra\> elements. For this, the extra tree
39 	root simply contains a list of techniques. Each technique
40 	belongs to a different application-specific profile.
41 */
42 class FCOLLADA_EXPORT FCDExtra : public FCDObject
43 {
44 private:
45 	DeclareObjectType(FCDObject);
46 
47 	FUObject* parent;
48 	DeclareParameterContainer(FCDEType, types, FC("Extra Types"));
49 
50 public:
51 	/** Constructor.
52 		Only structures that contain extra trees should create them.
53 		@param document The COLLADA document that owns the extra tree.
54 		@param parent The object that contains this extra tree. This parameter
55 			is used only for plug-in support. */
56 	FCDExtra(FCDocument* document, FUObject* parent);
57 
58 	/** Destructor. */
59 	virtual ~FCDExtra();
60 
61 	/** Retrieves the parent object for the extra tree.
62 		@return The parent object pointer. */
GetParent()63 	inline FUObject* GetParent() { return parent; }
GetParent()64 	inline const FUObject* GetParent() const { return parent; } /**< See above. */
65 
66 	/** Retrieves the list of types contained by this extra tree.
67 		@return The list of types. */
GetTypes()68 	DEPRECATED(3.05A, GetTypeCount and GetType(index)) inline void GetTypes() const {}
69 
70 	/** Retrieves the number of types contained by this extra tree.
71 		@return The number of types. */
GetTypeCount()72 	size_t GetTypeCount() const { return types.size(); }
73 
74 	/** Retrieves the default extra type.
75 		The default extra type has an empty typename and is always created by default.
76 		The default extra type will NOT be exported if it is empty.
77 		@return The default extra type. */
GetDefaultType()78 	inline FCDEType* GetDefaultType() { return const_cast<FCDEType*>(const_cast<const FCDExtra*>(this)->GetDefaultType()); }
GetDefaultType()79 	inline const FCDEType* GetDefaultType() const { return FindType(""); }  /**< See above. */
80 
81 	/** Retrieves a specific type contained by this extra tree.
82 		@param index The index of the type.
83 		@return The type. This pointer will be NULL if the index is out-of-bounds. */
GetType(size_t index)84 	inline FCDEType* GetType(size_t index) { FUAssert(index < types.size(), return NULL); return types.at(index); }
GetType(size_t index)85 	inline const FCDEType* GetType(size_t index) const { FUAssert(index < types.size(), return NULL); return types.at(index); } /**< See above. */
86 
87 	/** Adds a new application-specific type to the extra tree.
88 		If the given application-specific type already exists
89 		within the extra tree, the old type will be returned.
90 		@param name The application-specific name.
91 		@return A type for this application-specific name. */
92 	FCDEType* AddType(const char* name);
AddType(const fm::string & name)93 	inline FCDEType* AddType(const fm::string& name) { return AddType(name.c_str()); } /**< See above. */
94 
95 	/** Retrieves a specific type contained by this extra tree.
96 		@param name The application-specific name of the type.
97 		@return The type that matches the name. This pointer may
98 			be NULL if no type matches the name. */
FindType(const char * name)99 	inline FCDEType* FindType(const char* name) { return const_cast<FCDEType*>(const_cast<const FCDExtra*>(this)->FindType(name)); }
100 	const FCDEType* FindType(const char* name) const; /**< See above. */
FindType(const fm::string & name)101 	inline FCDEType* FindType(const fm::string& name) { return FindType(name.c_str()); } /**< See above. */
FindType(const fm::string & name)102 	inline const FCDEType* FindType(const fm::string& name) const { return FindType(name.c_str()); } /**< See above. */
103 
104 	/** Determines whether this structure is empty or not.
105 		Basically, if there is an extra type, and that this type contains at
106 		least one extra technique, content exists.
107 		@return True if non-empty, false otherwise.*/
108 	bool HasContent() const;
109 
110 	/** [INTERNAL] Clones the extra tree information.
111 		@param clone The extra tree that will take in this extra tree's information.
112 			If this pointer is NULL, a new extra tree will be created and you will
113 			need to release the returned pointer manually.
114 		@return The clone. */
115 	FCDExtra* Clone(FCDExtra* clone = NULL) const;
116 };
117 
118 /**
119 	A COLLADA typed extra node.
120 
121 	The 'type' attribute of the extra nodes allow us to bucket techniques
122 	to allow for different data for the same idea.
123 
124 	Therefore, a typed extra node contains a type name and a list of techniques.
125 */
126 class FCOLLADA_EXPORT FCDEType : public FCDObject
127 {
128 private:
129 	DeclareObjectType(FCDObject);
130 
131 	FCDExtra* parent;
132 	DeclareParameter(fm::string, FUParameterQualifiers::SIMPLE, name, FC("Type name"));
133 	DeclareParameterContainer(FCDETechnique, techniques, FC("Profile-specific Techniques"));
134 
135 public:
136 	/** Constructor: do not use directly.
137 		Use the FCDExtra::AddType function instead.
138 		@param document The COLLADA document that owns the extra tree.
139 		@param parent The parent extra tree structure.
140 		@param type The name of the type for this typed extra. */
141 	FCDEType(FCDocument* document, FCDExtra* parent, const char* type);
142 
143 	/** Destructor. */
144 	virtual ~FCDEType();
145 
146 	/** Retrieves the extra tree that contains this typed extra.
147 		@return The parent extra tree. */
GetParent()148 	inline FCDExtra* GetParent() { return parent; }
GetParent()149 	inline const FCDExtra* GetParent() const { return parent; } /**< See above. */
150 
151 	/** Retrieves the name of the type of the typed extra.
152 		@return The name of the type. */
GetName()153 	inline const fm::string& GetName() const { return name; }
154 
155 	/** Modifies the name of the type of the typed extra.
156 		Be careful when modifying the name of a type. The extra tree
157 		assumes no duplicate type names within its typed extras.
158 		@param _name The new name of the type. */
SetName(const fm::string & _name)159 	inline void SetName(const fm::string& _name) { name = _name; }
160 
161 	/** Retrieves the list of techniques contained by this extra tree.
162 		@return The list of techniques. */
GetTechniques()163 	DEPRECATED(3.05A, GetTechniqueCount and GetTechnique(index)) inline void GetTechniques() const {}
164 
165 	/** Retrieves the number of techniques contained by this extra tree.
166 		@return The number of techniques. */
GetTechniqueCount()167 	inline size_t GetTechniqueCount() const { return techniques.size(); }
168 
169 	/** Retrieves a specific technique contained by this extra tree.
170 		@param index The index of the technique.
171 		@return The technique. This pointer will be NULL if the
172 			index is out-of-bounds. */
GetTechnique(size_t index)173 	inline FCDETechnique* GetTechnique(size_t index) { FUAssert(index < techniques.size(), return NULL); return techniques.at(index); }
GetTechnique(size_t index)174 	inline const FCDETechnique* GetTechnique(size_t index) const { FUAssert(index < techniques.size(), return NULL); return techniques.at(index); } /**< See above. */
175 
176 	/** Adds a new application-specific profile technique to the extra tree.
177 		If the given application-specific profile already exists
178 		within the extra tree, the old technique will be returned.
179 		@param profile The application-specific profile name.
180 		@return A technique for this application-specific profile. */
181 	FCDETechnique* AddTechnique(const char* profile);
AddTechnique(const fm::string & profile)182 	inline FCDETechnique* AddTechnique(const fm::string& profile) { return AddTechnique(profile.c_str()); } /**< See above. */
183 
184 	/** Retrieves a specific technique contained by this extra tree.
185 		@param profile The application-specific profile name of the technique.
186 		@return The technique that matches the profile name. This pointer may
187 			be NULL if no technique matches the profile name. */
FindTechnique(const char * profile)188 	FCDETechnique* FindTechnique(const char* profile) { return const_cast<FCDETechnique*>(const_cast<const FCDEType*>(this)->FindTechnique(profile)); }
189 	const FCDETechnique* FindTechnique(const char* profile) const; /**< See above. */
FindTechnique(const fm::string & profile)190 	inline FCDETechnique* FindTechnique(const fm::string& profile) { return FindTechnique(profile.c_str()); } /**< See above. */
FindTechnique(const fm::string & profile)191 	inline const FCDETechnique* FindTechnique(const fm::string& profile) const { return FindTechnique(profile.c_str()); } /**< See above. */
192 
193 	/** Retrieves the extra tree node that has a given element name.
194 		This function searches for the extra tree node within all the
195 		techniques.
196 		@param name An element name.
197 		@return The extra tree node that matches the element name. This pointer
198 			will be NULL if no extra tree node matches the element name. */
FindRootNode(const char * name)199 	inline FCDENode* FindRootNode(const char* name) { return const_cast<FCDENode*>(const_cast<const FCDEType*>(this)->FindRootNode(name)); }
200 	const FCDENode* FindRootNode(const char* name) const; /**< See above. */
FindRootNode(const fm::string & name)201 	inline FCDENode* FindRootNode(const fm::string& name) { return FindRootNode(name.c_str()); } /**< See above. */
FindRootNode(const fm::string & name)202 	inline const FCDENode* FindRootNode(const fm::string& name) const { return FindRootNode(name.c_str()); } /**< See above. */
203 
204 	/** [INTERNAL] Clones the extra tree information.
205 		@param clone The extra tree that will take in this extra tree's information.
206 			If this pointer is NULL, a new extra tree will be created and you will
207 			need to release the returned pointer manually.
208 		@return The clone. */
209 	FCDEType* Clone(FCDEType* clone = NULL) const;
210 };
211 
212 /**
213 	A COLLADA extra tree node.
214 
215 	The extra tree node is a hierarchical structure that contains child
216 	extra tree nodes as well as attributes. If the extra tree node is a leaf
217 	of the tree, it may contain textual content.
218 
219 	The extra tree node leaf may be animated, if it has the 'sid' attribute.
220 */
221 class FCOLLADA_EXPORT FCDENode : public FCDObject
222 {
223 private:
224 	DeclareObjectType(FCDObject);
225 
226 	FCDENode* parent;
227 	DeclareParameter(fm::string, FUParameterQualifiers::SIMPLE, name, FC("Node name"));
228 	DeclareParameter(fstring, FUParameterQualifiers::SIMPLE, content, FC("Node content"));
229 
230 	DeclareParameterContainer(FCDENode, children, FC("Children"));
231 	DeclareParameterContainer(FCDEAttribute, attributes, FC("Attributes"));
232 
233 	DeclareParameterRef(FCDAnimatedCustom, animated, FC("Custom Animatable"));
234 
235 public:
236 	/** Constructor: do not use directly.
237 		Instead, call the FCDENode::AddChild function of the parent within the hierarchy.
238 		@param document The COLLADA document that owns the extra tree node.
239 		@param parent The extra tree node that contains this extra tree node. */
240 	FCDENode(FCDocument* document, FCDENode* parent);
241 
242 	/** Destructor. */
243 	virtual ~FCDENode();
244 
245 	/** Retrieves the name of the extra tree node.
246 		The name of the extra tree node is the name of the equivalent XML tree node.
247 		@return The name of the extra tree node. */
GetName()248 	inline const char* GetName() const { return name->c_str(); }
249 
250 	/** Sets the name of the extra tree node.
251 		The name of the extra tree node is the name of the equivalent XML tree node.
252 		@param _name The name of the extra tree node. */
SetName(const char * _name)253 	inline void SetName(const char* _name) { fm::string n = _name; SetName(n); }
SetName(const fm::string & _name)254 	inline void SetName(const fm::string& _name) { fm::string n = _name; SetName(n); } /**< See above. */
255 	void SetName(fm::string& _name);
256 
257 	/** Cleans up extra tree node names and extra tree attribute names in order to
258 		always start with an alphabetic character or an underscore, as well as contain
259 		only alphanumeric characters or underscore.
260 		@param n The string to clean. This reference will be updated with the cleaned name. */
261 	static void CleanName(fm::string& n);
262 
263 	/** Retrieves the textual content of the extra tree node.
264 		This value is only valid for extra tree node that have no children,
265 		as COLLADA doesn't allow for mixed-content.
266 		@return The textual content of the extra tree node. */
267 	const fchar* GetContent() const;
268 
269 	/** Sets the textual content of the extra tree node.
270 		This function will release all the child node of this extra tree node,
271 		as COLLADA doesn't allow for mixed-content.
272 		@param _content The textual content. */
273 	void SetContent(const fchar* _content);
SetContent(const fstring & _content)274 	inline void SetContent(const fstring& _content) { return SetContent(_content.c_str()); } /**< See above. */
275 
276 	/** [INTERNAL] Set the content directly.
277 		@param _content The new content to set.
278 	*/
SetContentDirect(const fstring & _content)279 	void SetContentDirect(const fstring& _content) { content = _content; }
280 
281 	/** Retrieves the animated values associated with this extra tree node.
282 		Extra tree node leaves may be animated. If this extra tree node leaf
283 		is animated, this animated value will contain the animation curves.
284 		@return The animated value. */
GetAnimated()285 	FCDAnimatedCustom* GetAnimated() { return animated; }
GetAnimated()286 	const FCDAnimatedCustom* GetAnimated() const { return animated; } /**< See above. */
287 
288 	/**[INTERNAL] Set the customized animated. The old pointer is released first.
289 		@animatedCustom The new animated.
290 	*/
291 	void SetAnimated(FCDAnimatedCustom* animatedCustom);
292 
293 	/** Retrieves the parent of an extra tree node.
294 		The hierarchy cannot be changed dynamically. If you to move an extra tree node,
295 		you will need to clone it manually and release the old extra tree node.
296 		@return The parent extra tree node within the hierarchy. This pointer
297 			will be NULL if the extra tree node is a extra tree technique. */
GetParent()298 	FCDENode* GetParent() { return parent; }
GetParent()299 	const FCDENode* GetParent() const { return parent; } /**< See above. */
300 
301 	/** Retrieves the children of an extra tree node.
302 		@return The list of child extra tree nodes. */
GetChildNodes()303 	DEPRECATED(3.05A, GetChildNodeCount and GetChildNode(index)) void GetChildNodes() const {}
304 
305 	/** Retrieves the number of children of an extra tree node.
306 		@return The number of children. */
GetChildNodeCount()307 	size_t GetChildNodeCount() const { return children.size(); }
308 
309 	/** Retrieves a specific child extra tree node.
310 		@param index The index of the child extra tree node.
311 		@return The child extra tree node. This pointer will be NULL if the index
312 			is out-of-bounds. */
GetChildNode(size_t index)313 	FCDENode* GetChildNode(size_t index) { FUAssert(index < children.size(), return NULL); return children.at(index); }
GetChildNode(size_t index)314 	const FCDENode* GetChildNode(size_t index) const { FUAssert(index < children.size(), return NULL); return children.at(index); } /**< See above. */
315 
316 	/** Adds a new child extra tree to this extra tree node.
317 		@see AddParameter
318 		@return The new child extra tree node. */
319 	FCDENode* AddChildNode();
320 
321 	/** Adds a new, named, child extra tree to this extra tree node.
322 		@see AddParameter
323 		@param name The name of the child node.
324 		@return The new child extra tree node. */
325 	FCDENode* AddChildNode(const char* name);
AddChildNode(const fm::string & name)326 	inline FCDENode* AddChildNode(const fm::string& name) { return AddChildNode(name.c_str()); } /**< See above. */
327 
328 	/** Retrieves the child extra tree node with the given name.
329 		@param name A name.
330 		@return The child extra tree node that matches the given name.
331 			This pointer will be NULL if no child extra tree node matches
332 			the given name. */
FindChildNode(const char * name)333 	inline FCDENode* FindChildNode(const char* name) { return const_cast<FCDENode*>(const_cast<const FCDENode*>(this)->FindChildNode(name)); }
334 	const FCDENode* FindChildNode(const char* name) const; /**< See above. */
FindChildNode(const fm::string & name)335 	inline FCDENode* FindChildNode(const fm::string& name) { return FindChildNode(name.c_str()); } /**< See above. */
FindChildNode(const fm::string & name)336 	inline const FCDENode* FindChildNode(const fm::string& name) const { return FindChildNode(name.c_str()); } /**< See above. */
337 
338 	/** Retrieves the child extra tree nodes with the given name.
339 		@param name A name.
340 		@param nodes A list of nodes to fill in with the nodes
341 			that match a given name. */
342 	void FindChildrenNodes(const char* name, FCDENodeList& nodes) const;
FindChildrenNodes(const fm::string & name,FCDENodeList & nodes)343 	inline void FindChildrenNodes(const fm::string& name, FCDENodeList& nodes) const { FindChildrenNodes(name.c_str(), nodes); } /**< See above. */
344 
345 	/** Retrieves the child extra tree node with the given name.
346 		A parameter has no child nodes and is described as: \<X\>value\</X\>.
347 		The first child extra tree node where the name matches 'X' will be returned.
348 		@param name The parameter name.
349 		@return The first child extra tree node holding the wanted parameter within the hierarchy.
350 			This pointer will be NULL to indicate that no parameter matches the given name. */
351 	const FCDENode* FindParameter(const char* name) const;
FindParameter(const char * name)352 	inline FCDENode* FindParameter(const char* name) { return const_cast<FCDENode*>(const_cast<const FCDENode*>(this)->FindParameter(name)); } /**< See above. */
353 
354 	/** Retrieves a list of all the parameters contained within the hierarchy.
355 		A parameter has no child nodes and is described as: \<X\>value\</X\>.
356 		Using this function, The parameter would be returned with the name 'X'.
357 		@param nodes The list of parameters to fill in. This list is not emptied by the function.
358 		@param names The list of names of the parameters. This list is not emptied by the function. */
359 	void FindParameters(FCDENodeList& nodes, StringList& names);
360 
361 	/** Retrieves the list of attributes for this extra tree node.
362 		@return The list of attributes. */
GetAttributes()363 	DEPRECATED(3.05A, GetAttributeCount and GetAttribute(index)) void GetAttributes() const {}
364 
365 	/** Retrieves the number of attributes for this extra tree node.
366 		@return The number of attributes. */
GetAttributeCount()367 	size_t GetAttributeCount() const { return attributes.size(); }
368 
369 	/** Retrieves a specific attribute of this extra tree node.
370 		@param index The index.
371 		@return The attribute at this index. This pointer will be NULL
372 			if the index is out-of-bounds. */
GetAttribute(size_t index)373 	FCDEAttribute* GetAttribute(size_t index) { FUAssert(index < attributes.size(), return NULL); return attributes.at(index); }
GetAttribute(size_t index)374 	const FCDEAttribute* GetAttribute(size_t index) const { FUAssert(index < attributes.size(), return NULL); return attributes.at(index); } /**< See above. */
375 
376 	/** Adds a new attribute to this extra tree node.
377 		If an attribute with the same name already exists, this function simply
378 		assigns the new value to the existing attribute and returns the existing attribute.
379 		@param _name The name of the attribute. If this parameter is
380 			a non-constant fm::string reference, it will be updated with the cleaned name.
381 		@param _value The value of the attribute.
382 		@return The new attribute. */
383 	FCDEAttribute* AddAttribute(fm::string& _name, const fchar* _value);
AddAttribute(const char * _name,const fchar * _value)384 	inline FCDEAttribute* AddAttribute(const char* _name, const fchar* _value) { fm::string n = _name; return AddAttribute(n, _value); } /**< See above. */
AddAttribute(const fm::string & _name,const fchar * _value)385 	inline FCDEAttribute* AddAttribute(const fm::string& _name, const fchar* _value) { fm::string n = _name; return AddAttribute(n, _value); } /**< See above. */
AddAttribute(const char * _name,const fstring & _value)386 	inline FCDEAttribute* AddAttribute(const char* _name, const fstring& _value) { fm::string n = _name; return AddAttribute(n, _value.c_str()); } /**< See above. */
AddAttribute(fm::string & _name,const fstring & _value)387 	inline FCDEAttribute* AddAttribute(fm::string& _name, const fstring& _value) { return AddAttribute(_name, _value.c_str()); } /**< See above. */
AddAttribute(const fm::string & _name,const fstring & _value)388 	inline FCDEAttribute* AddAttribute(const fm::string& _name, const fstring& _value) { fm::string n = _name; return AddAttribute(n, _value.c_str()); } /**< See above. */
AddAttribute(const char * _name,const T & _value)389 	template <typename T> inline FCDEAttribute* AddAttribute(const char* _name, const T& _value) { fm::string n = _name; return AddAttribute(n, TO_FSTRING(_value)); } /**< See above. */
AddAttribute(fm::string & _name,const T & _value)390 	template <typename T> inline FCDEAttribute* AddAttribute(fm::string& _name, const T& _value) { return AddAttribute(_name, TO_FSTRING(_value)); } /**< See above. */
AddAttribute(const fm::string & _name,const T & _value)391 	template <typename T> inline FCDEAttribute* AddAttribute(const fm::string& _name, const T& _value) { fm::string n = _name; return AddAttribute(n, TO_FSTRING(_value)); } /**< See above. */
392 
393 	/** Retrieve the attribute of this extra tree node with the given name.
394 		Attribute names are unique within an extra tree node.
395 		@param name The attribute name.
396 		@return The attribute that matches the name. This pointer will be NULL if
397 			there is no attribute with the given name. */
FindAttribute(const char * name)398 	inline FCDEAttribute* FindAttribute(const char* name) { return const_cast<FCDEAttribute*>(const_cast<const FCDENode*>(this)->FindAttribute(name)); }
399 	const FCDEAttribute* FindAttribute(const char* name) const; /**< See above. */
400 
401 	/** Retrieves the value of an attribute on this extra tree node.
402 		Attributes names are unique within an extra tree node.
403 		@param name The attribute name.
404 		@return The value attached to the attribute with the given name. This value
405 			will be the empty string when no attribute exists with the given name. */
406 	const fstring& ReadAttribute(const char* name) const;
407 
408 	/** Adds a parameter as the child node.
409 		A parameter is the simplest child node possible:
410 		with a name and a value, represented as the node's content.
411 		@see AddChildNode
412 		@param name The parameter name.
413 		@param value The parameter value. */
414 	FCDENode* AddParameter(const char* name, const fchar* value);
AddParameter(const fm::string & name,const fchar * value)415 	inline FCDENode* AddParameter(const fm::string& name, const fchar* value) { return AddParameter(name.c_str(), value); } /**< See above. */
AddParameter(const char * name,const fstring & value)416 	inline FCDENode* AddParameter(const char* name, const fstring& value) { return AddParameter(name, value.c_str()); } /**< See above. */
AddParameter(const fm::string & name,const fstring & value)417 	inline FCDENode* AddParameter(const fm::string& name, const fstring& value) { return AddParameter(name.c_str(), value.c_str()); } /**< See above. */
418 	template <class T>
AddParameter(const char * name,const T & value)419 	inline FCDENode* AddParameter(const char* name, const T& value) { return AddParameter(name, TO_FSTRING(value)); } /**< See above. */
420 	template <class T>
AddParameter(const fm::string & name,const T & value)421 	inline FCDENode* AddParameter(const fm::string& name, const T& value) { return AddParameter(name.c_str(), TO_FSTRING(value)); } /**< See above. */
422 
423 	/** Clones the extra tree node.
424 		@param clone The extra tree node that will receive the clone information.
425 			This pointer cannot be NULL.
426 		@return The clone. You will need to release the returned pointer manually. */
427 	virtual FCDENode* Clone(FCDENode* clone) const;
428 };
429 
430 /**
431 	A COLLADA extra tree technique.
432 
433 	For convenience, this extra tree technique is based on top of the FCDENode class.
434 	An extra tree technique is the root of the extra tree specific to
435 	the profile of an application.
436 
437 	@ingroup FCDocument
438 */
439 class FCOLLADA_EXPORT FCDETechnique : public FCDENode
440 {
441 private:
442 	DeclareObjectType(FCDENode);
443 
444 	FCDEType* parent;
445 	DeclareParameterPtr(FUTrackable, pluginOverride, FC("Plug-in Override Object"));
446 	DeclareParameter(fm::string, FUParameterQualifiers::SIMPLE, profile, FC("Profile Name"));
447 
448 public:
449 	/** Constructor: do not use directly.
450 		Instead, use the FCDEType::AddTechnique function.
451 		@param document The COLLADA document that owns the technique.
452 		@param parent The extra type that contains this technique.
453 		@param profile The application-specific profile name. */
454 	FCDETechnique(FCDocument* document, FCDEType* parent, const char* profile);
455 
456 	/** Destructor. */
457 	virtual ~FCDETechnique();
458 
459 	/** Retrieves the name of the application-specific profile of the technique.
460 		@return The name of the application-specific profile. */
GetProfile()461 	const char* GetProfile() const { return profile->c_str(); }
462 
463 	/** Sets the name of the application-specific profile of the technique.
464 		Be careful when modifying the application-specific profile name.
465 		There is an assumption that within a typed-extra, all application-specific
466 		profile names are unique.
467 		@param _profile The new name of the application-specific profile. */
SetProfile(const fm::string & _profile)468 	void SetProfile(const fm::string& _profile) { profile = _profile; }
469 
470 	/** Retrieves the plug-in object that overrides the extra tree for this profile.
471 		The plug-in object should contain all the necessary information and this extra tree
472 		is expected to be empty.
473 		@return The profile-specific plug-in object. */
GetPluginObject()474 	FUTrackable* GetPluginObject() { return pluginOverride; }
GetPluginObject()475 	const FUTrackable* GetPluginObject() const { return pluginOverride; } /**< See above. */
476 
477 	/** Sets the plug-in object that overrides the extra tree for this profile.*/
SetPluginObject(FUTrackable * plugin)478 	void SetPluginObject(FUTrackable* plugin) { pluginOverride = plugin; }
479 
480 	/** Clones the extra tree node.
481 		@param clone The extra tree node that will receive the clone information.
482 			If this pointer is NULL, a new extra tree technique will be created and you will
483 			need to release the returned pointer manually.
484 		@return The clone. */
485 	virtual FCDENode* Clone(FCDENode* clone) const;
486 };
487 
488 /**
489 	An extra tree attribute.
490 	Contains a name and a value string.
491 */
492 class FCDEAttribute : public FUParameterizable
493 {
494 private:
495 	DeclareParameter(fm::string, FUParameterQualifiers::SIMPLE, name, FC("Attribute Name")); /**< The attribute name. Must be provided. */
496 	DeclareParameter(fstring, FUParameterQualifiers::SIMPLE, value, FC("Attribute Value")); /**< The attribute value. Is optional. */
497 
498 public:
499 	/** Default constructor.
500 		The name and the value string will be blank. */
501 	FCDEAttribute();
502 
503 	/** Constructor.
504 		Sets the attribute name and the attribute value appropriately.
505 		@param name The attribute name.
506 		@param value The attribute value. */
507 	FCDEAttribute(const char* name, const fchar* value);
508 
509 	/** Retrieves the name of the attribute.
510 		@return The name of the attribute. */
GetName()511 	inline const fm::string& GetName() const { return name; }
512 
513 	/** Sets the name of the attribute.
514 		@param _name The new name of the attribute. */
SetName(const fm::string & _name)515 	inline void SetName(const fm::string& _name) { name = _name; }
516 
517 	/** Retrieves the value of the attribute.
518 		@return The value of the attribute. */
GetValue()519 	inline const fstring& GetValue() const { return value; }
520 
521 	/** Sets the value of the attribute.
522 		@param _value The new value of the attribute. */
SetValue(const fstring & _value)523 	inline void SetValue(const fstring& _value) { value = _value; }
524 };
525 
526 #endif // _FCD_EXTRA_H_
527