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
23struct 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 */
58class DLLSPEC daeSIDResolver
59{
60public:
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
145private:
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.
154class DLLSPEC daeSidRefCache {
155public:
156	daeSidRefCache();
157
158	daeSidRef::resolveData lookup(const daeSidRef& sidRef);
159	void add(const daeSidRef& sidRef, const daeSidRef::resolveData& data);
160	void clear();
161
162	// For debugging/testing
163	bool empty();
164	int misses();
165	int hits();
166
167private:
168	std::map<daeSidRef, daeSidRef::resolveData> lookupTable;
169	int hitCount;
170	int missCount;
171};
172
173#endif
174
175