1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 29 #ifndef __StringInterface_H__ 30 #define __StringInterface_H__ 31 32 #include "OgrePrerequisites.h" 33 #include "OgreCommon.h" 34 #include "Threading/OgreThreadHeaders.h" 35 #include "OgreHeaderPrefix.h" 36 37 namespace Ogre { 38 39 /** \addtogroup Core 40 * @{ 41 */ 42 /** \addtogroup General 43 * @{ 44 */ 45 46 /// List of parameter types available 47 enum ParameterType 48 { 49 PT_BOOL, 50 PT_REAL, 51 PT_INT, 52 PT_UNSIGNED_INT, 53 PT_SHORT, 54 PT_UNSIGNED_SHORT, 55 PT_LONG, 56 PT_UNSIGNED_LONG, 57 PT_STRING, 58 PT_VECTOR3, 59 PT_MATRIX3, 60 PT_MATRIX4, 61 PT_QUATERNION, 62 PT_COLOURVALUE 63 }; 64 65 /// Definition of a parameter supported by a StringInterface class, for introspection 66 class _OgreExport ParameterDef 67 { 68 public: 69 String name; 70 ParameterType paramType; ParameterDef(const String & newName,const String & newDescription,ParameterType newType)71 ParameterDef(const String& newName, const String& newDescription, ParameterType newType) 72 : name(newName), paramType(newType) {} 73 }; 74 typedef std::vector<ParameterDef> ParameterList; 75 76 /** Abstract class which is command object which gets/sets parameters.*/ 77 class _OgreExport ParamCommand 78 { 79 public: 80 virtual String doGet(const void* target) const = 0; 81 virtual void doSet(void* target, const String& val) = 0; 82 ~ParamCommand()83 virtual ~ParamCommand() { } 84 }; 85 typedef std::map<String, ParamCommand* > ParamCommandMap; 86 87 /** Class to hold a dictionary of parameters for a single class. */ 88 class _OgreExport ParamDictionary 89 { 90 friend class StringInterface; 91 protected: 92 /// Definitions of parameters 93 ParameterList mParamDefs; 94 95 /// Command objects to get/set 96 ParamCommandMap mParamCommands; 97 98 /** Retrieves the parameter command object for a named parameter. */ getParamCommand(const String & name)99 ParamCommand* getParamCommand(const String& name) 100 { 101 ParamCommandMap::iterator i = mParamCommands.find(name); 102 if (i != mParamCommands.end()) 103 { 104 return i->second; 105 } 106 else 107 { 108 return 0; 109 } 110 } 111 getParamCommand(const String & name)112 const ParamCommand* getParamCommand(const String& name) const 113 { 114 ParamCommandMap::const_iterator i = mParamCommands.find(name); 115 if (i != mParamCommands.end()) 116 { 117 return i->second; 118 } 119 else 120 { 121 return 0; 122 } 123 } 124 public: ParamDictionary()125 ParamDictionary() {} 126 /** Method for adding a parameter definition for this class. 127 @param paramDef A ParameterDef object defining the parameter 128 @param paramCmd Pointer to a ParamCommand subclass to handle the getting / setting of this parameter. 129 NB this class will not destroy this on shutdown, please ensure you do 130 131 */ addParameter(const ParameterDef & paramDef,ParamCommand * paramCmd)132 void addParameter(const ParameterDef& paramDef, ParamCommand* paramCmd) 133 { 134 mParamDefs.push_back(paramDef); 135 mParamCommands[paramDef.name] = paramCmd; 136 } 137 /** Retrieves a list of parameters valid for this object. 138 @return 139 A reference to a static list of ParameterDef objects. 140 141 */ getParameters(void)142 const ParameterList& getParameters(void) const 143 { 144 return mParamDefs; 145 } 146 147 148 149 }; 150 typedef std::map<String, ParamDictionary> ParamDictionaryMap; 151 152 /** Class defining the common interface which classes can use to 153 present a reflection-style, self-defining parameter set to callers. 154 @remarks 155 This class also holds a static map of class name to parameter dictionaries 156 for each subclass to use. See ParamDictionary for details. 157 @remarks 158 In order to use this class, each subclass must call createParamDictionary in their constructors 159 which will create a parameter dictionary for the class if it does not exist yet. 160 */ 161 class _OgreExport StringInterface 162 { 163 private: 164 OGRE_STATIC_MUTEX( msDictionaryMutex ); 165 166 /// Dictionary of parameters 167 static ParamDictionaryMap msDictionary; 168 169 /// Class name for this instance to be used as a lookup (must be initialised by subclasses) 170 String mParamDictName; 171 ParamDictionary* mParamDict; 172 173 protected: 174 /** Internal method for creating a parameter dictionary for the class, if it does not already exist. 175 @remarks 176 This method will check to see if a parameter dictionary exist for this class yet, 177 and if not will create one. NB you must supply the name of the class (RTTI is not 178 used or performance). 179 @param 180 className the name of the class using the dictionary 181 @return 182 true if a new dictionary was created, false if it was already there 183 */ createParamDictionary(const String & className)184 bool createParamDictionary(const String& className) 185 { 186 OGRE_LOCK_MUTEX( msDictionaryMutex ); 187 188 ParamDictionaryMap::iterator it = msDictionary.find(className); 189 190 if ( it == msDictionary.end() ) 191 { 192 mParamDict = &msDictionary.insert( std::make_pair( className, ParamDictionary() ) ).first->second; 193 mParamDictName = className; 194 return true; 195 } 196 else 197 { 198 mParamDict = &it->second; 199 mParamDictName = className; 200 return false; 201 } 202 } 203 204 public: StringInterface()205 StringInterface() : mParamDict(NULL) { } 206 207 /** Virtual destructor, see Effective C++ */ ~StringInterface()208 virtual ~StringInterface() {} 209 210 /** Retrieves the parameter dictionary for this class. 211 @remarks 212 Only valid to call this after createParamDictionary. 213 @return 214 Pointer to ParamDictionary shared by all instances of this class 215 which you can add parameters to, retrieve parameters etc. 216 */ getParamDictionary(void)217 ParamDictionary* getParamDictionary(void) 218 { 219 return mParamDict; 220 } 221 getParamDictionary(void)222 const ParamDictionary* getParamDictionary(void) const 223 { 224 return mParamDict; 225 } 226 227 /** Retrieves a list of parameters valid for this object. 228 @return 229 A reference to a static list of ParameterDef objects. 230 231 */ 232 const ParameterList& getParameters(void) const; 233 234 /** Generic parameter setting method. 235 @remarks 236 Call this method with the name of a parameter and a string version of the value 237 to set. The implementor will convert the string to a native type internally. 238 If in doubt, check the parameter definition in the list returned from 239 StringInterface::getParameters. 240 @param 241 name The name of the parameter to set 242 @param 243 value String value. Must be in the right format for the type specified in the parameter definition. 244 See the StringConverter class for more information. 245 @return 246 true if set was successful, false otherwise (NB no exceptions thrown - tolerant method) 247 */ 248 bool setParameter(const String& name, const String& value); 249 /** Generic multiple parameter setting method. 250 @remarks 251 Call this method with a list of name / value pairs 252 to set. The implementor will convert the string to a native type internally. 253 If in doubt, check the parameter definition in the list returned from 254 StringInterface::getParameters. 255 @param 256 paramList Name/value pair list 257 */ 258 void setParameterList(const NameValuePairList& paramList); 259 /** Generic parameter retrieval method. 260 @remarks 261 Call this method with the name of a parameter to retrieve a string-format value of 262 the parameter in question. If in doubt, check the parameter definition in the 263 list returned from getParameters for the type of this parameter. If you 264 like you can use StringConverter to convert this string back into a native type. 265 @param 266 name The name of the parameter to get 267 @return 268 String value of parameter, blank if not found 269 */ getParameter(const String & name)270 String getParameter(const String& name) const 271 { 272 // Get dictionary 273 const ParamDictionary* dict = getParamDictionary(); 274 275 if (dict) 276 { 277 // Look up command object 278 const ParamCommand* cmd = dict->getParamCommand(name); 279 280 if (cmd) 281 { 282 return cmd->doGet(this); 283 } 284 } 285 286 // Fallback 287 return ""; 288 } 289 /** Method for copying this object's parameters to another object. 290 @remarks 291 This method takes the values of all the object's parameters and tries to set the 292 same values on the destination object. This provides a completely type independent 293 way to copy parameters to other objects. Note that because of the String manipulation 294 involved, this should not be regarded as an efficient process and should be saved for 295 times outside of the rendering loop. 296 @par 297 Any unrecognised parameters will be ignored as with setParameter method. 298 @param dest Pointer to object to have it's parameters set the same as this object. 299 300 */ copyParametersTo(StringInterface * dest)301 void copyParametersTo(StringInterface* dest) const 302 { 303 // Get dictionary 304 const ParamDictionary* dict = getParamDictionary(); 305 306 if (dict) 307 { 308 // Iterate through own parameters 309 ParameterList::const_iterator i; 310 311 for (i = dict->mParamDefs.begin(); 312 i != dict->mParamDefs.end(); ++i) 313 { 314 dest->setParameter(i->name, getParameter(i->name)); 315 } 316 } 317 318 319 } 320 321 /** Cleans up the static 'msDictionary' required to reset Ogre, 322 otherwise the containers are left with invalid pointers, which will lead to a crash 323 as soon as one of the ResourceManager implementers (e.g. MaterialManager) initializes.*/ 324 static void cleanupDictionary () ; 325 326 }; 327 328 /** @} */ 329 /** @} */ 330 331 332 } 333 334 #include "OgreHeaderSuffix.h" 335 336 #endif 337 338