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 #ifndef __DAE_SIDRESOLVER_H__
10 #define __DAE_SIDRESOLVER_H__
11 
12 #include <string>
13 #include <map>
14 #include <dae/daeTypes.h>
15 #include <dae/daeElement.h>
16 
17 
18 // This is an alternative to the daeSIDResolver class. It's recommended you use
19 // this class instead. Typical usage: get the element a sid ref points to. For
20 // example, if you want to find the element with sid 'sampler' using a
21 // daeElement pointer named 'effect', that would look like this:
22 //   daeElement* elt = daeSidRef("sampler", effect).resolve().elt
23 struct DLLSPEC daeSidRef {
24 	// A helper class for returning all the data retrieved when a sid is resolved.
25 	struct DLLSPEC resolveData {
26 		resolveData();
27 		resolveData(daeElement* elt, daeDoubleArray* array, daeDouble* scalar);
28 
29 		daeElement* elt;
30 		daeDoubleArray* array;
31 		daeDouble* scalar;
32 	};
33 
34 	daeSidRef();
35 	daeSidRef(const std::string& sidRef, daeElement* referenceElt, const std::string& profile = "");
36 	bool operator<(const daeSidRef& other) const;
37 
38 	resolveData resolve();
39 
40 	std::string sidRef;
41 	daeElement* refElt;
42 	std::string profile;
43 };
44 
45 
46 /**
47  * The daeSIDResolver class is designed to resolve sid references within a COLLADA document.
48  * The rules for sid resolution are set forth by the Addressing Syntax section in Chapter 3 of the
49  * COLLADA specification which can be found at https://www.khronos.org/collada .
50  * This resolver always attempts to resolve to the daeElement which is referenced. If the element contains
51  * a daeDoubleArray (domFloatArray) value, the resolver will set the pointer to that array. The
52  * resolver will also do this if the sid target points to a <source> element which has a <float_array> as
53  * a child. If the sid target specifies a value, i.e. blah.X or blah(6), the resolver will attempt to
54  * get a pointer to that specific value. The resolver only attempts to resolve to that level for values which
55  * are defined in the COMMON profile glossary of the COLLADA specification, or values reference with the (#)
56  * syntax. You can check the return value from getState() to see which level of resolution is possible.
57  */
58 class DLLSPEC daeSIDResolver
59 {
60 public:
61 	/**
62 	 * An enum describing the status of the SID resolution process.
63 	 */
64 	enum ResolveState{
65 		/** No target specified */
66 		target_empty,
67 		/** target specified but not resolved */
68 		target_loaded,
69 		/** Resolution failed because target was not found */
70 		sid_failed_not_found,
71 		/** Resolution successful to the Element level */
72 		sid_success_element,
73 		/** Resolution successful to the Double Array level */
74 		sid_success_array,
75 		/** Resolution successful to the Double level */
76 		sid_success_double
77 	};
78 
79 	/**
80 	 * Constructor.
81 	 * @param container The element which contains the target that you want to resolve.
82 	 * @param target The target string which needs to be resolved.
83 	 * @param platform The platform name of the technique to use. A NULL value indicates the common platform.
84 	 */
85 	daeSIDResolver( daeElement *container, daeString target, daeString platform = NULL );
86 
87 	/**
88 	 * Gets the target string.
89 	 * @return Returns the target string of this SID resolver.
90 	 */
91 	daeString getTarget() const;
92 	/**
93 	 * Sets the target string.
94 	 * @param t The new target string for this resolver.
95 	 */
96 	void setTarget( daeString t );
97 
98 	/**
99 	 * Gets the name of the profile to use when resolving.
100 	 * @return Returns the name of the profile or NULL for the common profile.
101 	 */
102 	daeString getProfile()	const;
103 	/**
104 	 * Sets the profile to use when resolving.
105 	 * @param p The profile name of the technique to use. A NULL value indicates the common profile.
106 	 */
107 	void setProfile( daeString p );
108 
109 	/**
110 	 * Gets a pointer to the @c daeElement that contains the target to resolve.
111 	 * @return Returns the pointer to the containing daeElmement.
112 	 */
113 	daeElement* getContainer() const;
114 	/**
115 	 * Sets the pointer to the @c daeElement that contains the target to resolve.
116 	 * @param element Pointer to the containing @c daeElmement.
117 	 */
118 	void setContainer(daeElement* element);
119 
120 	/**
121 	 * Gets the element that this SID resolves to.
122 	 * @return Returns the element that the URI resolves to.
123 	 */
124 	daeElement* getElement();
125 
126 	/**
127 	 * Gets the value array of the element that the SID resolves to.
128 	 * @return Returns a pointer to the value array that the SID resolves to
129 	 * @note The daeSIDResolver can only resolve to this level for daeDoubleArray values.
130 	 */
131 	daeDoubleArray *getDoubleArray();
132 
133 	/**
134 	 * Gets a pointer to the particle this target resolved to.
135 	 * @return Returns a pointer to a double value which is the fully resolved target.
136 	 * @note The daeSIDResolver can only resolve to this level for domDouble values and only if the
137 	 * final symbolic name is from the COMMON profile or a cardinal value is specified.
138 	 * @note The daeSIDResolver assumes the value is a 4x4 matrix if there are 2 cardinal values specified.
139 	 */
140 	daeDouble *getDouble();
141 
142 	// This method is deprecated. Don't use it.
143 	ResolveState getState() const;
144 
145 private:
146 	// This data is provided by the user
147 	std::string	target;
148 	std::string	profile;
149 	daeElement* container;
150 };
151 
152 
153 // A class to make sid ref lookups faster. Meant for DOM internal use only.
154 class DLLSPEC daeSidRefCache {
155 public:
156 	daeSidRefCache();
157 	~daeSidRefCache();
158 
159 	daeSidRef::resolveData lookup(const daeSidRef& sidRef);
160 	void add(const daeSidRef& sidRef, const daeSidRef::resolveData& data);
161 	void clear();
162 
163 	// For debugging/testing
164 	bool empty();
165 	int misses();
166 	int hits();
167 
168 private:
169 	std::map<daeSidRef, daeSidRef::resolveData> * lookupTable;
170 	int hitCount;
171 	int missCount;
172 };
173 
174 #endif
175 
176