Changeset 10624 for code/trunk/src/libraries/core
- Timestamp:
- Oct 4, 2015, 9:12:21 PM (9 years ago)
- Location:
- code/trunk
- Files:
-
- 9 deleted
- 64 edited
- 22 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
-
code/trunk/src/libraries/core/BaseObject.cc
r9667 r10624 63 63 this->bActive_ = true; 64 64 this->bVisible_ = true; 65 this->oldGametype_ = 0;66 65 this->bRegisteredEventStates_ = false; 67 66 … … 78 77 { 79 78 this->setFile(this->creator_->getFile()); 80 this->setNamespace(this->creator_->getNamespace()); 81 this->setScene(this->creator_->getScene(), this->creator_->getSceneID()); 82 this->setGametype(this->creator_->getGametype()); 83 this->setLevel(this->creator_->getLevel()); 79 80 // store strong-pointers on all four base objects by default (can be overwritten with weak-ptr after the constructor if necessary) 81 this->setNamespace(this->creator_->namespace_.createStrongPtr()); 82 this->setScene (this->creator_->scene_ .createStrongPtr(), this->creator_->sceneID_); 83 this->setGametype (this->creator_->gametype_ .createStrongPtr()); 84 this->setLevel (this->creator_->level_ .createStrongPtr()); 84 85 } 85 86 else 86 87 { 87 88 this->file_ = 0; 88 this->namespace_ = 0;89 this->scene_ = 0;90 89 this->sceneID_ = OBJECTID_UNKNOWN; 91 this->gametype_ = 0;92 this->level_ = 0;93 90 } 94 91 } -
code/trunk/src/libraries/core/BaseObject.h
r10298 r10624 51 51 #include "class/OrxonoxClass.h" 52 52 #include "class/Super.h" 53 #include "object/S martPtr.h"53 #include "object/StrongPtr.h" 54 54 55 55 namespace orxonox … … 63 63 { 64 64 template <class T> friend class XMLPortClassParamContainer; 65 66 public: 67 template <class T> 68 class StrongOrWeakPtr 69 { 70 public: 71 inline StrongOrWeakPtr(); 72 inline StrongOrWeakPtr(const StrongPtr<T>& ptr); 73 inline StrongOrWeakPtr(const WeakPtr<T>& ptr); 74 75 inline T* get() const; 76 inline StrongPtr<T> createStrongPtr() const; 77 78 private: 79 StrongPtr<T> strongPtr_; 80 WeakPtr<T> weakPtr_; 81 }; 65 82 66 83 public: … … 138 155 { return this->templates_; } 139 156 140 inline void setNamespace(const S martPtr<Namespace>& ns) { this->namespace_ = ns; }141 inline const SmartPtr<Namespace>& getNamespace() const { return this->namespace_; }157 inline void setNamespace(const StrongOrWeakPtr<Namespace>& ns) { this->namespace_ = ns; } 158 inline Namespace* getNamespace() const { return this->namespace_.get(); } 142 159 143 160 inline void setCreator(BaseObject* creator) { this->creator_ = creator; } 144 161 inline BaseObject* getCreator() const { return this->creator_; } 145 162 146 inline void setScene(const S martPtr<Scene>& scene, uint32_t sceneID) { this->scene_ = scene; this->sceneID_=sceneID; }147 inline const SmartPtr<Scene>& getScene() const { return this->scene_; }163 inline void setScene(const StrongOrWeakPtr<Scene>& scene, uint32_t sceneID) { this->scene_ = scene; this->sceneID_=sceneID; } 164 inline Scene* getScene() const { return this->scene_.get(); } 148 165 inline virtual uint32_t getSceneID() const { return this->sceneID_; } 149 166 150 inline void setGametype(const SmartPtr<Gametype>& gametype) 151 { 152 if (gametype != this->gametype_) 153 { 154 this->oldGametype_ = this->gametype_; 155 this->gametype_ = gametype; 156 this->changedGametype(); 157 } 158 } 159 inline const SmartPtr<Gametype>& getGametype() const { return this->gametype_; } 160 inline Gametype* getOldGametype() const { return this->oldGametype_; } 161 virtual void changedGametype() {} 162 163 inline void setLevel(const SmartPtr<Level>& level) 164 { 165 if (level != this->level_) 166 { 167 this->level_ = level; 168 this->changedLevel(); 169 } 170 } 171 inline const SmartPtr<Level>& getLevel() const { return this->level_; } 172 virtual void changedLevel() {} 167 inline void setGametype(const StrongOrWeakPtr<Gametype>& gametype) { this->gametype_ = gametype; } 168 inline Gametype* getGametype() const { return this->gametype_.get(); } 169 170 inline void setLevel(const StrongOrWeakPtr<Level>& level) { this->level_ = level; } 171 inline Level* getLevel() const { return this->level_.get(); } 173 172 174 173 void addEventSource(BaseObject* source, const std::string& state); … … 217 216 void registerEventStates(); 218 217 219 bool bInitialized_;//!< True if the object was initialized (passed the object registration)220 const XMLFile* file_;//!< The XMLFile that loaded this object221 Element* lastLoadedXMLElement_;//!< Non 0 if the TinyXML attributes have already been copied to our own lowercase map218 bool bInitialized_; //!< True if the object was initialized (passed the object registration) 219 const XMLFile* file_; //!< The XMLFile that loaded this object 220 Element* lastLoadedXMLElement_; //!< Non 0 if the TinyXML attributes have already been copied to our own lowercase map 222 221 std::map<std::string, std::string> xmlAttributes_; //!< Lowercase XML attributes 223 std::string loaderIndentation_; //!< Indentation of the debug output in the Loader 224 SmartPtr<Namespace> namespace_; 225 BaseObject* creator_; 226 SmartPtr<Scene> scene_; 227 uint32_t sceneID_; 228 SmartPtr<Gametype> gametype_; 229 Gametype* oldGametype_; 230 SmartPtr<Level> level_; 231 std::set<Template*> templates_; 222 std::string loaderIndentation_; //!< Indentation of the debug output in the Loader 223 StrongOrWeakPtr<Namespace> namespace_; 224 BaseObject* creator_; 225 StrongOrWeakPtr<Scene> scene_; 226 uint32_t sceneID_; 227 StrongOrWeakPtr<Gametype> gametype_; 228 StrongOrWeakPtr<Level> level_; 229 std::set<Template*> templates_; 232 230 233 231 std::map<BaseObject*, std::string> eventSources_; //!< List of objects which send events to this object, mapped to the state which they affect … … 243 241 SUPER_FUNCTION(4, BaseObject, XMLEventPort, false); 244 242 SUPER_FUNCTION(8, BaseObject, changedName, false); 245 SUPER_FUNCTION(9, BaseObject, changedGametype, false); 243 244 template <class T> 245 BaseObject::StrongOrWeakPtr<T>::StrongOrWeakPtr() 246 { 247 } 248 249 template <class T> 250 BaseObject::StrongOrWeakPtr<T>::StrongOrWeakPtr(const StrongPtr<T>& ptr) : strongPtr_(ptr) 251 { 252 } 253 254 template <class T> 255 BaseObject::StrongOrWeakPtr<T>::StrongOrWeakPtr(const WeakPtr<T>& ptr) : weakPtr_(ptr) 256 { 257 } 258 259 template <class T> 260 T* BaseObject::StrongOrWeakPtr<T>::get() const 261 { 262 if (this->strongPtr_) 263 return this->strongPtr_; 264 else if (this->weakPtr_) 265 return this->weakPtr_; 266 else 267 return NULL; 268 } 269 270 template <class T> 271 StrongPtr<T> BaseObject::StrongOrWeakPtr<T>::createStrongPtr() const 272 { 273 if (this->strongPtr_) 274 return this->strongPtr_; // creates a copy 275 else 276 return this->weakPtr_; // converts automatically to StrongPtr 277 } 246 278 } 247 279 -
code/trunk/src/libraries/core/CMakeLists.txt
r10268 r10624 22 22 #BUILD_UNIT CoreStableBuildUnit.cc 23 23 ClassTreeMask.cc 24 DynLib.cc25 DynLibManager.cc26 24 Event.cc 27 25 Game.cc 26 GameConfig.cc 28 27 GameMode.cc 29 28 GameState.cc … … 34 33 NamespaceNode.cc 35 34 Template.cc 35 UpdateListener.cc 36 36 ViewportEventListener.cc 37 37 WindowEventListener.cc … … 42 42 BaseObject.cc 43 43 Core.cc 44 CoreConfig.cc 45 CoreStaticInitializationHandler.cc 44 46 45 47 BUILD_UNIT OgreBuildUnit.cc … … 52 54 command/ArgumentCompletionFunctions.cc 53 55 config/ConfigFile.cc 54 PathConfig.cc 56 ApplicationPaths.cc 57 ConfigurablePaths.cc 55 58 END_BUILD_UNIT 56 59 … … 64 67 ADD_SUBDIRECTORY(class) 65 68 ADD_SUBDIRECTORY(command) 69 ADD_SUBDIRECTORY(commandline) 66 70 ADD_SUBDIRECTORY(config) 67 71 ADD_SUBDIRECTORY(input) 72 ADD_SUBDIRECTORY(module) 68 73 ADD_SUBDIRECTORY(object) 74 ADD_SUBDIRECTORY(singleton) 69 75 70 76 #Add the icon (for the renderwindow) … … 78 84 command/CommandExecutor.h 79 85 config/SettingsConfigFile.h 86 ApplicationPaths.h 87 ConfigurablePaths.h 80 88 Game.h 81 89 GameMode.h … … 84 92 Loader.h 85 93 LuaState.h 86 PathConfig.h87 94 input/InputManager.h 88 95 input/KeyBinder.h -
code/trunk/src/libraries/core/ClassTreeMask.cc
r9667 r10624 293 293 { 294 294 // No it's not: Search for classes inheriting from the given class and add the rules for them 295 for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildren Begin(); it != subclass->getDirectChildrenEnd(); ++it)295 for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildren().begin(); it != subclass->getDirectChildren().end(); ++it) 296 296 if ((*it)->isA(this->root_->getClass())) 297 297 if (overwrite || (!this->nodeExists(*it))) // If we don't want to overwrite, only add nodes that don't already exist … … 392 392 if (!subclass) 393 393 return; 394 for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildren Begin(); it != subclass->getDirectChildrenEnd(); ++it)394 for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildren().begin(); it != subclass->getDirectChildren().end(); ++it) 395 395 this->add(*it, this->isIncluded(*it), false, false); 396 396 … … 943 943 944 944 // Insert all directChildren of the directChild 945 directChildren.insert((*it2)->getDirectChildren Begin(), (*it2)->getDirectChildrenEnd());945 directChildren.insert((*it2)->getDirectChildren().begin(), (*it2)->getDirectChildren().end()); 946 946 947 947 // Restart the scan with the expanded set of directChildren -
code/trunk/src/libraries/core/Core.cc
r9667 r10624 54 54 #include "util/Output.h" 55 55 #include "util/Exception.h" 56 #include "util/SignalHandler.h" 56 57 #include "util/output/LogWriter.h" 57 58 #include "util/output/OutputManager.h" 58 #include "util/Scope.h" 59 #include "util/ScopedSingletonManager.h" 60 #include "util/SignalHandler.h" 61 #include "PathConfig.h" 62 #include "config/CommandLineParser.h" 59 #include "core/singleton/Scope.h" 60 #include "ApplicationPaths.h" 61 #include "ConfigurablePaths.h" 62 #include "commandline/CommandLineIncludes.h" 63 63 #include "config/ConfigFileManager.h" 64 #include "config/ConfigValueIncludes.h"65 #include "CoreIncludes.h"66 #include "DynLibManager.h"67 64 #include "GameMode.h" 68 65 #include "GraphicsManager.h" 69 66 #include "GUIManager.h" 70 #include "class/Identifier.h"71 67 #include "Language.h" 68 #include "Loader.h" 72 69 #include "LuaState.h" 73 #include "command/ConsoleCommand.h"74 70 #include "command/IOConsole.h" 75 71 #include "command/TclBind.h" … … 77 73 #include "input/InputManager.h" 78 74 #include "object/ObjectList.h" 75 #include "module/DynLibManager.h" 76 #include "module/ModuleInstance.h" 77 #include "module/StaticInitializationManager.h" 78 #include "module/PluginManager.h" 79 #include "CoreStaticInitializationHandler.h" 80 #include "UpdateListener.h" 79 81 80 82 namespace orxonox … … 92 94 #endif 93 95 94 // register Core as an abstract class to avoid problems if the class hierarchy is created within Core-constructor95 RegisterAbstractClass(Core).inheritsFrom(Class(Configurable));96 97 96 Core::Core(const std::string& cmdLine) 98 : pathConfig_(NULL) 97 : applicationPaths_(NULL) 98 , configurablePaths_(NULL) 99 99 , dynLibManager_(NULL) 100 100 , signalHandler_(NULL) 101 101 , configFileManager_(NULL) 102 102 , languageInstance_(NULL) 103 , loaderInstance_(NULL) 103 104 , ioConsole_(NULL) 104 105 , tclBind_(NULL) … … 110 111 , graphicsScope_(NULL) 111 112 , bGraphicsLoaded_(false) 112 , bStartIOConsole_(true)113 , lastLevelTimestamp_(0)114 , ogreConfigTimestamp_(0)115 , bDevMode_(false)113 , staticInitHandler_(NULL) 114 , pluginManager_(NULL) 115 , rootModule_(NULL) 116 , config_(NULL) 116 117 , destructionHelper_(this) 117 118 { … … 119 120 120 121 // Set the hard coded fixed paths 121 this-> pathConfig_ = new PathConfig();122 this->applicationPaths_ = new ApplicationPaths(); 122 123 123 124 // Create a new dynamic library manager 124 125 this->dynLibManager_ = new DynLibManager(); 125 126 126 // Load modules 127 orxout(internal_info) << "Loading modules:" << endl; 128 const std::vector<std::string>& modulePaths = this->pathConfig_->getModulePaths(); 129 for (std::vector<std::string>::const_iterator it = modulePaths.begin(); it != modulePaths.end(); ++it) 130 { 131 try 132 { 133 this->dynLibManager_->load(*it); 134 } 135 catch (...) 136 { 137 orxout(user_error) << "Couldn't load module \"" << *it << "\": " << Exception::handleMessage() << endl; 138 } 139 } 127 // create handler for static initialization 128 new StaticInitializationManager(); // create singleton 129 this->staticInitHandler_ = new CoreStaticInitializationHandler(); 130 StaticInitializationManager::getInstance().addHandler(this->staticInitHandler_); 131 132 // load root module (all libraries which are linked to the executable, including core, network, and orxonox) 133 this->rootModule_ = ModuleInstance::getCurrentModuleInstance(); 134 StaticInitializationManager::getInstance().loadModule(this->rootModule_); 140 135 141 136 // Parse command line arguments AFTER the modules have been loaded (static code!) … … 143 138 144 139 // Set configurable paths like log, config and media 145 this->pathConfig_->setConfigurablePaths(); 146 147 orxout(internal_info) << "Root path: " << PathConfig::getRootPathString() << endl; 148 orxout(internal_info) << "Executable path: " << PathConfig::getExecutablePathString() << endl; 149 orxout(internal_info) << "Data path: " << PathConfig::getDataPathString() << endl; 150 orxout(internal_info) << "Ext. data path: " << PathConfig::getExternalDataPathString() << endl; 151 orxout(internal_info) << "Config path: " << PathConfig::getConfigPathString() << endl; 152 orxout(internal_info) << "Log path: " << PathConfig::getLogPathString() << endl; 153 orxout(internal_info) << "Modules path: " << PathConfig::getModulePathString() << endl; 154 155 // create a signal handler (only active for Linux) 140 this->configurablePaths_ = new ConfigurablePaths(); 141 this->configurablePaths_->setConfigurablePaths(ApplicationPaths::getInstance()); 142 143 orxout(internal_info) << "Root path: " << ApplicationPaths::getRootPathString() << endl; 144 orxout(internal_info) << "Executable path: " << ApplicationPaths::getExecutablePathString() << endl; 145 orxout(internal_info) << "Modules path: " << ApplicationPaths::getModulePathString() << endl; 146 orxout(internal_info) << "Plugins path: " << ApplicationPaths::getPluginPathString() << endl; 147 148 orxout(internal_info) << "Data path: " << ConfigurablePaths::getDataPathString() << endl; 149 orxout(internal_info) << "Ext. data path: " << ConfigurablePaths::getExternalDataPathString() << endl; 150 orxout(internal_info) << "Config path: " << ConfigurablePaths::getConfigPathString() << endl; 151 orxout(internal_info) << "Log path: " << ConfigurablePaths::getLogPathString() << endl; 152 153 // create a signal handler 156 154 // This call is placed as soon as possible, but after the directories are set 157 155 this->signalHandler_ = new SignalHandler(); 158 this->signalHandler_->doCatch( PathConfig::getExecutablePathString(), PathConfig::getLogPathString() + "orxonox_crash.log");156 this->signalHandler_->doCatch(ApplicationPaths::getExecutablePathString(), ConfigurablePaths::getLogPathString() + "orxonox_crash.log"); 159 157 160 158 #ifdef ORXONOX_PLATFORM_WINDOWS … … 177 175 this->languageInstance_ = new Language(); 178 176 177 // initialize root context 178 Context::setRootContext(new Context(NULL)); 179 179 180 // Do this soon after the ConfigFileManager has been created to open up the 180 181 // possibility to configure everything below here 181 RegisterObject(Core);182 182 orxout(internal_info) << "configuring Core" << endl; 183 this-> setConfigValues();183 this->config_ = new CoreConfig(); 184 184 185 185 // Set the correct log path and rewrite the log file with the correct log levels 186 OutputManager::getInstance().getLogWriter()->setLogDirectory( PathConfig::getLogPathString());186 OutputManager::getInstance().getLogWriter()->setLogDirectory(ConfigurablePaths::getLogPathString()); 187 187 188 188 #if !defined(ORXONOX_PLATFORM_APPLE) && !defined(ORXONOX_USE_WINMAIN) 189 189 // Create persistent IO console 190 if (CommandLineParser::getValue("noIOConsole").get<bool>()) 191 { 192 ModifyConfigValue(bStartIOConsole_, tset, false); 193 } 194 if (this->bStartIOConsole_) 190 if (CommandLineParser::getValue("noIOConsole").get<bool>() == false && this->config_->getStartIOConsole()) 195 191 { 196 192 orxout(internal_info) << "creating IO console" << endl; … … 201 197 // creates the class hierarchy for all classes with factories 202 198 orxout(internal_info) << "creating class hierarchy" << endl; 203 IdentifierManager::getInstance().createClassHierarchy(); 199 this->staticInitHandler_->initInstances(this->rootModule_); 200 this->staticInitHandler_->setInitInstances(true); 201 202 // Create plugin manager and search for plugins 203 this->pluginManager_ = new PluginManager(); 204 this->pluginManager_->findPlugins(); 205 206 // Loader 207 this->loaderInstance_ = new Loader(); 204 208 205 209 // Load OGRE excluding the renderer and the render window … … 208 212 209 213 // initialise Tcl 210 this->tclBind_ = new TclBind( PathConfig::getDataPathString());214 this->tclBind_ = new TclBind(ConfigurablePaths::getDataPathString()); 211 215 this->tclThreadManager_ = new TclThreadManager(tclBind_->getTclInterpreter()); 212 216 213 217 // Create singletons that always exist (in other libraries) 214 218 orxout(internal_info) << "creating root scope:" << endl; 215 this->rootScope_ = new Scope<ScopeID::R oot>();219 this->rootScope_ = new Scope<ScopeID::ROOT>(); 216 220 217 221 // Generate documentation instead of normal run? … … 237 241 orxout(internal_status) << "destroying Core object..." << endl; 238 242 239 // Remove us from the object lists again to avoid problems when destroying them240 this->unregisterObject();241 242 243 safeObjectDelete(&graphicsScope_); 243 244 safeObjectDelete(&guiManager_); … … 248 249 safeObjectDelete(&tclBind_); 249 250 safeObjectDelete(&ioConsole_); 251 safeObjectDelete(&loaderInstance_); 252 safeObjectDelete(&config_); 250 253 safeObjectDelete(&languageInstance_); 251 254 safeObjectDelete(&configFileManager_); 252 ConsoleCommand::destroyAll();253 Context::setRootContext(NULL);254 IdentifierManager::getInstance().destroyAllIdentifiers();255 255 safeObjectDelete(&signalHandler_); 256 safeObjectDelete(&pluginManager_); 257 Context::getRootContext()->unregisterObject(); // unregister context from object lists - otherwise the root context would be destroyed while unloading the root module 258 if (this->rootModule_) 259 { 260 StaticInitializationManager::getInstance().unloadModule(this->rootModule_); 261 this->rootModule_->deleteAllStaticallyInitializedInstances(); 262 } 263 if (this->staticInitHandler_) 264 StaticInitializationManager::getInstance().removeHandler(this->staticInitHandler_); 265 Context::destroyRootContext(); 266 safeObjectDelete(&rootModule_); 267 safeObjectDelete(&staticInitHandler_); 268 delete &StaticInitializationManager::getInstance(); 256 269 safeObjectDelete(&dynLibManager_); 257 safeObjectDelete(&pathConfig_); 270 safeObjectDelete(&configurablePaths_); 271 safeObjectDelete(&applicationPaths_); 258 272 259 273 orxout(internal_status) << "finished destroying Core object" << endl; 260 274 } 261 275 262 //! Function to collect the SetConfigValue-macro calls. 263 void Core::setConfigValues() 264 { 265 SetConfigValueExternal(OutputManager::getInstance().getLogWriter()->configurableMaxLevel_, 266 OutputManager::getInstance().getLogWriter()->getConfigurableSectionName(), 267 OutputManager::getInstance().getLogWriter()->getConfigurableMaxLevelName(), 268 OutputManager::getInstance().getLogWriter()->configurableMaxLevel_) 269 .description("The maximum level of output shown in the log file") 270 .callback(static_cast<BaseWriter*>(OutputManager::getInstance().getLogWriter()), &BaseWriter::changedConfigurableLevel); 271 SetConfigValueExternal(OutputManager::getInstance().getLogWriter()->configurableAdditionalContextsMaxLevel_, 272 OutputManager::getInstance().getLogWriter()->getConfigurableSectionName(), 273 OutputManager::getInstance().getLogWriter()->getConfigurableAdditionalContextsMaxLevelName(), 274 OutputManager::getInstance().getLogWriter()->configurableAdditionalContextsMaxLevel_) 275 .description("The maximum level of output shown in the log file for additional contexts") 276 .callback(static_cast<BaseWriter*>(OutputManager::getInstance().getLogWriter()), &BaseWriter::changedConfigurableAdditionalContextsLevel); 277 SetConfigValueExternal(OutputManager::getInstance().getLogWriter()->configurableAdditionalContexts_, 278 OutputManager::getInstance().getLogWriter()->getConfigurableSectionName(), 279 OutputManager::getInstance().getLogWriter()->getConfigurableAdditionalContextsName(), 280 OutputManager::getInstance().getLogWriter()->configurableAdditionalContexts_) 281 .description("Additional output contexts shown in the log file") 282 .callback(static_cast<BaseWriter*>(OutputManager::getInstance().getLogWriter()), &BaseWriter::changedConfigurableAdditionalContexts); 283 284 SetConfigValue(bDevMode_, PathConfig::buildDirectoryRun()) 285 .description("Developer mode. If not set, hides some things from the user to not confuse him.") 286 .callback(this, &Core::devModeChanged); 287 SetConfigValue(language_, Language::getInstance().defaultLanguage_) 288 .description("The language of the in game text") 289 .callback(this, &Core::languageChanged); 290 SetConfigValue(bInitRandomNumberGenerator_, true) 291 .description("If true, all random actions are different each time you start the game") 292 .callback(this, &Core::initRandomNumberGenerator); 293 SetConfigValue(bStartIOConsole_, true) 294 .description("Set to false if you don't want to use the IOConsole (for Lua debugging for instance)"); 295 SetConfigValue(lastLevelTimestamp_, 0) 296 .description("Timestamp when the last level was started."); 297 SetConfigValue(ogreConfigTimestamp_, 0) 298 .description("Timestamp when the ogre config file was changed."); 299 } 300 301 /** Callback function for changes in the dev mode that affect debug levels. 302 The function behaves according to these rules: 303 - 'normal' mode is defined based on where the program was launched: if 304 the launch path was the build directory, development mode \c on is 305 normal, otherwise normal means development mode \c off. 306 - Debug levels should not be hard configured (\c config instead of 307 \c tconfig) in non 'normal' mode to avoid strange behaviour. 308 - Changing the development mode from 'normal' to the other state will 309 immediately change the debug levels to predefined values which can be 310 reconfigured with \c tconfig. 311 @note 312 The debug levels for the IOConsole and the InGameConsole can be found 313 in the Shell class. The same rules apply. 314 */ 315 void Core::devModeChanged() 316 { 317 // Inform listeners 318 ObjectList<DevModeListener>::iterator it = ObjectList<DevModeListener>::begin(); 319 for (; it != ObjectList<DevModeListener>::end(); ++it) 320 it->devModeChanged(bDevMode_); 321 } 322 323 //! Callback function if the language has changed. 324 void Core::languageChanged() 325 { 326 // Read the translation file after the language was configured 327 Language::getInstance().readTranslatedLanguageFile(); 328 } 329 330 void Core::initRandomNumberGenerator() 331 { 332 static bool bInitialized = false; 333 if (!bInitialized && this->bInitRandomNumberGenerator_) 334 { 335 srand(static_cast<unsigned int>(time(0))); 336 rand(); 337 bInitialized = true; 338 } 276 void Core::loadModules() 277 { 278 orxout(internal_info) << "Loading modules:" << endl; 279 280 const std::vector<std::string>& modulePaths = ApplicationPaths::getInstance().getModulePaths(); 281 for (std::vector<std::string>::const_iterator it = modulePaths.begin(); it != modulePaths.end(); ++it) 282 { 283 ModuleInstance* module = new ModuleInstance(*it); 284 this->loadModule(module); 285 this->modules_.push_back(module); 286 } 287 288 orxout(internal_info) << "finished loading modules" << endl; 289 } 290 291 void Core::loadModule(ModuleInstance* module) 292 { 293 orxout(internal_info) << "Loading module " << module->getLibraryName() << "..." << endl; 294 295 try 296 { 297 ModuleInstance::setCurrentModuleInstance(module); 298 DynLib* dynLib = this->dynLibManager_->load(module->getLibraryName()); 299 module->setDynLib(dynLib); 300 301 StaticInitializationManager::getInstance().loadModule(module); 302 } 303 catch (...) 304 { 305 orxout(user_error) << "Couldn't load module \"" << module->getLibraryName() << "\": " << Exception::handleMessage() << endl; 306 } 307 } 308 309 void Core::unloadModules() 310 { 311 for (std::list<ModuleInstance*>::iterator it = this->modules_.begin(); it != this->modules_.end(); ++it) 312 { 313 ModuleInstance* module = (*it); 314 this->unloadModule(module); 315 delete module; 316 } 317 this->modules_.clear(); 318 } 319 320 void Core::unloadModule(ModuleInstance* module) 321 { 322 orxout(internal_info) << "Unloading module " << module->getLibraryName() << "..." << endl; 323 324 StaticInitializationManager::getInstance().unloadModule(module); 325 326 module->deleteAllStaticallyInitializedInstances(); 327 this->dynLibManager_->unload(module->getDynLib()); 328 module->setDynLib(NULL); 339 329 } 340 330 … … 344 334 345 335 // Any exception should trigger this, even in upgradeToGraphics (see its remarks) 346 Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics );336 Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics, true); 347 337 348 338 // Upgrade OGRE to receive a render window … … 385 375 // Create singletons associated with graphics (in other libraries) 386 376 orxout(internal_info) << "creating graphics scope:" << endl; 387 graphicsScope_ = new Scope<ScopeID::G raphics>();377 graphicsScope_ = new Scope<ScopeID::GRAPHICS>(); 388 378 389 379 unloader.Dismiss(); … … 392 382 } 393 383 394 void Core::unloadGraphics( )384 void Core::unloadGraphics(bool loadGraphicsManagerWithoutRenderer) 395 385 { 396 386 orxout(internal_info) << "unloading graphics in Core" << endl; 387 388 if (this->graphicsManager_) 389 this->graphicsManager_->unloadDebugOverlay(); 397 390 398 391 safeObjectDelete(&graphicsScope_); … … 403 396 // Load Ogre::Root again, but without the render system 404 397 try 405 { this->graphicsManager_ = new GraphicsManager(false); } 398 { 399 if (loadGraphicsManagerWithoutRenderer) 400 this->graphicsManager_ = new GraphicsManager(false); 401 } 406 402 catch (...) 407 403 { … … 414 410 bGraphicsLoaded_ = false; 415 411 GameMode::bShowsGraphics_s = false; 416 }417 418 //! Sets the language in the config-file back to the default.419 void Core::resetLanguage()420 {421 ResetConfigValue(language_);422 412 } 423 413 … … 470 460 void Core::preUpdate(const Clock& time) 471 461 { 472 // Update singletons before general ticking 473 ScopedSingletonManager::preUpdate<ScopeID::Root>(time); 462 // Update UpdateListeners before general ticking 463 for (ObjectList<UpdateListener>::iterator it = ObjectList<UpdateListener>::begin(); it != ObjectList<UpdateListener>::end(); ++it) 464 it->preUpdate(time); 474 465 if (this->bGraphicsLoaded_) 475 466 { … … 478 469 // Update GUI 479 470 this->guiManager_->preUpdate(time); 480 // Update singletons before general ticking481 ScopedSingletonManager::preUpdate<ScopeID::Graphics>(time);482 471 } 483 472 // Process console events and status line … … 490 479 void Core::postUpdate(const Clock& time) 491 480 { 492 // Update singletons just before rendering 493 ScopedSingletonManager::postUpdate<ScopeID::Root>(time); 481 // Update UpdateListeners just before rendering 482 for (ObjectList<UpdateListener>::iterator it = ObjectList<UpdateListener>::begin(); it != ObjectList<UpdateListener>::end(); ++it) 483 it->postUpdate(time); 494 484 if (this->bGraphicsLoaded_) 495 485 { 496 // Update singletons just before rendering497 ScopedSingletonManager::postUpdate<ScopeID::Graphics>(time);498 486 // Render (doesn't throw) 499 487 this->graphicsManager_->postUpdate(time); 500 488 } 501 489 } 502 503 void Core::updateLastLevelTimestamp()504 {505 ModifyConfigValue(lastLevelTimestamp_, set, static_cast<long long>(time(NULL)));506 }507 508 void Core::updateOgreConfigTimestamp()509 {510 ModifyConfigValue(ogreConfigTimestamp_, set, static_cast<long long>(time(NULL)));511 }512 513 514 RegisterAbstractClass(DevModeListener).inheritsFrom(Class(Listable));515 516 DevModeListener::DevModeListener()517 {518 RegisterObject(DevModeListener);519 }520 490 } -
code/trunk/src/libraries/core/Core.h
r9667 r10624 47 47 #include "util/DestructionHelper.h" 48 48 #include "util/Singleton.h" 49 #include " config/Configurable.h"49 #include "CoreConfig.h" 50 50 51 51 namespace orxonox 52 52 { 53 //! Informs about changes in the Development Mode.54 class DevModeListener : virtual public Listable55 {56 public:57 DevModeListener();58 virtual ~DevModeListener() {}59 virtual void devModeChanged(bool value) = 0;60 };61 62 53 /** 63 54 @brief … … 66 57 You should only create this singleton once because it destroys the identifiers! 67 58 */ 68 class _CoreExport Core : public Singleton<Core> , public Configurable59 class _CoreExport Core : public Singleton<Core> 69 60 { 70 61 friend class Singleton<Core>; 71 friend class Game;72 62 73 63 public: … … 86 76 void destroy(); 87 77 88 void setConfigValues(); 78 void preUpdate(const Clock& time); 79 void postUpdate(const Clock& time); 89 80 90 //! Returns the configured language. 91 const std::string& getLanguage() 92 { return this->language_; } 93 void resetLanguage(); 81 void loadGraphics(); 82 void unloadGraphics(bool loadGraphicsManagerWithoutRenderer = true); 94 83 95 void updateLastLevelTimestamp(); 96 inline long long getLastLevelTimestamp() const 97 { return this->lastLevelTimestamp_; } 84 void loadModules(); 85 void unloadModules(); 86 void loadModule(ModuleInstance* module); 87 void unloadModule(ModuleInstance* module); 98 88 99 void updateOgreConfigTimestamp(); 100 inline long long getOgreConfigTimestamp() const 101 { return this->ogreConfigTimestamp_; } 102 103 //! Developers bit. If returns false, some options are not available as to not confuse the normal user. 104 inline bool inDevMode(void) const 105 { return this->bDevMode_; } 89 inline CoreConfig* getConfig() const 90 { return this->config_; } 106 91 107 92 private: 108 93 Core(const Core&); //!< Don't use (undefined symbol) 109 94 110 void devModeChanged();111 void languageChanged();112 void initRandomNumberGenerator();113 114 void preUpdate(const Clock& time);115 void postUpdate(const Clock& time);116 117 void loadGraphics();118 void unloadGraphics();119 120 95 void setThreadAffinity(int limitToCPU); 121 96 122 PathConfig* pathConfig_; 123 DynLibManager* dynLibManager_; 124 SignalHandler* signalHandler_; 125 ConfigFileManager* configFileManager_; 126 Language* languageInstance_; 127 IOConsole* ioConsole_; 128 TclBind* tclBind_; 129 TclThreadManager* tclThreadManager_; 130 Scope<ScopeID::Root>* rootScope_; 97 ApplicationPaths* applicationPaths_; 98 ConfigurablePaths* configurablePaths_; 99 DynLibManager* dynLibManager_; 100 SignalHandler* signalHandler_; 101 ConfigFileManager* configFileManager_; 102 Language* languageInstance_; 103 Loader* loaderInstance_; 104 IOConsole* ioConsole_; 105 TclBind* tclBind_; 106 TclThreadManager* tclThreadManager_; 107 Scope<ScopeID::ROOT>* rootScope_; 131 108 // graphical 132 GraphicsManager* graphicsManager_; //!< Interface to OGRE 133 InputManager* inputManager_; //!< Interface to OIS 134 GUIManager* guiManager_; //!< Interface to GUI 135 Scope<ScopeID::Graphics>* graphicsScope_; 109 GraphicsManager* graphicsManager_; //!< Interface to OGRE 110 InputManager* inputManager_; //!< Interface to OIS 111 GUIManager* guiManager_; //!< Interface to GUI 112 Scope<ScopeID::GRAPHICS>* graphicsScope_; 113 bool bGraphicsLoaded_; 136 114 137 bool bGraphicsLoaded_;138 std::string language_; //!< The language139 bool bInitRandomNumberGenerator_; //!< If true, srand(time(0)) is called140 bool bStartIOConsole_; //!< Set to false if you don't want to use the IOConsole141 long long lastLevelTimestamp_; ///< Timestamp when the last level was started 142 long long ogreConfigTimestamp_; ///< Timestamp wehen the ogre config level was modified143 bool bDevMode_; //!< Developers bit. If set to false, some options are not available as to not confuse the normal user.115 CoreStaticInitializationHandler* staticInitHandler_; 116 PluginManager* pluginManager_; 117 ModuleInstance* rootModule_; 118 std::list<ModuleInstance*> modules_; 119 120 /// Helper object that stores the config values 121 CoreConfig* config_; 144 122 145 123 /// Helper object that executes the surrogate destructor destroy() 146 DestructionHelper<Core> destructionHelper_;124 DestructionHelper<Core> destructionHelper_; 147 125 148 static Core* singletonPtr_s;126 static Core* singletonPtr_s; 149 127 }; 150 128 } -
code/trunk/src/libraries/core/CoreIncludes.h
r10208 r10624 84 84 #include "object/ClassFactory.h" 85 85 #include "object/ObjectList.h" 86 #include "module/StaticallyInitializedInstance.h" 86 87 87 88 // resolve macro conflict on windows … … 126 127 */ 127 128 #define RegisterClassWithFactory(ClassName, FactoryInstance, bLoadable) \ 128 Identifier& _##ClassName##Identifier = orxonox::registerClass<ClassName>(#ClassName, FactoryInstance, bLoadable)129 orxonox::SI_I& _##ClassName##Identifier = (*new orxonox::SI_I(orxonox::registerClass<ClassName>(#ClassName, FactoryInstance, bLoadable))) 129 130 130 131 /** … … 133 134 */ 134 135 #define RegisterObject(ClassName) \ 135 if (ClassIdentifier<ClassName>::getIdentifier( #ClassName)->initializeObject(this)) \136 if (ClassIdentifier<ClassName>::getIdentifier()->initializeObject(this)) \ 136 137 return; \ 137 138 else \ … … 152 153 */ 153 154 template <class T> 154 inline Identifier ®isterClass(const std::string& name, ClassFactory<T>* factory, bool bLoadable = true)155 inline Identifier* registerClass(const std::string& name, ClassFactory<T>* factory, bool bLoadable = true) 155 156 { 156 157 return registerClass<T>(name, static_cast<Factory*>(factory), bLoadable); … … 164 165 */ 165 166 template <class T> 166 inline Identifier& registerClass(const std::string& name, Factory* factory, bool bLoadable = true) 167 { 168 orxout(verbose, context::misc::factory) << "Create entry for " << name << " in Factory." << endl; 169 Identifier* identifier = ClassIdentifier<T>::getIdentifier(name); 170 identifier->setFactory(factory); 171 identifier->setLoadable(bLoadable); 172 return *identifier; 167 inline Identifier* registerClass(const std::string& name, Factory* factory, bool bLoadable = true) 168 { 169 return new ClassIdentifier<T>(name, factory, bLoadable); 173 170 } 174 171 … … 211 208 return ClassIdentifier<T>::getIdentifier(); 212 209 } 210 211 212 213 214 /** 215 * The static initializer stores the parent classes of this identifier. The corresponding identifiers are later loaded. This prevents identifiers from 216 * being used before they are completely initialized. 217 */ 218 class _CoreExport StaticallyInitializedIdentifier : public StaticallyInitializedInstance 219 { 220 template <class T> 221 struct InheritsFromClass : public Identifier::InheritsFrom 222 { 223 virtual Identifier* getParent() const { return Class(T); } 224 }; 225 226 public: 227 StaticallyInitializedIdentifier(Identifier* identifier) 228 : StaticallyInitializedInstance(StaticInitialization::IDENTIFIER) 229 , identifier_(identifier) 230 {} 231 ~StaticallyInitializedIdentifier() { delete identifier_; } 232 233 virtual void load() 234 { 235 IdentifierManager::getInstance().addIdentifier(this->identifier_); 236 } 237 238 virtual void unload() 239 { 240 IdentifierManager::getInstance().removeIdentifier(this->identifier_); 241 } 242 243 inline Identifier& getIdentifier() 244 { return *this->identifier_; } 245 246 template <class T> 247 inline StaticallyInitializedIdentifier& inheritsFrom() 248 { this->identifier_->inheritsFrom(new InheritsFromClass<T>()); return *this; } 249 250 inline StaticallyInitializedIdentifier& virtualBase() 251 { this->identifier_->setVirtualBase(true); return *this; } 252 253 private: 254 Identifier* identifier_; 255 }; 256 257 typedef StaticallyInitializedIdentifier SI_I; 213 258 } 214 259 -
code/trunk/src/libraries/core/CorePrereqs.h
r9978 r10624 77 77 namespace orxonox 78 78 { 79 namespace ScopeID 80 { 81 typedef int Value; 82 83 //!A list of available scopes for the Scope template. 84 static const Value ROOT = 1; 85 static const Value GRAPHICS = 2; 86 } 87 88 namespace StaticInitialization 89 { 90 typedef int Type; 91 92 static const Type STATIC_INITIALIZATION_HANDLER = 1; 93 static const Type IDENTIFIER = 2; 94 static const Type SCOPED_SINGLETON_WRAPPER = 3; 95 static const Type COMMAND_LINE_ARGUMENT = 4; 96 static const Type CONSOLE_COMMAND = 5; 97 } 98 79 99 namespace XMLPort 80 100 { … … 123 143 T orxonox_cast(U*); 124 144 145 class ApplicationPaths; 125 146 class BaseObject; 126 147 template <class T> … … 143 164 class ConfigFileSection; 144 165 class Configurable; 166 class ConfigurablePaths; 145 167 class ConfigValueContainer; 146 168 class Context; 147 169 class Core; 170 class CoreConfig; 171 class CoreStaticInitializationHandler; 148 172 class Destroyable; 173 class DestroyLaterManager; 149 174 class DestructionListener; 150 175 class DynLib; … … 154 179 class Factory; 155 180 class Game; 181 class GameConfig; 156 182 class GameState; 157 183 struct GameStateInfo; … … 165 191 class Language; 166 192 class Listable; 193 class Loader; 167 194 class LuaFunctor; 168 195 class LuaState; 169 196 class MemoryArchive; 170 197 class MemoryArchiveFactory; 198 class ModuleInstance; 171 199 class Namespace; 172 200 class NamespaceNode; … … 182 210 class OrxonoxClass; 183 211 class OrxonoxInterface; 184 class PathConfig; 212 class Plugin; 213 class PluginManager; 214 class PluginReference; 185 215 struct ResourceInfo; 216 template <ScopeID::Value> 217 class Scope; 218 class ScopeManager; 219 class ScopedSingletonWrapper; 186 220 class SettingsConfigFile; 187 template <class T> 188 class SmartPtr; 221 class StaticallyInitializedInstance; 222 class StaticInitializationHandler; 223 class StaticInitializationManager; 224 template <class T> 225 class StrongPtr; 189 226 template <class T> 190 227 class SubclassIdentifier; … … 192 229 class Thread; 193 230 class ThreadPool; 231 class UpdateListener; 194 232 class ViewportEventListener; 195 233 template <class T> … … 210 248 class CommandEvaluation; 211 249 class ConsoleCommand; 250 class ConsoleCommandManager; 212 251 class Executor; 213 252 template <class T> -
code/trunk/src/libraries/core/GUIManager.cc
r10279 r10624 106 106 #include "GraphicsManager.h" 107 107 #include "LuaState.h" 108 #include " PathConfig.h"108 #include "ConfigurablePaths.h" 109 109 #include "Resource.h" 110 #include "command/ConsoleCommand .h"110 #include "command/ConsoleCommandIncludes.h" 111 111 #include "input/InputManager.h" 112 112 #include "input/InputState.h" … … 255 255 SetConsoleCommand("toggleGUI", &GUIManager::toggleGUI).defaultValue(1, false).defaultValue(2, false); 256 256 257 RegisterAbstractClass(GUIManager).inheritsFrom<WindowEventListener>(); 258 257 259 /** 258 260 @brief … … 329 331 // Create our own logger to specify the filepath 330 332 std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger()); 331 ceguiLogger->setLogFilename( PathConfig::getLogPathString() + "cegui.log");333 ceguiLogger->setLogFilename(ConfigurablePaths::getLogPathString() + "cegui.log"); 332 334 ceguiLogger->setLoggingLevel(static_cast<CEGUI::LoggingLevel>(this->outputLevelCeguiLog_)); 333 335 this->ceguiLogger_ = ceguiLogger.release(); … … 833 835 /*static*/ bool GUIManager::inDevMode() 834 836 { 835 return Core::getInstance(). inDevMode();837 return Core::getInstance().getConfig()->inDevMode(); 836 838 } 837 839 -
code/trunk/src/libraries/core/Game.cc
r9667 r10624 45 45 #include "util/SubString.h" 46 46 #include "Core.h" 47 #include "CoreIncludes.h" 48 #include "config/CommandLineParser.h" 49 #include "config/ConfigValueIncludes.h" 47 #include "commandline/CommandLineParser.h" 48 #include "GameConfig.h" 50 49 #include "GameMode.h" 51 50 #include "GameState.h" 52 51 #include "GraphicsManager.h" 53 52 #include "GUIManager.h" 54 #include "command/ConsoleCommand .h"53 #include "command/ConsoleCommandIncludes.h" 55 54 56 55 namespace orxonox … … 82 81 , bChangingState_(false) 83 82 , bAbort_(false) 83 , config_(NULL) 84 84 , destructionHelper_(this) 85 85 { … … 110 110 orxout(internal_info) << "creating Core object:" << endl; 111 111 this->core_ = new Core(cmdLine); 112 this->core_->loadModules(); 112 113 113 114 // Do this after the Core creation! 114 RegisterObject(Game); 115 this->setConfigValues(); 115 this->config_ = new GameConfig(); 116 116 117 117 // After the core has been created, we can safely instantiate the GameStates that don't require graphics … … 136 136 orxout(internal_status) << "destroying Game object..." << endl; 137 137 138 // Remove us from the object lists again to avoid problems when destroying them139 this->unregisterObject();140 141 138 assert(loadedStates_.size() <= 1); // Just empty root GameState 142 139 // Destroy all GameStates (shared_ptrs take care of actual destruction) … … 144 141 145 142 GameStateFactory::getFactories().clear(); 143 safeObjectDelete(&config_); 144 if (this->core_) 145 this->core_->unloadModules(); 146 146 safeObjectDelete(&core_); 147 147 safeObjectDelete(&gameClock_); 148 148 149 149 orxout(internal_status) << "finished destroying Game object..." << endl; 150 }151 152 void Game::setConfigValues()153 {154 SetConfigValue(statisticsRefreshCycle_, 250000)155 .description("Sets the time in microseconds interval at which average fps, etc. get updated.");156 SetConfigValue(statisticsAvgLength_, 1000000)157 .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");158 159 SetConfigValueExternal(fpsLimit_, "GraphicsSettings", "fpsLimit", 50)160 .description("Sets the desired frame rate (0 for no limit).");161 150 } 162 151 … … 229 218 // Limit frame rate 230 219 static bool hasVSync = GameMode::showsGraphics() && GraphicsManager::getInstance().hasVSyncEnabled(); // can be static since changes of VSync currently require a restart 231 if (this-> fpsLimit_> 0 && !hasVSync)220 if (this->config_->getFpsLimit() > 0 && !hasVSync) 232 221 this->updateFPSLimiter(); 233 222 } … … 311 300 this->statisticsTickTimes_.back().tickLength += (uint32_t)(currentRealTime - currentTime); 312 301 this->periodTickTime_ += (uint32_t)(currentRealTime - currentTime); 313 if (this->periodTime_ > this-> statisticsRefreshCycle_)302 if (this->periodTime_ > this->config_->getStatisticsRefreshCycle()) 314 303 { 315 304 std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin(); 316 305 assert(it != this->statisticsTickTimes_.end()); 317 int64_t lastTime = currentTime - this-> statisticsAvgLength_;306 int64_t lastTime = currentTime - this->config_->getStatisticsAvgLength(); 318 307 if (static_cast<int64_t>(it->tickTime) < lastTime) 319 308 { … … 333 322 this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f; 334 323 335 this->periodTime_ -= this-> statisticsRefreshCycle_;324 this->periodTime_ -= this->config_->getStatisticsRefreshCycle(); 336 325 } 337 326 } … … 339 328 void Game::updateFPSLimiter() 340 329 { 341 uint64_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / fpsLimit_);330 uint64_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / this->config_->getFpsLimit()); 342 331 uint64_t currentRealTime = gameClock_->getRealMicroseconds(); 343 332 while (currentRealTime < nextTime - minimumSleepTime_) … … 529 518 530 519 core_->loadGraphics(); 531 Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics );520 Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics, true); 532 521 533 522 // Construct all the GameStates that require graphics … … 550 539 } 551 540 552 void Game::unloadGraphics( )541 void Game::unloadGraphics(bool loadGraphicsManagerWithoutRenderer) 553 542 { 554 543 if (GameMode::showsGraphics()) … … 566 555 } 567 556 568 core_->unloadGraphics( );557 core_->unloadGraphics(loadGraphicsManagerWithoutRenderer); 569 558 } 570 559 } … … 587 576 588 577 // If state requires graphics, load it 589 Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics );578 Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics, true); 590 579 if (gameStateDeclarations_s[name].bGraphicsMode && !GameMode::showsGraphics()) 591 580 this->loadGraphics(); … … 623 612 } 624 613 // Check if graphics is still required 625 if (!bAbort_) 626 { 627 bool graphicsRequired = false; 628 for (unsigned i = 0; i < loadedStates_.size(); ++i) 629 graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode; 630 if (!graphicsRequired) 631 this->unloadGraphics(); 632 } 614 bool graphicsRequired = false; 615 for (unsigned i = 0; i < loadedStates_.size(); ++i) 616 graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode; 617 if (!graphicsRequired) 618 this->unloadGraphics(!this->bAbort_); // if abort is false, that means the game is still running while unloading graphics. in this case we load a graphics manager without renderer (to keep all necessary ogre instances alive) 633 619 this->bChangingState_ = false; 634 620 } -
code/trunk/src/libraries/core/Game.h
r9667 r10624 50 50 #include "util/DestructionHelper.h" 51 51 #include "util/Singleton.h" 52 #include "config/Configurable.h"53 52 54 53 /** … … 82 81 class _CoreExport Game 83 82 // tolua_end 84 : public Singleton<Game> , public Configurable83 : public Singleton<Game> 85 84 { // tolua_export 86 85 friend class Singleton<Game>; … … 96 95 /// Destructor that also executes when object fails to construct 97 96 void destroy(); 98 99 void setConfigValues();100 97 101 98 void setStateHierarchy(const std::string& str); … … 151 148 152 149 void loadGraphics(); 153 void unloadGraphics( );150 void unloadGraphics(bool loadGraphicsManagerWithoutRenderer = true); 154 151 155 152 void parseStates(std::vector<std::pair<std::string, int> >::const_iterator& it, shared_ptr<GameStateTreeNode> currentNode); … … 189 186 unsigned int minimumSleepTime_; 190 187 191 // config values 192 unsigned int statisticsRefreshCycle_; 193 unsigned int statisticsAvgLength_; 194 unsigned int fpsLimit_; 188 /// Helper object that stores the config values 189 GameConfig* config_; 195 190 196 191 /// Helper object that executes the surrogate destructor destroy() -
code/trunk/src/libraries/core/GraphicsManager.cc
r10295 r10624 59 59 #include "GUIManager.h" 60 60 #include "Loader.h" 61 #include "PathConfig.h" 61 #include "ApplicationPaths.h" 62 #include "ConfigurablePaths.h" 62 63 #include "ViewportEventListener.h" 63 64 #include "WindowEventListener.h" 64 65 #include "XMLFile.h" 65 #include "command/ConsoleCommand .h"66 #include "command/ConsoleCommandIncludes.h" 66 67 #include "input/InputManager.h" 67 68 … … 94 95 GraphicsManager* GraphicsManager::singletonPtr_s = 0; 95 96 97 RegisterAbstractClass(GraphicsManager).inheritsFrom<Configurable>(); 98 96 99 GraphicsManager::GraphicsManager(bool bLoadRenderer) 97 100 : ogreWindowEventListener_(new OgreWindowEventListener()) … … 111 114 112 115 // At first, add the root paths of the data directories as resource locations 113 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( PathConfig::getDataPathString(), "FileSystem");116 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(ConfigurablePaths::getDataPathString(), "FileSystem"); 114 117 // Load resources 115 118 resources_.reset(new XMLFile("DefaultResources.oxr")); 116 119 resources_->setLuaSupport(false); 117 Loader:: open(resources_.get(), ClassTreeMask(), false);120 Loader::getInstance().load(resources_.get(), ClassTreeMask(), false); 118 121 119 122 // Only for runs in the build directory (not installed) 120 if ( PathConfig::buildDirectoryRun())121 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( PathConfig::getExternalDataPathString(), "FileSystem");123 if (ApplicationPaths::buildDirectoryRun()) 124 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(ConfigurablePaths::getExternalDataPathString(), "FileSystem"); 122 125 123 126 extResources_.reset(new XMLFile("resources.oxr")); 124 127 extResources_->setLuaSupport(false); 125 Loader:: open(extResources_.get(), ClassTreeMask(), false);128 Loader::getInstance().load(extResources_.get(), ClassTreeMask(), false); 126 129 127 130 if (bLoadRenderer) … … 137 140 { 138 141 orxout(internal_status) << "destroying GraphicsManager..." << endl; 139 140 Loader::unload(debugOverlay_.get());141 142 142 143 Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow_, ogreWindowEventListener_); … … 147 148 148 149 // Undeclare the resources 149 Loader:: unload(resources_.get());150 Loader:: unload(extResources_.get());150 Loader::getInstance().unload(resources_.get()); 151 Loader::getInstance().unload(extResources_.get()); 151 152 152 153 safeObjectDelete(&ogreRoot_); … … 218 219 } 219 220 220 boost::filesystem::path ogreConfigFilepath( PathConfig::getConfigPath() / this->ogreConfigFile_);221 boost::filesystem::path ogreLogFilepath( PathConfig::getLogPath() / this->ogreLogFile_);221 boost::filesystem::path ogreConfigFilepath(ConfigurablePaths::getConfigPath() / this->ogreConfigFile_); 222 boost::filesystem::path ogreLogFilepath(ConfigurablePaths::getLogPath() / this->ogreLogFile_); 222 223 223 224 // create a new logManager … … 258 259 std::string pluginPath = specialConfig::ogrePluginsDirectory; 259 260 #ifdef DEPENDENCY_PACKAGE_ENABLE 260 if (! PathConfig::buildDirectoryRun())261 if (!ApplicationPaths::buildDirectoryRun()) 261 262 { 262 263 # if defined(ORXONOX_PLATFORM_WINDOWS) 263 pluginPath = PathConfig::getExecutablePathString();264 pluginPath = ApplicationPaths::getExecutablePathString(); 264 265 # elif defined(ORXONOX_PLATFORM_APPLE) 265 266 // TODO: Where are the plugins being installed to? 266 pluginPath = PathConfig::getExecutablePathString();267 pluginPath = ApplicationPaths::getExecutablePathString(); 267 268 # endif 268 269 } … … 279 280 orxout(internal_info) << "GraphicsManager: Configuring Renderer" << endl; 280 281 281 bool updatedConfig = Core::getInstance().get OgreConfigTimestamp() > Core::getInstance().getLastLevelTimestamp();282 bool updatedConfig = Core::getInstance().getConfig()->getOgreConfigTimestamp() > Core::getInstance().getConfig()->getLastLevelTimestamp(); 282 283 if (updatedConfig) 283 284 orxout(user_info)<< "Ogre config file has changed, but no level was started since then. Displaying config dialogue again to verify the changes." << endl; … … 288 289 ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue canceled."); 289 290 else 290 Core::getInstance(). updateOgreConfigTimestamp();291 Core::getInstance().getConfig()->updateOgreConfigTimestamp(); 291 292 } 292 293 … … 328 329 orxout(internal_info) << "Loading Debug Overlay..." << endl; 329 330 debugOverlay_.reset(new XMLFile("debug.oxo")); 330 Loader::open(debugOverlay_.get(), ClassTreeMask(), false); 331 Loader::getInstance().load(debugOverlay_.get(), ClassTreeMask(), false); 332 } 333 334 void GraphicsManager::unloadDebugOverlay() 335 { 336 Loader::getInstance().unload(debugOverlay_.get()); 331 337 } 332 338 … … 514 520 GraphicsManager::getInstance().getRenderWindow()->setFullscreen(fullscreen, width, height); 515 521 this->ogreRoot_->saveConfig(); 516 Core::getInstance(). updateOgreConfigTimestamp();522 Core::getInstance().getConfig()->updateOgreConfigTimestamp(); 517 523 // Also reload the input devices 518 524 InputManager::getInstance().reload(); … … 532 538 //this->ogreRoot_->getRenderSystem()->reinitialise(); // can't use this that easily, because it recreates the render window, invalidating renderWindow_ 533 539 this->ogreRoot_->saveConfig(); 534 Core::getInstance(). updateOgreConfigTimestamp();540 Core::getInstance().getConfig()->updateOgreConfigTimestamp(); 535 541 } 536 542 … … 548 554 //this->ogreRoot_->getRenderSystem()->reinitialise(); // can't use this that easily, because it recreates the render window, invalidating renderWindow_ 549 555 this->ogreRoot_->saveConfig(); 550 Core::getInstance(). updateOgreConfigTimestamp();556 Core::getInstance().getConfig()->updateOgreConfigTimestamp(); 551 557 } 552 558 … … 557 563 { 558 564 assert(this->renderWindow_); 559 this->renderWindow_->writeContentsToTimestampedFile( PathConfig::getLogPathString() + "screenShot_", ".png");565 this->renderWindow_->writeContentsToTimestampedFile(ConfigurablePaths::getLogPathString() + "screenShot_", ".png"); 560 566 } 561 567 } -
code/trunk/src/libraries/core/GraphicsManager.h
r9675 r10624 95 95 void upgradeToGraphics(); 96 96 void loadDebugOverlay(); 97 void unloadDebugOverlay(); 97 98 bool rendererLoaded() const { return renderWindow_ != NULL; } 98 99 -
code/trunk/src/libraries/core/Language.cc
r8858 r10624 37 37 #include "util/Output.h" 38 38 #include "util/StringUtils.h" 39 #include "Core.h" 40 #include "PathConfig.h" 39 #include "ConfigurablePaths.h" 41 40 42 41 namespace orxonox … … 203 202 orxout(internal_info, context::language) << "Read default language file." << endl; 204 203 205 const std::string& filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);204 const std::string& filepath = ConfigurablePaths::getConfigPathString() + getFilename(this->defaultLanguage_); 206 205 207 206 // This creates the file if it's not existing … … 247 246 /** 248 247 @brief Reads the language file of the configured language and assigns the localisation to the corresponding LanguageEntry object. 249 */ 250 void Language::readTranslatedLanguageFile() 251 { 252 orxout(internal_info, context::language) << "Read translated language file (" << Core::getInstance().getLanguage() << ")." << endl; 253 254 const std::string& filepath = PathConfig::getConfigPathString() + getFilename(Core::getInstance().getLanguage()); 248 @return Returns false if the language file couldn't be found. 249 */ 250 bool Language::readTranslatedLanguageFile(const std::string& language) 251 { 252 orxout(internal_info, context::language) << "Read translated language file (" << language << ")." << endl; 253 254 const std::string& filepath = ConfigurablePaths::getConfigPathString() + getFilename(language); 255 255 256 256 // Open the file … … 261 261 { 262 262 orxout(internal_error, context::language) << "An error occurred in Language.cc:" << endl; 263 orxout(internal_error, context::language) << "Couldn't open file " << getFilename(Core::getInstance().getLanguage()) << " to read the translated language entries!" << endl; 264 Core::getInstance().resetLanguage(); 265 orxout(internal_info, context::language) << "Reset language to " << this->defaultLanguage_ << '.' << endl; 266 return; 263 orxout(internal_error, context::language) << "Couldn't open file " << getFilename(language) << " to read the translated language entries!" << endl; 264 return false; 267 265 } 268 266 … … 291 289 else 292 290 { 293 orxout(internal_warning, context::language) << "Invalid language entry \"" << lineString << "\" in " << getFilename( Core::getInstance().getLanguage()) << endl;291 orxout(internal_warning, context::language) << "Invalid language entry \"" << lineString << "\" in " << getFilename(language) << endl; 294 292 } 295 293 } … … 297 295 298 296 file.close(); 297 return true; 299 298 } 300 299 … … 306 305 orxout(verbose, context::language) << "Write default language file." << endl; 307 306 308 const std::string& filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);307 const std::string& filepath = ConfigurablePaths::getConfigPathString() + getFilename(this->defaultLanguage_); 309 308 310 309 // Open the file -
code/trunk/src/libraries/core/Language.h
r8858 r10624 161 161 { 162 162 friend class Singleton<Language>; 163 friend class Core ;163 friend class CoreConfig; 164 164 165 165 public: … … 174 174 175 175 void readDefaultLanguageFile(); 176 void readTranslatedLanguageFile();176 bool readTranslatedLanguageFile(const std::string& language); 177 177 void writeDefaultLanguageFile() const; 178 178 static std::string getFilename(const std::string& language); -
code/trunk/src/libraries/core/Loader.cc
r10278 r10624 48 48 namespace orxonox 49 49 { 50 std::vector<std::pair<const XMLFile*, ClassTreeMask> > Loader::files_s; 51 ClassTreeMask Loader::currentMask_s; 52 53 bool Loader::open(const XMLFile* file, const ClassTreeMask& mask, bool bVerbose) 54 { 55 Loader::add(file, mask); 56 return Loader::load(file, mask, bVerbose); 57 } 58 59 void Loader::close() 60 { 61 Loader::unload(); 62 Loader::files_s.clear(); 63 } 64 65 void Loader::close(const XMLFile* file) 66 { 67 Loader::unload(file); 68 Loader::remove(file); 69 } 70 71 void Loader::add(const XMLFile* file, const ClassTreeMask& mask) 72 { 73 if (!file) 74 return; 75 Loader::files_s.insert(Loader::files_s.end(), std::pair<const XMLFile*, ClassTreeMask>(file, mask)); 76 } 77 78 void Loader::remove(const XMLFile* file) 79 { 80 if (!file) 81 return; 82 for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it) 83 { 84 if (it->first == file) 85 { 86 Loader::files_s.erase(it); 87 break; 88 } 89 } 90 } 91 92 /** 93 @brief 94 Loads all opened files, while conforming to the restrictions given by the input ClassTreeMask. 95 @param mask 96 A ClassTreeMask, which defines which types of classes are loaded and which aren't. 97 @param bVerbose 98 Whether the loader is verbose (prints its progress in a low output level) or not. 99 @return 100 Returns true if successful. 101 */ 102 bool Loader::load(const ClassTreeMask& mask, bool bVerbose) 103 { 104 bool success = true; 105 for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it) 106 if (!Loader::load(it->first, it->second * mask, bVerbose)) 107 success = false; 108 109 return success; 110 } 111 112 void Loader::unload(const ClassTreeMask& mask) 113 { 114 for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ) 115 { 116 if (mask.isIncluded(it->getIdentifier())) 117 (it++)->destroy(); 118 else 119 ++it; 120 } 121 } 122 123 /** 124 @brief 125 Reloads all opened files, while conforming to the restrictions given by the input ClassTreeMask. 126 @param mask 127 A ClassTreeMask, which defines which types of classes are reloaded and which aren't. 128 @param bVerbose 129 Whether the loader is verbose (prints its progress in a low output level) or not. 130 @return 131 Returns true if successful. 132 */ 133 bool Loader::reload(const ClassTreeMask& mask, bool bVerbose) 134 { 135 Loader::unload(mask); 136 return Loader::load(mask, bVerbose); 137 } 50 Loader* Loader::singletonPtr_s = 0; 138 51 139 52 /** … … 156 69 return false; 157 70 158 Loader::currentMask_s= file->getMask() * mask;71 this->currentMask_ = file->getMask() * mask; 159 72 160 73 std::string xmlInput; … … 189 102 // start of the program. 190 103 // Assumption: the LevelInfo tag does not use Lua scripting 191 xmlInput = removeLuaTags(xmlInput);104 xmlInput = Loader::removeLuaTags(xmlInput); 192 105 } 193 106 } … … 198 111 { 199 112 orxout(user_info) << "Start loading " << file->getFilename() << "..." << endl; 200 orxout(internal_info, context::loader) << "Mask: " << Loader::currentMask_s<< endl;113 orxout(internal_info, context::loader) << "Mask: " << this->currentMask_ << endl; 201 114 } 202 115 else 203 116 { 204 117 orxout(verbose, context::loader) << "Start loading " << file->getFilename() << "..." << endl; 205 orxout(verbose_more, context::loader) << "Mask: " << Loader::currentMask_s<< endl;118 orxout(verbose_more, context::loader) << "Mask: " << this->currentMask_ << endl; 206 119 } 207 120 … … 220 133 rootNamespace->setLoaderIndentation(" "); 221 134 rootNamespace->setFile(file); 222 rootNamespace->setNamespace(rootNamespace);223 135 rootNamespace->setRoot(true); 224 136 rootNamespace->XMLPort(rootElement, XMLPort::LoadObject); … … 303 215 ++it; 304 216 } 305 }306 307 /**308 @brief309 Reloads the input file, while conforming to the restrictions given by the input ClassTreeMask.310 @param file311 The file to be reloaded.312 @param mask313 A ClassTreeMask, which defines which types of classes are reloaded and which aren't.314 @param bVerbose315 Whether the loader is verbose (prints its progress in a low output level) or not.316 @return317 Returns true if successful.318 */319 bool Loader::reload(const XMLFile* file, const ClassTreeMask& mask, bool bVerbose)320 {321 Loader::unload(file, mask);322 return Loader::load(file, mask, bVerbose);323 217 } 324 218 -
code/trunk/src/libraries/core/Loader.h
r8858 r10624 44 44 #include <map> 45 45 #include <vector> 46 47 #include "util/Singleton.h" 46 48 #include "ClassTreeMask.h" 47 49 48 50 namespace orxonox 49 51 { 50 class _CoreExport Loader 52 class _CoreExport Loader : public Singleton<Loader> 51 53 { 54 friend class Singleton<Loader>; 55 52 56 public: 53 static bool open(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), bool bVerbose = true); 54 static void close(); 55 static void close(const XMLFile* file); 56 57 static void add(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask()); 58 static void remove(const XMLFile* file); 59 60 static bool load(const ClassTreeMask& mask = ClassTreeMask(), bool bVerbose = true); 61 static void unload(const ClassTreeMask& mask = ClassTreeMask()); 62 static bool reload(const ClassTreeMask& mask = ClassTreeMask(), bool bVerbose = true); 63 64 static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), 65 bool bVerbose = true, bool bRemoveLuaTags = false); 66 static void unload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask()); 67 static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), bool bVerbose = true); 57 bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), 58 bool bVerbose = true, bool bRemoveLuaTags = false); 59 void unload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask()); 68 60 69 61 static std::string replaceLuaTags(const std::string& text); 70 62 static std::string removeLuaTags(const std::string& text); 71 63 72 static ClassTreeMask currentMask_s;64 ClassTreeMask currentMask_; 73 65 74 66 private: 75 67 static bool getLuaTags(const std::string& text, std::map<size_t, bool>& luaTags); 76 68 77 static std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_s; 69 std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_; 70 71 static Loader* singletonPtr_s; 78 72 }; 79 73 } -
code/trunk/src/libraries/core/Namespace.cc
r10298 r10624 47 47 RegisterObject(Namespace); 48 48 49 this->setNamespace( SmartPtr<Namespace>(this, false));49 this->setNamespace(WeakPtr<Namespace>(this)); // store a weak-pointer to itself (a strong-pointer would create a recursive dependency) 50 50 } 51 51 … … 105 105 void Namespace::loadObjects(BaseObject* object) 106 106 { 107 object->setNamespace(this);108 107 } 109 108 -
code/trunk/src/libraries/core/ViewportEventListener.cc
r9667 r10624 32 32 namespace orxonox 33 33 { 34 RegisterAbstractClass(ViewportEventListener).inheritsFrom (Class(Listable));34 RegisterAbstractClass(ViewportEventListener).inheritsFrom<Listable>(); 35 35 36 36 ViewportEventListener::ViewportEventListener() -
code/trunk/src/libraries/core/WindowEventListener.cc
r9667 r10624 35 35 unsigned int WindowEventListener::windowHeight_s = 0; 36 36 37 RegisterAbstractClass(WindowEventListener).inheritsFrom (Class(Listable));37 RegisterAbstractClass(WindowEventListener).inheritsFrom<Listable>(); 38 38 39 39 WindowEventListener::WindowEventListener() -
code/trunk/src/libraries/core/XMLNameListener.cc
r9667 r10624 32 32 namespace orxonox 33 33 { 34 RegisterAbstractClass(XMLNameListener).inheritsFrom (Class(Listable));34 RegisterAbstractClass(XMLNameListener).inheritsFrom<Listable>(); 35 35 36 36 XMLNameListener::XMLNameListener() -
code/trunk/src/libraries/core/XMLPort.cc
r9667 r10624 40 40 bool XMLPortObjectContainer::identifierIsIncludedInLoaderMask(const Identifier* identifier) 41 41 { 42 return ((!this->bApplyLoaderMask_) || identifier->isA(ClassIdentifier<Namespace>::getIdentifier()) || Loader:: currentMask_s.isIncluded(identifier));42 return ((!this->bApplyLoaderMask_) || identifier->isA(ClassIdentifier<Namespace>::getIdentifier()) || Loader::getInstance().currentMask_.isIncluded(identifier)); 43 43 } 44 44 -
code/trunk/src/libraries/core/class/Identifiable.cc
r9667 r10624 41 41 namespace orxonox 42 42 { 43 RegisterClassNoArgs(Identifiable) ;43 RegisterClassNoArgs(Identifiable).virtualBase(); 44 44 45 45 /** -
code/trunk/src/libraries/core/class/Identifier.cc
r9667 r10624 44 44 namespace orxonox 45 45 { 46 bool Identifier::initConfigValues_s = true; 47 46 48 // ############################### 47 49 // ### Identifier ### … … 50 52 @brief Constructor: No factory, no object created, new ObjectList and a unique networkID. 51 53 */ 52 Identifier::Identifier() 53 : classID_(IdentifierManager::getInstance().getUniqueClassId()) 54 { 55 this->factory_ = 0; 54 Identifier::Identifier(const std::string& name, Factory* factory, bool bLoadable) 55 { 56 orxout(verbose, context::identifier) << "Create identifier for " << name << endl; 57 58 static unsigned int classIDCounter = 0; 59 60 this->classID_ = classIDCounter++; 61 this->name_ = name; 62 this->factory_ = factory; 63 this->bLoadable_ = bLoadable; 56 64 this->bInitialized_ = false; 57 this->b Loadable_ = false;65 this->bIsVirtualBase_ = false; 58 66 59 67 this->bHasConfigValues_ = false; … … 71 79 delete this->factory_; 72 80 81 for (std::list<const InheritsFrom*>::const_iterator it = this->manualDirectParents_.begin(); it != this->manualDirectParents_.end(); ++it) 82 delete (*it); 83 84 // erase this Identifier from all related identifiers 85 for (std::list<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it) 86 const_cast<Identifier*>(*it)->children_.erase(this); 87 for (std::list<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it) 88 const_cast<Identifier*>(*it)->directChildren_.erase(this); 89 for (std::set<const Identifier*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it) 90 const_cast<Identifier*>(*it)->parents_.remove(this); 91 for (std::set<const Identifier*>::const_iterator it = this->directChildren_.begin(); it != this->directChildren_.end(); ++it) 92 const_cast<Identifier*>(*it)->directParents_.remove(this); 93 73 94 for (std::map<std::string, ConfigValueContainer*>::iterator it = this->configValues_.begin(); it != this->configValues_.end(); ++it) 74 95 delete (it->second); … … 77 98 for (std::map<std::string, XMLPortObjectContainer*>::iterator it = this->xmlportObjectContainers_.begin(); it != this->xmlportObjectContainers_.end(); ++it) 78 99 delete (it->second); 79 }80 81 /**82 @brief Sets the name of the class.83 */84 void Identifier::setName(const std::string& name)85 {86 if (name != this->name_)87 {88 this->name_ = name;89 IdentifierManager::getInstance().addIdentifierToLookupMaps(this);90 }91 }92 93 void Identifier::setFactory(Factory* factory)94 {95 if (this->factory_)96 delete this->factory_;97 98 this->factory_ = factory;99 100 } 100 101 … … 126 127 { 127 128 this->networkID_ = id; 128 IdentifierManager::getInstance().addIdentifier ToLookupMaps(this);129 IdentifierManager::getInstance().addIdentifier(this); // add with new id 129 130 } 130 131 … … 132 133 * @brief Used to define the direct parents of an Identifier of an abstract class. 133 134 */ 134 Identifier& Identifier::inheritsFrom(I dentifier* directParent)135 { 136 if (this-> parents_.empty())137 this-> directParents_.insert(directParent);138 else 139 orxout(internal_error) << "Trying to add " << directParent->getName() << " as adirect parent of " << this->getName() << " after the latter was already initialized" << endl;135 Identifier& Identifier::inheritsFrom(InheritsFrom* directParent) 136 { 137 if (this->directParents_.empty()) 138 this->manualDirectParents_.push_back(directParent); 139 else 140 orxout(internal_error) << "Trying to manually add direct parent of " << this->getName() << " after the latter was already initialized" << endl; 140 141 141 142 return *this; … … 144 145 /** 145 146 * @brief Initializes the parents of this Identifier while creating the class hierarchy. 146 * @param i dentifiers All identifiers that were used to create an instance of this class (includingthis identifier itself)147 */ 148 void Identifier::initializeParents(const std:: set<const Identifier*>& identifiers)147 * @param initializationTrace All identifiers that were recorded while creating an instance of this class (including nested classes and this identifier itself) 148 */ 149 void Identifier::initializeParents(const std::list<const Identifier*>& initializationTrace) 149 150 { 150 151 if (!IdentifierManager::getInstance().isCreatingHierarchy()) … … 154 155 } 155 156 156 for (std::set<const Identifier*>::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it) 157 if (*it != this) 158 this->parents_.insert(*it); 159 } 160 161 /** 162 * @brief Initializes the direct parents of this Identifier while creating the class hierarchy. This is only intended for abstract classes. 163 */ 164 void Identifier::initializeDirectParentsOfAbstractClass() 157 if (this->directParents_.empty()) 158 { 159 for (std::list<const Identifier*>::const_iterator it = initializationTrace.begin(); it != initializationTrace.end(); ++it) 160 if (*it != this) 161 this->parents_.push_back(*it); 162 } 163 else 164 orxout(internal_error) << "Trying to add parents to " << this->getName() << " after it was already initialized with manual calls to inheritsFrom<Class>()." << endl; 165 } 166 167 /** 168 * @brief Finishes the initialization of this Identifier after creating the class hierarchy by wiring the (direct) parent/child references correctly. 169 */ 170 void Identifier::finishInitialization() 165 171 { 166 172 if (!IdentifierManager::getInstance().isCreatingHierarchy()) 167 173 { 168 orxout(internal_warning) << "Identifier:: initializeDirectParentsOfAbstractClass() created outside of class hierarchy creation" << endl;174 orxout(internal_warning) << "Identifier::finishInitialization() created outside of class hierarchy creation" << endl; 169 175 return; 170 176 } 171 177 172 // only Identifiable is allowed to have no parents (even tough it's currently not abstract) 173 if (this->directParents_.empty() && !this->isExactlyA(Class(Identifiable))) 174 { 175 orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeidName() << " is marked as abstract but has no direct parents defined" << endl; 178 if (this->isInitialized()) 179 return; 180 181 if (!this->parents_.empty()) 182 { 183 // parents defined -> this class was initialized by creating a sample instance and recording the trace of identifiers 184 185 // initialize all parents 186 for (std::list<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it) 187 const_cast<Identifier*>(*it)->finishInitialization(); // initialize parent 188 189 // parents of parents are no direct parents of this identifier 190 this->directParents_ = this->parents_; 191 for (std::list<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent) 192 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 193 this->directParents_.remove(*it_parent_parent); 194 195 this->verifyIdentifierTrace(); 196 } 197 else if (!this->manualDirectParents_.empty()) 198 { 199 // no parents defined -> this class was manually initialized by calling inheritsFrom<Class>() 200 201 // initialize all direct parents 202 for (std::list<const InheritsFrom*>::const_iterator it = this->manualDirectParents_.begin(); it != this->manualDirectParents_.end(); ++it) 203 { 204 Identifier* directParent = (*it)->getParent(); 205 this->directParents_.push_back(directParent); 206 directParent->finishInitialization(); // initialize parent 207 } 208 209 // direct parents and their parents are also parents of this identifier (but only add them once) 210 for (std::list<const Identifier*>::const_iterator it_parent = this->directParents_.begin(); it_parent != this->directParents_.end(); ++it_parent) 211 { 212 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 213 this->addIfNotExists(this->parents_, *it_parent_parent); 214 this->addIfNotExists(this->parents_, *it_parent); 215 } 216 } 217 else if (!this->isExactlyA(Class(Identifiable))) 218 { 219 // only Identifiable is allowed to have no parents (even tough it's currently not abstract) 220 orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeInfo().name() << " is marked as abstract but has no direct parents defined" << endl; 176 221 orxout(internal_error) << " If this class is not abstract, use RegisterClass(ThisClass);" << endl; 177 222 orxout(internal_error) << " If this class is abstract, use RegisterAbstractClass(ThisClass).inheritsFrom(Class(BaseClass));" << endl; 178 223 } 179 }180 181 /**182 * @brief Finishes the initialization of this Identifier after creating the class hierarchy by wiring the (direct) parent/child references correctly.183 */184 void Identifier::finishInitialization()185 {186 if (!IdentifierManager::getInstance().isCreatingHierarchy())187 {188 orxout(internal_warning) << "Identifier::finishInitialization() created outside of class hierarchy creation" << endl;189 return;190 }191 192 if (this->isInitialized())193 return;194 195 // if no direct parents were defined, initialize them with the set of all parents196 if (this->directParents_.empty())197 this->directParents_ = this->parents_;198 199 // initialize all parents before continuing to initialize this identifier200 for (std::set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)201 {202 Identifier* directParent = const_cast<Identifier*>(*it);203 directParent->finishInitialization(); // initialize parent204 this->parents_.insert(directParent); // direct parent is also a parent205 this->parents_.insert(directParent->parents_.begin(), directParent->parents_.end()); // parents of direct parent are also parents206 }207 208 // parents of parents are no direct parents of this identifier209 for (std::set<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent)210 for (std::set<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent)211 this->directParents_.erase(*it_parent_parent);212 224 213 225 // tell all parents that this identifier is a child 214 for (std:: set<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it)226 for (std::list<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it) 215 227 const_cast<Identifier*>(*it)->children_.insert(this); 216 228 217 229 // tell all direct parents that this identifier is a direct child 218 for (std:: set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)230 for (std::list<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it) 219 231 { 220 232 const_cast<Identifier*>(*it)->directChildren_.insert(this); … … 228 240 229 241 /** 242 * Resets all information about the class hierarchy. The identifier is considered uninitialized afterwards. 243 */ 244 void Identifier::reset() 245 { 246 this->directParents_.clear(); 247 this->parents_.clear(); 248 this->directChildren_.clear(); 249 this->children_.clear(); 250 this->bInitialized_ = false; 251 } 252 253 /** 254 * Verifies if the recorded trace of parent identifiers matches the expected trace according to the class hierarchy. If it doesn't match, the class 255 * hierarchy is likely wrong, e.g. due to wrong inheritsFrom<>() definitions in abstract classes. 256 */ 257 void Identifier::verifyIdentifierTrace() const 258 { 259 260 std::list<const Identifier*> expectedIdentifierTrace; 261 262 // if any parent class is virtual, it will be instantiated first, so we need to add them first. 263 for (std::list<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent) 264 { 265 if ((*it_parent)->isVirtualBase()) 266 { 267 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 268 this->addIfNotExists(expectedIdentifierTrace, *it_parent_parent); 269 this->addIfNotExists(expectedIdentifierTrace, *it_parent); 270 } 271 } 272 273 // now all direct parents get created recursively. already added identifiers (e.g. virtual base classes) are not added again. 274 for (std::list<const Identifier*>::const_iterator it_parent = this->directParents_.begin(); it_parent != this->directParents_.end(); ++it_parent) 275 { 276 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 277 this->addIfNotExists(expectedIdentifierTrace, *it_parent_parent); 278 this->addIfNotExists(expectedIdentifierTrace, *it_parent); 279 } 280 281 // check if the expected trace matches the actual trace (which was defined by creating a sample instance) 282 if (expectedIdentifierTrace != this->parents_) 283 { 284 orxout(internal_warning) << this->getName() << " has an unexpected initialization trace:" << endl; 285 286 orxout(internal_warning) << " Actual trace (after creating a sample instance):" << endl << " "; 287 for (std::list<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent) 288 orxout(internal_warning) << " " << (*it_parent)->getName(); 289 orxout(internal_warning) << endl; 290 291 orxout(internal_warning) << " Expected trace (according to class hierarchy definitions):" << endl << " "; 292 for (std::list<const Identifier*>::const_iterator it_parent = expectedIdentifierTrace.begin(); it_parent != expectedIdentifierTrace.end(); ++it_parent) 293 orxout(internal_warning) << " " << (*it_parent)->getName(); 294 orxout(internal_warning) << endl; 295 296 orxout(internal_warning) << " Direct parents (according to class hierarchy definitions):" << endl << " "; 297 for (std::list<const Identifier*>::const_iterator it_parent = this->directParents_.begin(); it_parent != this->directParents_.end(); ++it_parent) 298 orxout(internal_warning) << " " << (*it_parent)->getName(); 299 orxout(internal_warning) << endl; 300 } 301 } 302 303 /** 304 * Adds @param identifierToAdd to @param list if this identifier is not already contained in the list. 305 */ 306 void Identifier::addIfNotExists(std::list<const Identifier*>& list, const Identifier* identifierToAdd) const 307 { 308 if (std::find(list.begin(), list.end(), identifierToAdd) == list.end()) 309 list.push_back(identifierToAdd); 310 } 311 312 /** 230 313 @brief Returns true, if the Identifier is at least of the given type. 231 314 @param identifier The identifier to compare with … … 233 316 bool Identifier::isA(const Identifier* identifier) const 234 317 { 235 return (identifier == this || (this-> parents_.find(identifier) != this->parents_.end()));318 return (identifier == this || (this->isChildOf(identifier))); 236 319 } 237 320 … … 251 334 bool Identifier::isChildOf(const Identifier* identifier) const 252 335 { 253 return ( this->parents_.find(identifier) != this->parents_.end());336 return (std::find(this->parents_.begin(), this->parents_.end(), identifier) != this->parents_.end()); 254 337 } 255 338 … … 260 343 bool Identifier::isDirectChildOf(const Identifier* identifier) const 261 344 { 262 return ( this->directParents_.find(identifier) != this->directParents_.end());345 return (std::find(this->directParents_.begin(), this->directParents_.end(), identifier) != this->directParents_.end()); 263 346 } 264 347 -
code/trunk/src/libraries/core/class/Identifier.h
r9667 r10624 80 80 #include <typeinfo> 81 81 #include <loki/TypeTraits.h> 82 #include <boost/static_assert.hpp> 83 #include <boost/type_traits/is_base_of.hpp> 82 84 83 85 #include "util/Output.h" 86 #include "util/OrxAssert.h" 84 87 #include "core/object/ObjectList.h" 85 88 #include "core/object/Listable.h" … … 109 112 { 110 113 public: 111 Identifier(); 114 struct InheritsFrom //! helper class to manually define inheritance 115 { 116 virtual ~InheritsFrom() {} 117 virtual Identifier* getParent() const = 0; 118 }; 119 120 public: 121 Identifier(const std::string& name, Factory* factory, bool bLoadable); 112 122 Identifier(const Identifier& identifier); // don't copy 113 123 virtual ~Identifier(); … … 115 125 /// Returns the name of the class the Identifier belongs to. 116 126 inline const std::string& getName() const { return this->name_; } 117 void setName(const std::string& name); 118 119 /// Returns the name of the class as it is returned by typeid(T).name() 120 virtual const std::string& getTypeidName() = 0; 127 128 /// Returns the type_info of the class as it is returned by typeid(T) 129 virtual const std::type_info& getTypeInfo() = 0; 121 130 122 131 /// Returns the network ID to identify a class through the network. … … 127 136 ORX_FORCEINLINE unsigned int getClassID() const { return this->classID_; } 128 137 129 /// Sets the Factory.130 void setFactory(Factory* factory);131 138 /// Returns true if the Identifier has a Factory. 132 139 inline bool hasFactory() const { return (this->factory_ != 0); } … … 136 143 /// Returns true if the class can be loaded through XML. 137 144 inline bool isLoadable() const { return this->bLoadable_; } 138 /// Set the class to be loadable through XML or not. 139 inline void setLoadable(bool bLoadable) { this->bLoadable_ = bLoadable; } 145 146 /// Returns true if child classes should inherit virtually from this class. 147 inline bool isVirtualBase() const { return this->bIsVirtualBase_; } 148 /// Defines if child classes should inherit virtually from this class. 149 inline void setVirtualBase(bool bIsVirtualBase) { this->bIsVirtualBase_ = bIsVirtualBase; } 140 150 141 151 /// Returns true if the Identifier was completely initialized. 142 152 inline bool isInitialized() const { return this->bInitialized_; } 153 154 virtual void destroyObjects() = 0; 155 156 virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const = 0; 157 158 static bool initConfigValues_s; // TODO: this is a hack - remove it as soon as possible 143 159 144 160 … … 146 162 ////// Class Hierarchy ////// 147 163 ///////////////////////////// 148 Identifier& inheritsFrom(Identifier* directParent); 149 150 void initializeParents(const std::set<const Identifier*>& identifiers); 151 void initializeDirectParentsOfAbstractClass(); 164 Identifier& inheritsFrom(InheritsFrom* directParent); 165 166 void initializeParents(const std::list<const Identifier*>& initializationTrace); 152 167 void finishInitialization(); 168 void reset(); 153 169 154 170 bool isA(const Identifier* identifier) const; … … 159 175 bool isDirectParentOf(const Identifier* identifier) const; 160 176 177 /// Returns the direct parents of the class the Identifier belongs to. 178 inline const std::list<const Identifier*>& getDirectParents() const { return this->directParents_; } 161 179 /// Returns the parents of the class the Identifier belongs to. 162 inline const std::set<const Identifier*>& getParents() const { return this->parents_; } 163 /// Returns the begin-iterator of the parents-list. 164 inline std::set<const Identifier*>::const_iterator getParentsBegin() const { return this->parents_.begin(); } 165 /// Returns the end-iterator of the parents-list. 166 inline std::set<const Identifier*>::const_iterator getParentsEnd() const { return this->parents_.end(); } 167 180 inline const std::list<const Identifier*>& getParents() const { return this->parents_; } 181 182 /// Returns the direct children the class the Identifier belongs to. 183 inline const std::set<const Identifier*>& getDirectChildren() const { return this->directChildren_; } 168 184 /// Returns the children of the class the Identifier belongs to. 169 185 inline const std::set<const Identifier*>& getChildren() const { return this->children_; } 170 /// Returns the begin-iterator of the children-list.171 inline std::set<const Identifier*>::const_iterator getChildrenBegin() const { return this->children_.begin(); }172 /// Returns the end-iterator of the children-list.173 inline std::set<const Identifier*>::const_iterator getChildrenEnd() const { return this->children_.end(); }174 175 /// Returns the direct parents of the class the Identifier belongs to.176 inline const std::set<const Identifier*>& getDirectParents() const { return this->directParents_; }177 /// Returns the begin-iterator of the direct-parents-list.178 inline std::set<const Identifier*>::const_iterator getDirectParentsBegin() const { return this->directParents_.begin(); }179 /// Returns the end-iterator of the direct-parents-list.180 inline std::set<const Identifier*>::const_iterator getDirectParentsEnd() const { return this->directParents_.end(); }181 182 /// Returns the direct children the class the Identifier belongs to.183 inline const std::set<const Identifier*>& getDirectChildren() const { return this->directChildren_; }184 /// Returns the begin-iterator of the direct-children-list.185 inline std::set<const Identifier*>::const_iterator getDirectChildrenBegin() const { return this->directChildren_.begin(); }186 /// Returns the end-iterator of the direct-children-list.187 inline std::set<const Identifier*>::const_iterator getDirectChildrenEnd() const { return this->directChildren_.end(); }188 186 189 187 … … 223 221 XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname); 224 222 225 226 223 protected: 227 224 virtual void createSuperFunctionCaller() const = 0; 228 225 229 226 private: 230 std::set<const Identifier*> parents_; //!< The parents of the class the Identifier belongs to 227 void verifyIdentifierTrace() const; 228 void addIfNotExists(std::list<const Identifier*>& list, const Identifier* identifierToAdd) const; 229 230 std::list<const InheritsFrom*> manualDirectParents_; //!< Manually defined direct parents 231 std::list<const Identifier*> directParents_; //!< The direct parents of the class the Identifier belongs to (sorted by their order of initialization) 232 std::list<const Identifier*> parents_; //!< The parents of the class the Identifier belongs to (sorted by their order of initialization) 233 234 std::set<const Identifier*> directChildren_; //!< The direct children of the class the Identifier belongs to 231 235 std::set<const Identifier*> children_; //!< The children of the class the Identifier belongs to 232 233 std::set<const Identifier*> directParents_; //!< The direct parents of the class the Identifier belongs to234 std::set<const Identifier*> directChildren_; //!< The direct children of the class the Identifier belongs to235 236 236 237 bool bInitialized_; //!< Is true if the Identifier was completely initialized 237 238 bool bLoadable_; //!< False = it's not permitted to load the object through XML 239 bool bIsVirtualBase_; //!< If true, it is recommended to inherit virtually from this class. This changes the order of initialization of child classes, thus this information is necessary to check the class hierarchy. 238 240 std::string name_; //!< The name of the class the Identifier belongs to 239 241 Factory* factory_; //!< The Factory, able to create new objects of the given class (if available) 240 242 uint32_t networkID_; //!< The network ID to identify a class through the network 241 const unsigned int classID_;//!< Uniquely identifies a class (might not be the same as the networkID_)243 unsigned int classID_; //!< Uniquely identifies a class (might not be the same as the networkID_) 242 244 243 245 bool bHasConfigValues_; //!< True if this class has at least one assigned config value … … 267 269 class ClassIdentifier : public Identifier 268 270 { 271 BOOST_STATIC_ASSERT((boost::is_base_of<Identifiable, T>::value)); 272 269 273 #ifndef DOXYGEN_SHOULD_SKIP_THIS 270 274 #define SUPER_INTRUSIVE_DECLARATION_INCLUDE … … 273 277 274 278 public: 275 static ClassIdentifier<T>* getIdentifier(); 276 static ClassIdentifier<T>* getIdentifier(const std::string& name); 277 278 bool initializeObject(T* object); 279 280 void setConfigValues(T* object, Configurable*) const; 281 void setConfigValues(T* object, Identifiable*) const; 282 283 void addObjectToList(T* object, Listable*); 284 void addObjectToList(T* object, Identifiable*); 285 286 virtual void updateConfigValues(bool updateChildren = true) const; 287 288 virtual const std::string& getTypeidName() 289 { return this->typeidName_; } 290 291 private: 292 static void initializeIdentifier(); 293 294 ClassIdentifier(const ClassIdentifier<T>& identifier) {} // don't copy 295 ClassIdentifier() 279 ClassIdentifier(const std::string& name, Factory* factory, bool bLoadable) : Identifier(name, factory, bLoadable) 296 280 { 297 this->typeidName_ = typeid(T).name(); 281 OrxVerify(ClassIdentifier<T>::classIdentifier_s == NULL, "Assertion failed in ClassIdentifier of type " << typeid(T).name()); 282 ClassIdentifier<T>::classIdentifier_s = this; 283 298 284 SuperFunctionInitialization<0, T>::initialize(this); 299 285 } … … 303 289 } 304 290 291 bool initializeObject(T* object); 292 293 virtual void updateConfigValues(bool updateChildren = true) const; 294 295 virtual const std::type_info& getTypeInfo() 296 { return typeid(T); } 297 298 virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const 299 { return dynamic_cast<T*>(object) != 0; } 300 301 virtual void destroyObjects(); 302 303 static ClassIdentifier<T>* getIdentifier(); 304 305 private: 306 ClassIdentifier(const ClassIdentifier<T>& identifier) {} // don't copy 307 308 void setConfigValues(T* object, Configurable*) const; 309 void setConfigValues(T* object, Identifiable*) const; 310 311 void addObjectToList(T* object, Listable*); 312 void addObjectToList(T* object, Identifiable*); 313 314 void destroyObjects(Listable*); 315 void destroyObjects(void*); 316 317 void destroyObject(Destroyable* object); 318 void destroyObject(void* object); 319 305 320 void updateConfigValues(bool updateChildren, Listable*) const; 306 321 void updateConfigValues(bool updateChildren, Identifiable*) const; 307 322 308 std::string typeidName_;309 323 static WeakPtr<ClassIdentifier<T> > classIdentifier_s; 310 324 }; … … 318 332 */ 319 333 template <class T> 320 inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()321 { 322 // check if the Identifier already exists323 if (!ClassIdentifier<T>::classIdentifier_s)324 ClassIdentifier<T>::initializeIdentifier(); 325 334 /*static*/ inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier() 335 { 336 if (ClassIdentifier<T>::classIdentifier_s == NULL) 337 ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*) IdentifierManager::getInstance().getIdentifierByTypeInfo(typeid(T)); 338 339 OrxVerify(ClassIdentifier<T>::classIdentifier_s != NULL, "Did you forget to register the class of type " << typeid(T).name() << "?"); 326 340 return ClassIdentifier<T>::classIdentifier_s; 327 }328 329 /**330 @brief Does the same as getIdentifier() but sets the name if this wasn't done yet.331 @param name The name of this Identifier332 @return The Identifier333 */334 template <class T>335 inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier(const std::string& name)336 {337 ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();338 identifier->setName(name);339 return identifier;340 }341 342 /**343 @brief Assigns the static field for the identifier singleton.344 */345 template <class T>346 /*static */ void ClassIdentifier<T>::initializeIdentifier()347 {348 // create a new identifier anyway. Will be deleted if not used.349 ClassIdentifier<T>* proposal = new ClassIdentifier<T>();350 351 // Get the entry from the map352 ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)IdentifierManager::getInstance().getGloballyUniqueIdentifier(proposal);353 354 if (ClassIdentifier<T>::classIdentifier_s == proposal)355 orxout(verbose, context::identifier) << "Requested Identifier for " << proposal->getTypeidName() << " was not yet existing and got created." << endl;356 else357 {358 orxout(verbose, context::identifier) << "Requested Identifier for " << proposal->getTypeidName() << " was already existing and got assigned." << endl;359 delete proposal; // delete proposal (it is not used anymore)360 }361 341 } 362 342 … … 375 355 IdentifierManager::getInstance().createdObject(object); 376 356 377 this->setConfigValues(object, object); 357 if (Identifier::initConfigValues_s) 358 this->setConfigValues(object, object); 359 378 360 return true; 379 361 } … … 420 402 421 403 /** 404 * @brief Destroy all objects of this class (must be Listable). 405 * Destroyables are destroyed with destroy(), all other classes with delete. 406 */ 407 template <class T> 408 void ClassIdentifier<T>::destroyObjects() 409 { 410 this->destroyObjects((T*)0); 411 } 412 413 /** 414 * @brief Only searches and destroys objects if is a @ref Listable 415 */ 416 template <class T> 417 void ClassIdentifier<T>::destroyObjects(Listable*) 418 { 419 ObjectListBase* objectList = Context::getRootContext()->getObjectList(this); 420 ObjectListElement<T>* begin = static_cast<ObjectListElement<T>*>(objectList->begin()); 421 ObjectListElement<T>* end = static_cast<ObjectListElement<T>*>(objectList->end()); 422 for (typename ObjectList<T>::iterator it = begin; it != end; ) 423 this->destroyObject(*(it++)); 424 } 425 426 template <class T> 427 void ClassIdentifier<T>::destroyObjects(void*) 428 { 429 // no action 430 } 431 432 /** 433 * @brief Call 'object->destroy()' for Destroyables and 'delete object' for all other types. 434 */ 435 template <class T> 436 void ClassIdentifier<T>::destroyObject(Destroyable* object) 437 { 438 object->destroy(); 439 } 440 441 template <class T> 442 void ClassIdentifier<T>::destroyObject(void* object) 443 { 444 delete static_cast<Identifiable*>(object); 445 } 446 447 /** 422 448 @brief Updates the config-values of all existing objects of this class by calling their setConfigValues() function. 423 449 */ … … 438 464 439 465 if (updateChildren) 440 for (std::set<const Identifier*>::const_iterator it = this->getChildren Begin(); it != this->getChildrenEnd(); ++it)466 for (std::set<const Identifier*>::const_iterator it = this->getChildren().begin(); it != this->getChildren().end(); ++it) 441 467 (*it)->updateConfigValues(false); 442 468 } -
code/trunk/src/libraries/core/class/IdentifierManager.cc
r9667 r10624 37 37 38 38 #include "util/StringUtils.h" 39 #include "core/Core Includes.h"39 #include "core/Core.h" 40 40 #include "core/config/ConfigValueContainer.h" 41 41 #include "core/XMLPort.h" … … 44 44 namespace orxonox 45 45 { 46 /* static */ IdentifierManager& IdentifierManager::getInstance() 47 { 48 static IdentifierManager instance; 49 return instance; 50 } 46 IdentifierManager* IdentifierManager::singletonPtr_s = 0; 51 47 52 48 IdentifierManager::IdentifierManager() 53 49 { 54 50 this->hierarchyCreatingCounter_s = 0; 55 this->classIDCounter_s = 0; 56 } 57 58 /** 59 @brief Returns an identifier by name and adds it if not available 60 @param proposal A pointer to a newly created identifier for the case of non existence in the map 61 @return The identifier (unique instance) 62 */ 63 Identifier* IdentifierManager::getGloballyUniqueIdentifier(Identifier* proposal) 64 { 65 const std::string& typeidName = proposal->getTypeidName(); 66 std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.find(typeidName); 67 68 if (it != this->identifierByTypeidName_.end()) 69 { 70 // There is already an entry: return it 71 return it->second; 72 } 73 else 74 { 75 // There is no entry: put the proposal into the map and return it 76 this->identifierByTypeidName_[typeidName] = proposal; 77 return proposal; 78 } 51 this->recordTraceForIdentifier_ = NULL; 79 52 } 80 53 … … 82 55 * Registers the identifier in all maps of the IdentifierManager. 83 56 */ 84 void IdentifierManager::addIdentifierToLookupMaps(Identifier* identifier) 85 { 86 const std::string& typeidName = identifier->getTypeidName(); 87 if (this->identifierByTypeidName_.find(typeidName) != this->identifierByTypeidName_.end()) 88 { 89 this->identifierByString_[identifier->getName()] = identifier; 90 this->identifierByLowercaseString_[getLowercase(identifier->getName())] = identifier; 91 this->identifierByNetworkId_[identifier->getNetworkID()] = identifier; 92 } 93 else 94 orxout(internal_warning) << "Trying to add an identifier to lookup maps which is not known to IdentifierManager" << endl; 57 void IdentifierManager::addIdentifier(Identifier* identifier) 58 { 59 orxout(verbose, context::identifier) << "Adding identifier for " << identifier->getName() << " / " << identifier->getTypeInfo().name() << endl; 60 61 this->identifiers_.insert(identifier); 62 this->identifierByString_[identifier->getName()] = identifier; 63 this->identifierByLowercaseString_[getLowercase(identifier->getName())] = identifier; 64 this->identifierByNetworkId_[identifier->getNetworkID()] = identifier; 65 } 66 67 /** 68 * Unregisters the identifier from all maps of the IdentifierManager. 69 */ 70 void IdentifierManager::removeIdentifier(Identifier* identifier) 71 { 72 this->identifiers_.erase(identifier); 73 this->identifierByString_.erase(identifier->getName()); 74 this->identifierByLowercaseString_.erase(getLowercase(identifier->getName())); 75 this->identifierByNetworkId_.erase(identifier->getNetworkID()); 95 76 } 96 77 … … 112 93 { 113 94 Context temporaryContext(NULL); 114 for (std:: map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)95 for (std::set<Identifier*>::const_iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it) 115 96 { 116 orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << it->second->getName() << ">-Singleton." << endl; 97 Identifier* identifier = (*it); 98 if (identifier->isInitialized()) 99 continue; 100 101 orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << identifier->getName() << ">-Singleton." << endl; 117 102 // To initialize the identifier, we create a new object and delete it afterwards. 118 if (i t->second->hasFactory())103 if (identifier->hasFactory()) 119 104 { 120 this->identifiersOfNewObject_.clear(); 121 Identifiable* temp = it->second->fabricate(&temporaryContext); 122 if (temp->getIdentifier() != it->second) 123 orxout(internal_error) << "Newly created object of type " << it->second->getName() << " has unexpected identifier. Did you forget to use RegisterObject(classname)?" << endl; 105 this->identifierTraceOfNewObject_.clear(); 106 this->recordTraceForIdentifier_ = identifier; 107 108 Identifiable* temp = identifier->fabricate(&temporaryContext); 109 110 this->recordTraceForIdentifier_ = NULL; 111 112 if (temp->getIdentifier() != identifier) 113 orxout(internal_error) << "Newly created object of type " << identifier->getName() << " has unexpected identifier. Did you forget to use RegisterObject(classname)?" << endl; 114 115 identifier->initializeParents(this->identifierTraceOfNewObject_[temp]); 116 124 117 delete temp; 125 126 it->second->initializeParents(this->identifiersOfNewObject_);127 118 } 128 else 129 it->second->initializeDirectParentsOfAbstractClass(); 130 131 initializedIdentifiers.insert(it->second); 119 120 initializedIdentifiers.insert(identifier); 132 121 } 133 122 … … 138 127 139 128 // finish the initialization of all identifiers 140 for (std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it) 141 { 142 if (initializedIdentifiers.find(it->second) != initializedIdentifiers.end()) 143 it->second->finishInitialization(); 144 else 145 orxout(internal_error) << "Identifier was registered late and is not initialized: " << it->second->getName() << " / " << it->second->getTypeidName() << endl; 146 } 129 for (std::set<Identifier*>::const_iterator it = initializedIdentifiers.begin(); it != initializedIdentifiers.end(); ++it) 130 (*it)->finishInitialization(); 131 132 // only check class hierarchy in dev mode because it's an expensive operation and it requires a developer to fix detected problems anyway. 133 if (!Core::exists() || Core::getInstance().getConfig()->inDevMode()) 134 this->verifyClassHierarchy(initializedIdentifiers); 147 135 148 136 this->stopCreatingHierarchy(); … … 151 139 152 140 /** 153 @brief Destroys all Identifiers. Called when exiting the program. 154 */ 155 void IdentifierManager::destroyAllIdentifiers() 156 { 157 for (std::map<std::string, Identifier*>::iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it) 158 delete (it->second); 159 160 this->identifierByTypeidName_.clear(); 161 this->identifierByString_.clear(); 162 this->identifierByLowercaseString_.clear(); 163 this->identifierByNetworkId_.clear(); 141 * Verifies if the class hierarchy is consistent with the RTTI. 142 */ 143 void IdentifierManager::verifyClassHierarchy(const std::set<Identifier*>& initializedIdentifiers) 144 { 145 // check if there are any uninitialized identifiers remaining 146 for (std::set<Identifier*>::const_iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it) 147 if (!(*it)->isInitialized()) 148 orxout(internal_error) << "Identifier was registered late and is not initialized: " << (*it)->getName() << " / " << (*it)->getTypeInfo().name() << endl; 149 150 // for all initialized identifiers, check if a sample instance behaves as expected according to the class hierarchy 151 Context temporaryContext(NULL); 152 for (std::set<Identifier*>::const_iterator it1 = initializedIdentifiers.begin(); it1 != initializedIdentifiers.end(); ++it1) 153 { 154 if (!(*it1)->hasFactory()) 155 continue; 156 157 Identifiable* temp = (*it1)->fabricate(&temporaryContext); 158 159 for (std::set<Identifier*>::const_iterator it2 = this->identifiers_.begin(); it2 != this->identifiers_.end(); ++it2) 160 { 161 bool isA_AccordingToRtti = (*it2)->canDynamicCastObjectToIdentifierClass(temp); 162 bool isA_AccordingToClassHierarchy = temp->isA((*it2)); 163 164 if (isA_AccordingToRtti != isA_AccordingToClassHierarchy) 165 { 166 orxout(internal_error) << "Class hierarchy does not match RTTI: Class hierarchy claims that " << (*it1)->getName() << 167 (isA_AccordingToClassHierarchy ? " is a " : " is not a ") << (*it2)->getName() << " but RTTI says the opposite." << endl; 168 } 169 } 170 171 delete temp; 172 } 173 orxout(internal_info) << "Class hierarchy matches RTTI" << endl; 174 175 size_t numberOfObjects = temporaryContext.getObjectList<Listable>()->size(); 176 if (numberOfObjects > 0) 177 orxout(internal_warning) << "There are still " << numberOfObjects << " listables left after creating the class hierarchy" << endl; 178 } 179 180 /** 181 * @brief Resets all Identifiers. 182 */ 183 void IdentifierManager::destroyClassHierarchy() 184 { 185 orxout(internal_status) << "Destroy class-hierarchy" << endl; 186 for (std::set<Identifier*>::const_iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it) 187 (*it)->reset(); 164 188 } 165 189 … … 170 194 { 171 195 if (this->isCreatingHierarchy()) 172 this->identifiersOfNewObject_.insert(identifiable->getIdentifier()); 196 { 197 if (this->recordTraceForIdentifier_) 198 { 199 std::list<const Identifier*>& traceForObject = this->identifierTraceOfNewObject_[identifiable]; 200 if (std::find(traceForObject.begin(), traceForObject.end(), identifiable->getIdentifier()) != traceForObject.end()) 201 { 202 orxout(internal_warning) << this->recordTraceForIdentifier_->getName() << " inherits two times from " << 203 identifiable->getIdentifier()->getName() << ". Did you forget to use virtual inheritance?" << endl; 204 } 205 traceForObject.push_back(identifiable->getIdentifier()); 206 } 207 } 173 208 else 174 209 orxout(internal_warning) << "createdObject() called outside of class hierarchy creation" << endl; … … 218 253 219 254 /** 255 @brief Returns the Identifier with a given typeid-name. 256 @param name The typeid-name of the wanted Identifier 257 @return The Identifier 258 */ 259 Identifier* IdentifierManager::getIdentifierByTypeInfo(const std::type_info& typeInfo) 260 { 261 // TODO: use std::type_index and a map to find identifiers by type_info (only with c++11) 262 for (std::set<Identifier*>::iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it) 263 if ((*it)->getTypeInfo() == typeInfo) 264 return (*it); 265 return 0; 266 } 267 268 /** 220 269 @brief Cleans the NetworkID map (needed on clients for correct initialization) 221 270 */ -
code/trunk/src/libraries/core/class/IdentifierManager.h
r9667 r10624 39 39 #include <map> 40 40 #include <set> 41 #include <list> 41 42 #include <string> 43 44 #include "util/Singleton.h" 42 45 43 46 namespace orxonox 44 47 { 45 class _CoreExport IdentifierManager 48 class _CoreExport IdentifierManager : public Singleton<IdentifierManager> 46 49 { 50 friend class Singleton<IdentifierManager>; 51 47 52 public: 48 static IdentifierManager& getInstance(); 53 IdentifierManager(); 54 ~IdentifierManager() {} 49 55 50 Identifier* getGloballyUniqueIdentifier(Identifier* proposal); 51 void addIdentifierToLookupMaps(Identifier* identifier); 52 53 unsigned int getUniqueClassId() 54 { return this->classIDCounter_s++; } 56 void addIdentifier(Identifier* identifier); 57 void removeIdentifier(Identifier* identifier); 55 58 56 59 … … 59 62 ///////////////////////////// 60 63 void createClassHierarchy(); 61 void destroyAllIdentifiers(); 64 void verifyClassHierarchy(const std::set<Identifier*>& initializedIdentifiers); 65 void destroyClassHierarchy(); 62 66 63 67 void createdObject(Identifiable* identifiable); … … 74 78 Identifier* getIdentifierByLowercaseString(const std::string& name); 75 79 Identifier* getIdentifierByID(uint32_t id); 80 Identifier* getIdentifierByTypeInfo(const std::type_info& typeInfo); 76 81 77 82 void clearNetworkIDs(); … … 88 93 89 94 private: 90 IdentifierManager(); 91 IdentifierManager(const IdentifierManager&); 92 ~IdentifierManager() {} 95 IdentifierManager(const IdentifierManager&); // not implemented 93 96 94 97 /// Increases the hierarchyCreatingCounter_s variable, causing all new objects to store their parents. … … 99 102 { hierarchyCreatingCounter_s--; } 100 103 101 std::map<std::string, Identifier*> identifierByTypeidName_; //!< Map with the names as received by typeid(). This is only used internally. 102 104 std::set<Identifier*> identifiers_; //!< All identifiers. This is only used internally. 103 105 std::map<std::string, Identifier*> identifierByString_; //!< Map that stores all Identifiers with their names. 104 106 std::map<std::string, Identifier*> identifierByLowercaseString_; //!< Map that stores all Identifiers with their names in lowercase. … … 106 108 107 109 int hierarchyCreatingCounter_s; //!< Bigger than zero if at least one Identifier stores its parents (its an int instead of a bool to avoid conflicts with multithreading) 108 std::set<const Identifier*> identifiersOfNewObject_; //!< Used while creating the object hierarchy to keep track of the identifiers of a newly created object 109 unsigned int classIDCounter_s; //!< counter for the unique classIDs 110 111 /// Used while creating the object hierarchy to keep track of the identifiers of a newly created object (and all other objects that get created as 112 /// a consequence of this, e.g. nested member objects). 113 std::map<Identifiable*, std::list<const Identifier*> > identifierTraceOfNewObject_; 114 Identifier* recordTraceForIdentifier_; //!< The identifier for which we want to record the trace of identifiers during object creation. If null, no trace is recorded. 115 116 static IdentifierManager* singletonPtr_s; 110 117 }; 111 118 } -
code/trunk/src/libraries/core/class/OrxonoxInterface.cc
r9667 r10624 32 32 namespace orxonox 33 33 { 34 RegisterClassNoArgs(OrxonoxInterface) ;34 RegisterClassNoArgs(OrxonoxInterface).virtualBase(); 35 35 36 36 OrxonoxInterface::OrxonoxInterface() -
code/trunk/src/libraries/core/class/Super.h
r9667 r10624 274 274 SUPER_NOARGS(classname, functionname) 275 275 276 #define SUPER_changedGametype(classname, functionname, ...) \277 SUPER_NOARGS(classname, functionname)278 279 276 #define SUPER_changedUsed(classname, functionname, ...) \ 280 277 SUPER_NOARGS(classname, functionname) … … 555 552 SUPER_FUNCTION_GLOBAL_DECLARATION_PART2; 556 553 557 SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedGametype, false) 558 () 559 SUPER_FUNCTION_GLOBAL_DECLARATION_PART2; 560 561 SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedUsed, false) 562 () 563 SUPER_FUNCTION_GLOBAL_DECLARATION_PART2; 564 565 SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(11, changedCarrier, false) 566 () 567 SUPER_FUNCTION_GLOBAL_DECLARATION_PART2; 568 569 SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(12, changedPickedUp, false) 554 SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedUsed, false) 555 () 556 SUPER_FUNCTION_GLOBAL_DECLARATION_PART2; 557 558 SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedCarrier, false) 559 () 560 SUPER_FUNCTION_GLOBAL_DECLARATION_PART2; 561 562 SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(11, changedPickedUp, false) 570 563 () 571 564 SUPER_FUNCTION_GLOBAL_DECLARATION_PART2; … … 623 616 SUPER_INTRUSIVE_DECLARATION(changedOverlayGroup); 624 617 SUPER_INTRUSIVE_DECLARATION(changedName); 625 SUPER_INTRUSIVE_DECLARATION(changedGametype);626 618 SUPER_INTRUSIVE_DECLARATION(changedUsed); 627 619 SUPER_INTRUSIVE_DECLARATION(changedCarrier); -
code/trunk/src/libraries/core/command/ArgumentCompletionFunctions.cc
r9667 r10624 44 44 #include "CommandExecutor.h" 45 45 #include "ConsoleCommand.h" 46 #include "ConsoleCommandManager.h" 46 47 #include "TclThreadManager.h" 47 48 … … 98 99 99 100 // get all the groups that are visible (except the shortcut group "") 100 const std::map<std::string, std::map<std::string, ConsoleCommand*> >& commands = ConsoleCommand ::getCommands();101 const std::map<std::string, std::map<std::string, ConsoleCommand*> >& commands = ConsoleCommandManager::getInstance().getCommands(); 101 102 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group) 102 103 if (groupIsVisible(it_group->second, bOnlyShowHidden) && it_group->first != "" && (fragmentLC == "" || getLowercase(it_group->first).find(fragmentLC) == 0)) … … 137 138 138 139 // find the iterator of the given group 139 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand ::getCommands().begin();140 for ( ; it_group != ConsoleCommand ::getCommands().end(); ++it_group)140 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommandManager::getInstance().getCommands().begin(); 141 for ( ; it_group != ConsoleCommandManager::getInstance().getCommands().end(); ++it_group) 141 142 if (getLowercase(it_group->first) == groupLC) 142 143 break; 143 144 144 145 // add all commands in the group to the list 145 if (it_group != ConsoleCommand ::getCommands().end())146 if (it_group != ConsoleCommandManager::getInstance().getCommands().end()) 146 147 { 147 148 for (std::map<std::string, ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command) … … 206 207 return detail::_groupsandcommands(fragment, true); 207 208 208 if (ConsoleCommand ::getCommandLC(getLowercase(tokens[0])))209 if (ConsoleCommandManager::getInstance().getCommandLC(getLowercase(tokens[0]))) 209 210 return ARGUMENT_COMPLETION_FUNCTION_CALL(command)(fragment); 210 211 211 212 if (tokens.size() == 1) 212 213 { 213 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand ::getCommands().find(tokens[0]);214 if (it_group != ConsoleCommand ::getCommands().end())214 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommandManager::getInstance().getCommands().find(tokens[0]); 215 if (it_group != ConsoleCommandManager::getInstance().getCommands().end()) 215 216 return detail::_subcommands(fragment, tokens[0], true); 216 217 else … … 218 219 } 219 220 220 if (ConsoleCommand ::getCommandLC(getLowercase(tokens[0]), getLowercase(tokens[1])))221 if (ConsoleCommandManager::getInstance().getCommandLC(getLowercase(tokens[0]), getLowercase(tokens[1]))) 221 222 return ARGUMENT_COMPLETION_FUNCTION_CALL(command)(fragment); 222 223 -
code/trunk/src/libraries/core/command/CMakeLists.txt
r7284 r10624 4 4 ConsoleCommand.cc 5 5 ConsoleCommandCompilation.cc 6 ConsoleCommandIncludes.cc 7 ConsoleCommandManager.cc 6 8 Executor.cc 7 9 IOConsole.cc -
code/trunk/src/libraries/core/command/CommandEvaluation.cc
r9550 r10624 37 37 #include "CommandExecutor.h" 38 38 #include "ConsoleCommand.h" 39 #include "ConsoleCommandManager.h" 39 40 40 41 namespace orxonox … … 305 306 // the user typed 1-2 arguments, check what he tried to type and print a suitable error 306 307 std::string groupLC = getLowercase(this->getToken(0)); 307 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand ::getCommandsLC().begin(); it_group != ConsoleCommand::getCommandsLC().end(); ++it_group)308 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommandManager::getInstance().getCommandsLC().begin(); it_group != ConsoleCommandManager::getInstance().getCommandsLC().end(); ++it_group) 308 309 if (it_group->first == groupLC) 309 310 return std::string("Error: There is no command in group \"") + this->getToken(0) + "\" starting with \"" + this->getToken(1) + "\"."; … … 327 328 328 329 // iterate through all groups and their commands and calculate the distance to the current command. keep the best. 329 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand ::getCommandsLC().begin(); it_group != ConsoleCommand::getCommandsLC().end(); ++it_group)330 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommandManager::getInstance().getCommandsLC().begin(); it_group != ConsoleCommandManager::getInstance().getCommandsLC().end(); ++it_group) 330 331 { 331 332 if (it_group->first != "") … … 345 346 346 347 // now also iterate through all shortcuts and keep the best if it's better than the one found above. 347 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand ::getCommandsLC().find("");348 if (it_group != ConsoleCommand ::getCommandsLC().end())348 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommandManager::getInstance().getCommandsLC().find(""); 349 if (it_group != ConsoleCommandManager::getInstance().getCommandsLC().end()) 349 350 { 350 351 for (std::map<std::string, ConsoleCommand*>::const_iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); ++it_name) -
code/trunk/src/libraries/core/command/CommandExecutor.cc
r9550 r10624 34 34 #include "CommandExecutor.h" 35 35 36 #include "ConsoleCommand .h"36 #include "ConsoleCommandIncludes.h" 37 37 #include "TclBind.h" 38 38 #include "Shell.h" … … 155 155 156 156 // assign the fallback-command to get hints about the possible commands and groups 157 evaluation.hintCommand_ = ConsoleCommand ::getCommand(__CC_CommandExecutor_name, __CC_autocomplete_name);157 evaluation.hintCommand_ = ConsoleCommandManager::getInstance().getCommand(__CC_CommandExecutor_name, __CC_autocomplete_name); 158 158 159 159 // check if there's at least one argument … … 161 161 { 162 162 // try to get a command from the first token 163 evaluation.execCommand_ = ConsoleCommand ::getCommandLC(evaluation.getToken(0));163 evaluation.execCommand_ = ConsoleCommandManager::getInstance().getCommandLC(evaluation.getToken(0)); 164 164 if (evaluation.execCommand_) 165 165 evaluation.execArgumentsOffset_ = 1; … … 167 167 { 168 168 // try to get a command from the first two tokens 169 evaluation.execCommand_ = ConsoleCommand ::getCommandLC(evaluation.getToken(0), evaluation.getToken(1));169 evaluation.execCommand_ = ConsoleCommandManager::getInstance().getCommandLC(evaluation.getToken(0), evaluation.getToken(1)); 170 170 if (evaluation.execCommand_) 171 171 evaluation.execArgumentsOffset_ = 2; … … 288 288 289 289 // check if the alias already exists - print an error and return if it does 290 if ((tokens.size() == 1 && ConsoleCommand ::getCommand(tokens[0])) || (tokens.size() == 2 && ConsoleCommand::getCommand(tokens[0], tokens[1])))290 if ((tokens.size() == 1 && ConsoleCommandManager::getInstance().getCommand(tokens[0])) || (tokens.size() == 2 && ConsoleCommandManager::getInstance().getCommand(tokens[0], tokens[1]))) 291 291 { 292 292 orxout(user_error) << "A command with name \"" << alias << "\" already exists." << endl; … … 296 296 // create a new console command with the given alias as its name 297 297 if (tokens.size() == 1) 298 createConsoleCommand(tokens[0], executor);298 ConsoleCommandManager::getInstance().registerCommand(new ConsoleCommand(tokens[0], executor)); 299 299 else if (tokens.size() == 2) 300 createConsoleCommand(tokens[0], tokens[1], executor);300 ConsoleCommandManager::getInstance().registerCommand(new ConsoleCommand(tokens[0], tokens[1], executor)); 301 301 else 302 302 orxout(user_error) << "\"" << alias << "\" is not a valid alias name (must have one or two words)." << endl; -
code/trunk/src/libraries/core/command/ConsoleCommand.cc
r9348 r10624 35 35 36 36 #include "util/Convert.h" 37 #include "util/StringUtils.h"38 37 #include "core/Language.h" 39 38 #include "core/GameMode.h" 40 39 #include "core/input/KeyBinder.h" 41 40 #include "core/input/KeyBinderManager.h" 41 #include "ConsoleCommandManager.h" 42 42 43 43 namespace orxonox 44 44 { 45 45 /** 46 @brief Constructor: Initializes all values and registers the command. 46 @brief Constructor: Initializes all values and registers the command (without a group). 47 @param name The name of the command 48 @param executor The executor of the command 49 @param bInitialized If true, the executor is used for both, the definition of the function-header AND to executute the command. If false, the command is inactive and needs to be assigned a function before it can be used. 50 */ 51 ConsoleCommand::ConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized) 52 { 53 this->init("", name, executor, bInitialized); 54 } 55 56 /** 57 @brief Constructor: Initializes all values and registers the command (with a group). 47 58 @param group The group of the command 48 59 @param name The name of the command … … 52 63 ConsoleCommand::ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized) 53 64 { 65 this->init(group, name, executor, bInitialized); 66 } 67 68 void ConsoleCommand::init(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized) 69 { 54 70 this->bActive_ = true; 55 71 this->bHidden_ = false; … … 68 84 this->executor_ = executor; 69 85 70 ConsoleCommand::registerCommand(group, name, this);86 this->names_.push_back(CommandName(group, name)); 71 87 } 72 88 … … 76 92 ConsoleCommand::~ConsoleCommand() 77 93 { 78 ConsoleCommand::unregisterCommand(this);79 94 } 80 95 … … 84 99 ConsoleCommand& ConsoleCommand::addShortcut() 85 100 { 86 ConsoleCommand::registerCommand("", this->baseName_, this);101 this->names_.push_back(CommandName("", this->baseName_)); 87 102 return *this; 88 103 } … … 93 108 ConsoleCommand& ConsoleCommand::addShortcut(const std::string& name) 94 109 { 95 ConsoleCommand::registerCommand("", name, this);110 this->names_.push_back(CommandName("", name)); 96 111 return *this; 97 112 } … … 102 117 ConsoleCommand& ConsoleCommand::addGroup(const std::string& group) 103 118 { 104 ConsoleCommand::registerCommand(group, this->baseName_, this);119 this->names_.push_back(CommandName(group, this->baseName_)); 105 120 return *this; 106 121 } … … 111 126 ConsoleCommand& ConsoleCommand::addGroup(const std::string& group, const std::string& name) 112 127 { 113 ConsoleCommand::registerCommand(group, name, this);128 this->names_.push_back(CommandName(group, name)); 114 129 return *this; 115 130 } … … 587 602 return *this; 588 603 } 589 590 /**591 @brief Returns the command with given group an name.592 @param group The group of the requested command593 @param name The group of the requested command594 @param bPrintError If true, an error is printed if the command doesn't exist595 */596 /* static */ ConsoleCommand* ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError)597 {598 // find the group599 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandMap().find(group);600 if (it_group != ConsoleCommand::getCommandMap().end())601 {602 // find the name603 std::map<std::string, ConsoleCommand*>::const_iterator it_name = it_group->second.find(name);604 if (it_name != it_group->second.end())605 {606 // return the pointer607 return it_name->second;608 }609 }610 if (bPrintError)611 {612 if (group == "")613 orxout(internal_error, context::commands) << "Couldn't find console command with shortcut \"" << name << "\"" << endl;614 else615 orxout(internal_error, context::commands) << "Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << endl;616 }617 return 0;618 }619 620 /**621 @brief Returns the command with given group an name in lowercase.622 @param group The group of the requested command in lowercase623 @param name The group of the requested command in lowercase624 @param bPrintError If true, an error is printed if the command doesn't exist625 */626 /* static */ ConsoleCommand* ConsoleCommand::getCommandLC(const std::string& group, const std::string& name, bool bPrintError)627 {628 std::string groupLC = getLowercase(group);629 std::string nameLC = getLowercase(name);630 631 // find the group632 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandMapLC().find(groupLC);633 if (it_group != ConsoleCommand::getCommandMapLC().end())634 {635 // find the name636 std::map<std::string, ConsoleCommand*>::const_iterator it_name = it_group->second.find(nameLC);637 if (it_name != it_group->second.end())638 {639 // return the pointer640 return it_name->second;641 }642 }643 if (bPrintError)644 {645 if (group == "")646 orxout(internal_error, context::commands) << "Couldn't find console command with shortcut \"" << name << "\"" << endl;647 else648 orxout(internal_error, context::commands) << "Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << endl;649 }650 return 0;651 }652 653 /**654 @brief Returns the static map that stores all console commands.655 */656 /* static */ std::map<std::string, std::map<std::string, ConsoleCommand*> >& ConsoleCommand::getCommandMap()657 {658 static std::map<std::string, std::map<std::string, ConsoleCommand*> > commandMap;659 return commandMap;660 }661 662 /**663 @brief Returns the static map that stores all console commands in lowercase.664 */665 /* static */ std::map<std::string, std::map<std::string, ConsoleCommand*> >& ConsoleCommand::getCommandMapLC()666 {667 static std::map<std::string, std::map<std::string, ConsoleCommand*> > commandMapLC;668 return commandMapLC;669 }670 671 /**672 @brief Registers a new command with given group an name by adding it to the command map.673 */674 /* static */ void ConsoleCommand::registerCommand(const std::string& group, const std::string& name, ConsoleCommand* command)675 {676 if (name == "")677 return;678 679 // check if a command with this name already exists680 if (ConsoleCommand::getCommand(group, name) != 0)681 {682 if (group == "")683 orxout(internal_warning, context::commands) << "A console command with shortcut \"" << name << "\" already exists." << endl;684 else685 orxout(internal_warning, context::commands) << "A console command with name \"" << name << "\" already exists in group \"" << group << "\"." << endl;686 }687 else688 {689 // add the command to the map690 ConsoleCommand::getCommandMap()[group][name] = command;691 ConsoleCommand::getCommandMapLC()[getLowercase(group)][getLowercase(name)] = command;692 }693 }694 695 /**696 @brief Removes the command from the command map.697 */698 /* static */ void ConsoleCommand::unregisterCommand(ConsoleCommand* command)699 {700 // iterate through all groups701 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::iterator it_group = ConsoleCommand::getCommandMap().begin(); it_group != ConsoleCommand::getCommandMap().end(); )702 {703 // iterate through all commands of each group704 for (std::map<std::string, ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); )705 {706 // erase the command707 if (it_name->second == command)708 it_group->second.erase(it_name++);709 else710 ++it_name;711 }712 713 // erase the group if it is empty now714 if (it_group->second.empty())715 ConsoleCommand::getCommandMap().erase(it_group++);716 else717 ++it_group;718 }719 720 // now the same for the lowercase-map:721 722 // iterate through all groups723 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::iterator it_group = ConsoleCommand::getCommandMapLC().begin(); it_group != ConsoleCommand::getCommandMapLC().end(); )724 {725 // iterate through all commands of each group726 for (std::map<std::string, ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); )727 {728 // erase the command729 if (it_name->second == command)730 it_group->second.erase(it_name++);731 else732 ++it_name;733 }734 735 // erase the group if it is empty now736 if (it_group->second.empty())737 ConsoleCommand::getCommandMapLC().erase(it_group++);738 else739 ++it_group;740 }741 }742 743 /**744 @brief Deletes all commands745 */746 /* static */ void ConsoleCommand::destroyAll()747 {748 // delete entries until the map is empty749 while (!ConsoleCommand::getCommandMap().empty() && !ConsoleCommand::getCommandMap().begin()->second.empty())750 delete ConsoleCommand::getCommandMap().begin()->second.begin()->second;751 }752 604 } -
code/trunk/src/libraries/core/command/ConsoleCommand.h
r9983 r10624 28 28 29 29 /** 30 @defgroup ConsoleCommand Console commands31 @ingroup Command32 */33 34 /**35 30 @file 36 31 @ingroup Command ConsoleCommand 37 @brief Declaration of the orxonox::ConsoleCommand class and the SetConsoleCommand() macro. 38 39 @anchor ConsoleCommandExample 40 41 Console commands can be used to write scripts, use key-bindings or simply to be 42 entered into the shell by the user. Instances of orxonox::ConsoleCommand define 43 the function of a command, and also more information like, for example, if it is 44 active, default values, and possible arguments. 45 46 Commands need to be registered to the system statically on startup by using the 47 SetConsoleCommand() or DeclareConsoleCommand() macros outside of a function. 48 This ensures that commands are known to the system at any time, so they can be 49 evaluated (see orxonox::CommandExecutor::evaluate()), for example for key-bindings. 50 51 Example: 52 @code 53 void myCoutFunction(const std::string& text) // Define a static function 54 { 55 orxout() << "Text: " << text << endl; // Print the text to the console 56 } 57 58 SetConsoleCommand("cout", &myCoutFunction); // Register the function as command with name "cout" 59 @endcode 60 61 Now you can open the shell and execute the command: 62 @code 63 $ cout Hello World 64 @endcode 65 66 Internally this command is now passed to orxonox::CommandExecutor::execute(): 67 @code 68 CommandExecutor::execute("cout HelloWorld"); 69 @endcode 70 71 CommandExecutor searches for a command with name "cout" and passes the arguments 72 "Hello World" to it. Because we registered myCoutFunction() with this command, 73 as a result the following text will be printed to the console: 74 @code 75 Text: Hello World 76 @endcode 77 78 You can add more attributes to the ConsoleCommand, by using the command-chain feature 79 of SetConsoleCommand(). For example like this: 80 @code 81 SetConsoleCommand("cout", &myCoutFunction) 82 .addGroup("output", "text") 83 .accessLevel(AccessLevel::Offline) 84 .defaultValues("no text"); 85 @endcode 86 87 Open the shell again and try it: 88 @code 89 $ cout Hello World 90 Text: Hello World 91 $ output text Hello World 92 Text: Hello World 93 $ cout 94 Text: no text 95 @endcode 96 97 If you execute it online (note: the access level is "Offline"), you will see the 98 following (or something similar): 99 @code 100 $ cout Hello World 101 Error: Can't execute command "cout", access denied. 102 @endcode 103 104 If a command is executed, the arguments are passed to an underlying function, 105 whitch is wrapped by an orxonox::Functor which again is wrapped by an orxonox::Executor. 106 The Functor contains the function-pointer, as well as the object-pointer in 107 case of a non-static member-function. The executor stores possible default-values 108 for each argument of the function. 109 110 The function of a command can be changed at any time. It's possible to just exchange 111 the function-pointer of the underlying Functor if the headers of the functions are 112 exactly the same. But you can also exchange the Functor itself or even completely 113 replace the Executor. Also the other attributes of a ConsoleCommand can be modified 114 during the game, for example it can be activated or deactivated. 115 116 To do so, the function ModifyConsoleCommand() has to be used. It returns an instance 117 of orxonox::ConsoleCommand::ConsoleCommandManipulator which has an interface similar to 118 orxonox::ConsoleCommand, but with slight differences. You can use it the same way like 119 SetConsoleCommand(), meaning you can use command-chains to change different attributes at 120 the same time. ModifyConsoleCommand() must not be executed statically, but rather in a 121 function at some point of the execution of the program. 122 123 Example: 124 @code 125 void myOtherCoutFunction(const std::string& text) // Define a new static function 126 { 127 orxout() << "Uppercase: " << getUppercase(text) << endl; // Print the text in uppercase to the console 128 } 129 130 { 131 // ... // somewhere in the code 132 133 ModifyConsoleCommand("cout").setFunction(&myOtherCoutFunction); // Modify the underlying function of the command 134 135 // ... 136 } 137 @endcode 138 139 If you now enter the command into the shell, you'll see a different behavior: 140 @code 141 $ cout Hello World 142 Uppercase: HELLO WORLD 143 $ cout 144 Uppercase: NO TEXT 145 @endcode 146 147 A few important notes about changing functions: 148 149 Instead of changing the function with setFunction(), you can also create a command-stack 150 by using pushFunction() and popFunction(). It's important to note a few things about that, 151 because the underlying structure of Executor and Functor has a few pitfalls: 152 - If you push a new function-pointer, the same executor as before will be used (and, if 153 the headers match, even the same functor can be used, which is very fast) 154 - If you push a new Functor, the same executor as before will be used 155 - If you push a new Executor, everything is changed 156 157 Note that the executor contains the @b default @b values, so if you just exchange the 158 Functor, the default values remain the same. However if you decide to change the default 159 values at any point of the stack, <b>this will also change the default values on all 160 other stack-levels</b> that share the same executor. If you don't like this behavior, 161 you have to explicitly push a new executor before changing the default values, either by 162 calling pushFunction(executor) or by calling pushFunction(void) which pushes a copy of 163 the current executor to the stack. 164 165 Another important point are object pointers in case of non-static member-functions. 166 Whenever you set or push a new function, <b>you must add the object pointer again</b> 167 because objects are stored in the Functor which is usually exchanged if you change 168 the function. 169 170 You can also use a stack for objects, but note that this <b>object-stack is different for each 171 function</b> - so if you set a new function, the object-stack will be cleared. If you push 172 a new function, the old object-stack is stored in the stack, so it can be restored if 173 you pop the function. 174 175 %DeclareConsoleCommand(): 176 177 Appart from SetConsoleCommand() you can also call DeclareConsoleCommand(). In contrast 178 to SetConsoleCommand(), this doesn't assign a function to the command. Indeed you have 179 to pass a function-pointer to DeclareConsoleCommand(), but it is only used to determine 180 the header of the future command-function. This allows to declare a command statically, 181 thus it's possible to evaluate key-bindings of this command, but the actual function 182 can be assigned at a later point. 183 184 Example: 185 @code 186 DeclareConsoleCommand("cout", &prototype::void__string); 187 @endcode 188 189 If you try to execute the command now, you see the following (or something similar): 190 @code 191 $ cout Hello World 192 Error: Can't execute command "cout", command is not active. 193 @endcode 194 195 You first have to assign a function to use the command: 196 @code 197 { 198 // ... 199 200 ModifyConsoleCommand("cout").setFunction(&myCoutFunction); 201 202 // ... 203 } 204 @endcode 205 206 Now you can use it: 207 @code 208 $ cout Hello World 209 Text: Hello World 210 @endcode 211 212 Note that the initial function prototype::void__string is defined in the namespace 213 orxonox::prototype. If there's no function with the desired header, you can extend 214 the collection of functions or simply use another function that has the same header. 32 @brief Declaration of the orxonox::ConsoleCommand class. 215 33 */ 216 34 … … 223 41 #include <vector> 224 42 225 #include "util/VA_NARGS.h"226 43 #include "ArgumentCompletionFunctions.h" 227 44 #include "Executor.h" 228 229 230 /**231 @brief Defines a console command. The macro is overloaded for 2-4 parameters.232 233 This is an overloaded macro. Depending on the number of arguments a different234 overloaded implementation of the macro will be chosen.235 236 Console commands created with SetConsoleCommand() become active immediately and237 the given function-pointer (and optionally the object) will be used to execute238 the command.239 */240 #define SetConsoleCommand(...) \241 BOOST_PP_EXPAND(BOOST_PP_CAT(SetConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__))242 /**243 @brief This macro is executed if you call SetConsoleCommand() with 2 arguments.244 @param name The name (string) of the console command245 @param functionpointer The function-pointer of the corresponding command-function246 */247 #define SetConsoleCommand2(name, functionpointer) \248 SetConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))249 /**250 @brief This macro is executed if you call SetConsoleCommand() with 3 arguments.251 @param group The group (string) of the console command252 @param name The name (string) of the console command253 @param functionpointer The function-pointer of the corresponding command-function254 */255 #define SetConsoleCommand3(group, name, functionpointer) \256 SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))257 /**258 @brief This macro is executed if you call SetConsoleCommand() with 4 arguments.259 @param group The group (string) of the console command260 @param name The name (string) of the console command261 @param functionpointer The function-pointer of the corresponding command-function262 @param object The object that will be assigned to the command. Used for member-functions.263 */264 #define SetConsoleCommand4(group, name, functionpointer, object) \265 SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))266 267 /// Internal macro268 #define SetConsoleCommandGeneric(group, name, functor) \269 static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __UNIQUE_NUMBER__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor)))270 271 272 /**273 @brief Declares a console command. The macro is overloaded for 2-3 parameters.274 275 This is an overloaded macro. Depending on the number of arguments a different276 overloaded implementation of the macro will be chosen.277 278 Console commands created with DeclareConsoleCommand() don't use the the given279 function-pointer to execute the command, it is only used to define the header280 of the future command-function. The command is inactive until you manually281 set a function with orxonox::ModifyConsoleCommand(). You can use a different282 function-pointer than in the final command, as long as it has the same header.283 */284 #define DeclareConsoleCommand(...) \285 BOOST_PP_EXPAND(BOOST_PP_CAT(DeclareConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__))286 /**287 @brief This macro is executed if you call DeclareConsoleCommand() with 2 arguments.288 @param name The name (string) of the console command289 @param functionpointer The function-pointer of an arbitrary function that has the same header as the final function290 */291 #define DeclareConsoleCommand2(name, functionpointer) \292 DeclareConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))293 /**294 @brief This macro is executed if you call DeclareConsoleCommand() with 3 arguments.295 @param group The group (string) of the console command296 @param name The name (string) of the console command297 @param functionpointer The function-pointer of an arbitrary function that has the same header as the final function298 */299 #define DeclareConsoleCommand3(group, name, functionpointer) \300 DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))301 302 /// Internal macro303 #define DeclareConsoleCommandGeneric(group, name, functor) \304 static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __UNIQUE_NUMBER__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor), false))305 306 45 307 46 namespace orxonox … … 365 104 366 105 public: 106 /** 107 * @brief Defines the name of a command, consisting of an optional group ("" means no group) and the name itself. 108 */ 109 struct CommandName 110 { 111 CommandName(const std::string& group, const std::string& name) : group_(group), name_(name) {} 112 std::string group_; 113 std::string name_; 114 }; 115 367 116 /** 368 117 @brief Helper class that is used to manipulate console commands. … … 522 271 523 272 public: 273 ConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true); 524 274 ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true); 525 275 ~ConsoleCommand(); … … 620 370 { return this; } 621 371 372 inline const std::vector<CommandName>& getNames() 373 { return this->names_; } 374 622 375 private: 376 void init(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized); 377 623 378 bool headersMatch(const FunctorPtr& functor); 624 379 bool headersMatch(const ExecutorPtr& executor); … … 641 396 AccessLevel::Enum accessLevel_; ///< The access level (the state of the game in which you can access the command) 642 397 std::string baseName_; ///< The name that was first assigned to the command 398 std::vector<CommandName> names_; ///< All names and aliases of this command 643 399 FunctorPtr baseFunctor_; ///< The functor that defines the header of the command-function 644 400 … … 655 411 LanguageEntryLabel descriptionReturnvalue_; ///< A description of the return-value 656 412 LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS]; ///< A description for each argument 657 658 public:659 /// Returns the map with all groups and commands.660 static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommands()661 { return ConsoleCommand::getCommandMap(); }662 /// Returns the map with all groups and commands in lowercase.663 static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandsLC()664 { return ConsoleCommand::getCommandMapLC(); }665 666 /// Returns a command (shortcut) with given name. @param name The name of the command shortcut @param bPrintError If true, an error is printed if the command doesn't exist667 static inline ConsoleCommand* getCommand(const std::string& name, bool bPrintError = false)668 { return ConsoleCommand::getCommand("", name, bPrintError); }669 /// Returns a command (shortcut) with given name in lowercase. @param name The lowercase name of the command shortcut @param bPrintError If true, an error is printed if the command doesn't exist670 static inline ConsoleCommand* getCommandLC(const std::string& name, bool bPrintError = false)671 { return ConsoleCommand::getCommandLC("", name, bPrintError); }672 673 static ConsoleCommand* getCommand(const std::string& group, const std::string& name, bool bPrintError = false);674 static ConsoleCommand* getCommandLC(const std::string& group, const std::string& name, bool bPrintError = false);675 676 static void destroyAll();677 678 private:679 static std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandMap();680 static std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandMapLC();681 682 static void registerCommand(const std::string& group, const std::string& name, ConsoleCommand* command);683 static void unregisterCommand(ConsoleCommand* command);684 413 }; 685 686 /**687 @brief Creates a new ConsoleCommand.688 @param name The name of the command689 @param executor The executor of the command690 @param bInitialized If true, the command is ready to be executed, otherwise it has to be activated first.691 */692 inline ConsoleCommand* createConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)693 { return new ConsoleCommand("", name, executor, bInitialized); }694 /**695 @brief Creates a new ConsoleCommand.696 @param group The group of the command697 @param name The name of the command698 @param executor The executor of the command699 @param bInitialized If true, the command is ready to be executed, otherwise it has to be activated first.700 */701 inline ConsoleCommand* createConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)702 { return new ConsoleCommand(group, name, executor, bInitialized); }703 704 705 /**706 @brief Returns a manipulator for a command with the given name.707 708 @note If the command doesn't exist, the manipulator contains a NULL pointer to the command,709 but it can still be used without checks, because all functions of ConsoleCommandManipulator710 check internally if the command exists.711 */712 inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& name)713 { return ConsoleCommand::getCommand(name, true); }714 /**715 @brief Returns a manipulator for a command with the given group and name.716 717 @note If the command doesn't exist, the manipulator contains a NULL pointer to the command,718 but it can still be used without checks, because all functions of ConsoleCommandManipulator719 check internally if the command exists.720 */721 inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& group, const std::string& name)722 { return ConsoleCommand::getCommand(group, name, true); }723 414 } 724 415 -
code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc
r8858 r10624 41 41 #include "util/ExprParser.h" 42 42 #include "util/StringUtils.h" 43 #include "ConsoleCommand .h"43 #include "ConsoleCommandIncludes.h" 44 44 #include "CommandExecutor.h" 45 45 -
code/trunk/src/libraries/core/command/IRC.cc
r8858 r10624 39 39 #include "util/Exception.h" 40 40 #include "util/StringUtils.h" 41 #include "ConsoleCommand .h"41 #include "ConsoleCommandIncludes.h" 42 42 #include "TclThreadManager.h" 43 43 -
code/trunk/src/libraries/core/command/Shell.cc
r9667 r10624 42 42 #include "core/config/ConfigFileManager.h" 43 43 #include "core/config/ConfigValueIncludes.h" 44 #include "core/ PathConfig.h"44 #include "core/ApplicationPaths.h" 45 45 #include "core/input/InputBuffer.h" 46 46 #include "CommandExecutor.h" … … 84 84 85 85 // Choose the default level according to the path Orxonox was started (build directory or not) 86 OutputLevel defaultDebugLevel = ( PathConfig::buildDirectoryRun() ? DefaultLogLevel::Dev : DefaultLogLevel::User);86 OutputLevel defaultDebugLevel = (ApplicationPaths::buildDirectoryRun() ? DefaultLogLevel::Dev : DefaultLogLevel::User); 87 87 this->setLevelMax(defaultDebugLevel); 88 88 … … 164 164 void Shell::devModeChanged(bool value) 165 165 { 166 bool isNormal = (value == PathConfig::buildDirectoryRun());166 bool isNormal = (value == ApplicationPaths::buildDirectoryRun()); 167 167 if (isNormal) 168 168 { -
code/trunk/src/libraries/core/command/Shell.h
r9667 r10624 49 49 50 50 #include "util/output/BaseWriter.h" 51 #include "core/Core .h"51 #include "core/CoreConfig.h" 52 52 53 53 namespace orxonox -
code/trunk/src/libraries/core/command/TclBind.cc
r9550 r10624 37 37 #include "util/Exception.h" 38 38 #include "util/StringUtils.h" 39 #include "core/ PathConfig.h"39 #include "core/ApplicationPaths.h" 40 40 #include "CommandExecutor.h" 41 #include "ConsoleCommand .h"41 #include "ConsoleCommandIncludes.h" 42 42 #include "TclThreadManager.h" 43 43 … … 143 143 { 144 144 #ifdef DEPENDENCY_PACKAGE_ENABLE 145 if ( PathConfig::buildDirectoryRun())145 if (ApplicationPaths::buildDirectoryRun()) 146 146 return (std::string(specialConfig::dependencyLibraryDirectory) + "/tcl"); 147 147 else 148 return ( PathConfig::getRootPathString() + specialConfig::defaultLibraryPath + "/tcl");148 return (ApplicationPaths::getRootPathString() + specialConfig::defaultLibraryPath + "/tcl"); 149 149 #else 150 150 return ""; -
code/trunk/src/libraries/core/command/TclThreadManager.cc
r8858 r10624 47 47 #include "core/CoreIncludes.h" 48 48 #include "CommandExecutor.h" 49 #include "ConsoleCommand .h"49 #include "ConsoleCommandIncludes.h" 50 50 #include "TclBind.h" 51 51 #include "TclThreadList.h" -
code/trunk/src/libraries/core/config/CMakeLists.txt
r9667 r10624 1 1 ADD_SOURCE_FILES(CORE_SRC_FILES 2 CommandLineParser.cc3 2 # ConfigFile.cc is already included in FilesystemBuildUnit.cc 4 3 ConfigFileEntryValue.cc -
code/trunk/src/libraries/core/config/ConfigFile.cc
r9559 r10624 38 38 #include "util/Convert.h" 39 39 #include "util/StringUtils.h" 40 #include "core/ PathConfig.h"40 #include "core/ConfigurablePaths.h" 41 41 #include "ConfigFileEntryComment.h" 42 42 #include "ConfigFileEntryValue.h" … … 81 81 if (!filepath.is_complete()) 82 82 { 83 filepath = PathConfig::getConfigPath() / filepath;83 filepath = ConfigurablePaths::getConfigPath() / filepath; 84 84 if (this->bCopyFallbackFile_) 85 85 { … … 87 87 if (!boost::filesystem::exists(filepath)) 88 88 { 89 boost::filesystem::path defaultFilepath( PathConfig::getDataPath() / DEFAULT_CONFIG_FOLDER / this->filename_);89 boost::filesystem::path defaultFilepath(ConfigurablePaths::getDataPath() / DEFAULT_CONFIG_FOLDER / this->filename_); 90 90 if (boost::filesystem::exists(defaultFilepath)) 91 91 { … … 216 216 boost::filesystem::path filepath(filename); 217 217 if (!filepath.is_complete()) 218 filepath = PathConfig::getConfigPath() / filename;218 filepath = ConfigurablePaths::getConfigPath() / filename; 219 219 std::ofstream file; 220 220 file.open(filepath.string().c_str(), std::fstream::out); -
code/trunk/src/libraries/core/config/Configurable.cc
r9667 r10624 32 32 namespace orxonox 33 33 { 34 RegisterClassNoArgs(Configurable) ;34 RegisterClassNoArgs(Configurable).virtualBase(); 35 35 36 36 Configurable::Configurable() -
code/trunk/src/libraries/core/config/SettingsConfigFile.cc
r9569 r10624 35 35 36 36 #include "util/StringUtils.h" 37 #include "core/command/ConsoleCommand .h"37 #include "core/command/ConsoleCommandIncludes.h" 38 38 #include "ConfigFileManager.h" 39 39 #include "ConfigValueContainer.h" -
code/trunk/src/libraries/core/input/InputManager.cc
r9667 r10624 48 48 #include "core/GraphicsManager.h" 49 49 #include "core/config/ConfigValueIncludes.h" 50 #include "core/co nfig/CommandLineParser.h"51 #include "core/command/ConsoleCommand .h"50 #include "core/commandline/CommandLineIncludes.h" 51 #include "core/command/ConsoleCommandIncludes.h" 52 52 #include "core/command/Functor.h" 53 53 … … 85 85 return (lval = (InputManager::State)(lval & rval)); 86 86 } 87 88 RegisterAbstractClass(InputManager).inheritsFrom<WindowEventListener>(); 87 89 88 90 // ############################################################ -
code/trunk/src/libraries/core/input/JoyStick.cc
r9667 r10624 47 47 48 48 std::vector<std::string> JoyStick::deviceNames_s; 49 50 RegisterAbstractClass(JoyStick).inheritsFrom<Configurable>(); 49 51 50 52 JoyStick::JoyStick(unsigned int id, OIS::InputManager* oisInputManager) -
code/trunk/src/libraries/core/input/JoyStickQuantityListener.cc
r9667 r10624 36 36 std::vector<JoyStick*> JoyStickQuantityListener::joyStickList_s; 37 37 38 RegisterAbstractClass(JoyStickQuantityListener).inheritsFrom<Listable>(); 39 38 40 JoyStickQuantityListener::JoyStickQuantityListener() 39 41 { -
code/trunk/src/libraries/core/input/KeyBinder.cc
r9667 r10624 37 37 #include "core/config/ConfigValueIncludes.h" 38 38 #include "core/config/ConfigFile.h" 39 #include "core/PathConfig.h" 39 #include "core/ApplicationPaths.h" 40 #include "core/ConfigurablePaths.h" 40 41 #include "InputCommands.h" 41 42 #include "JoyStick.h" … … 43 44 namespace orxonox 44 45 { 46 RegisterAbstractClass(KeyBinder).inheritsFrom<JoyStickQuantityListener>(); 47 45 48 /** 46 49 @brief … … 253 256 orxout(internal_info, context::input) << "KeyBinder: Loading key bindings..." << endl; 254 257 255 this->configFile_ = new ConfigFile(this->filename_, ! PathConfig::buildDirectoryRun());258 this->configFile_ = new ConfigFile(this->filename_, !ApplicationPaths::buildDirectoryRun()); 256 259 this->configFile_->load(); 257 260 258 if ( PathConfig::buildDirectoryRun())261 if (ApplicationPaths::buildDirectoryRun()) 259 262 { 260 263 // Dev users should have combined key bindings files 261 std::string defaultFilepath( PathConfig::getDataPathString() + ConfigFile::DEFAULT_CONFIG_FOLDER + '/' + this->filename_);264 std::string defaultFilepath(ConfigurablePaths::getDataPathString() + ConfigFile::DEFAULT_CONFIG_FOLDER + '/' + this->filename_); 262 265 std::ifstream file(defaultFilepath.c_str()); 263 266 if (file.is_open()) … … 287 290 addButtonToCommand(binding, it->second); 288 291 std::string str = binding; 289 if ( PathConfig::buildDirectoryRun() && binding.empty())292 if (ApplicationPaths::buildDirectoryRun() && binding.empty()) 290 293 str = "NoBinding"; 291 294 it->second->setBinding(this->configFile_, this->fallbackConfigFile_, binding, bTemporary); -
code/trunk/src/libraries/core/input/KeyBinderManager.cc
r9667 r10624 31 31 #include "util/Output.h" 32 32 #include "util/Exception.h" 33 #include " util/ScopedSingletonManager.h"33 #include "core/singleton/ScopedSingletonIncludes.h" 34 34 #include "core/config/ConfigValueIncludes.h" 35 35 #include "core/CoreIncludes.h" 36 36 #include "core/LuaState.h" 37 #include "core/command/ConsoleCommand .h"37 #include "core/command/ConsoleCommandIncludes.h" 38 38 #include "InputManager.h" 39 39 #include "KeyDetector.h" … … 41 41 namespace orxonox 42 42 { 43 ManageScopedSingleton(KeyBinderManager, ScopeID::G raphics, false);43 ManageScopedSingleton(KeyBinderManager, ScopeID::GRAPHICS, false); 44 44 45 45 static const std::string __CC_keybind_name = "keybind"; … … 52 52 SetConsoleCommand(__CC_unbind_name, &KeyBinderManager::unbind).defaultValues(""); 53 53 SetConsoleCommand(__CC_tunbind_name, &KeyBinderManager::tunbind).defaultValues(""); 54 55 RegisterAbstractClass(KeyBinderManager).inheritsFrom<Configurable>(); 54 56 55 57 KeyBinderManager::KeyBinderManager() -
code/trunk/src/libraries/core/input/KeyDetector.cc
r7284 r10624 29 29 #include "KeyDetector.h" 30 30 31 #include "util/ScopedSingletonManager.h"32 31 #include "core/CoreIncludes.h" 33 #include "core/command/ConsoleCommand.h" 32 #include "core/singleton/ScopedSingletonIncludes.h" 33 #include "core/command/ConsoleCommandIncludes.h" 34 34 #include "Button.h" 35 35 #include "InputManager.h" … … 38 38 namespace orxonox 39 39 { 40 ManageScopedSingleton(KeyDetector, ScopeID::G raphics, false);40 ManageScopedSingleton(KeyDetector, ScopeID::GRAPHICS, false); 41 41 42 42 static const std::string __CC_KeyDetector_callback_name = "KeyDetectorKeyPressed"; 43 43 DeclareConsoleCommand(__CC_KeyDetector_callback_name, &prototype::void__string).hide(); 44 45 RegisterAbstractClass(KeyDetector).inheritsFrom<KeyBinder>(); 44 46 45 47 KeyDetector::KeyDetector() -
code/trunk/src/libraries/core/input/Mouse.cc
r9667 r10624 31 31 #include <ois/OISMouse.h> 32 32 #include "core/CoreIncludes.h" 33 #include "core/command/ConsoleCommand .h"33 #include "core/command/ConsoleCommandIncludes.h" 34 34 #include "InputState.h" 35 35 … … 50 50 SetConsoleCommand(__CC_Mouse_name, __CC_ungrab_name, &Mouse::ungrab); 51 51 #endif 52 53 RegisterAbstractClass(Mouse).inheritsFrom<WindowEventListener>(); 52 54 53 55 Mouse::Mouse(unsigned int id, OIS::InputManager* oisInputManager) -
code/trunk/src/libraries/core/object/CMakeLists.txt
r9667 r10624 2 2 Context.cc 3 3 Destroyable.cc 4 DestroyLaterManager.cc 4 5 Listable.cc 5 6 ObjectListBase.cc -
code/trunk/src/libraries/core/object/Context.cc
r9667 r10624 76 76 /*static*/ void Context::setRootContext(Context* context) 77 77 { 78 if (Context::rootContext_s)79 delete Context::rootContext_s;80 78 Context::rootContext_s = context; 79 } 80 81 /*static*/ void Context::destroyRootContext() 82 { 83 delete Context::rootContext_s; 84 Context::rootContext_s = NULL; 81 85 } 82 86 83 87 /*static*/ Context* Context::getRootContext() 84 88 { 85 if (!Context::rootContext_s) 86 Context::rootContext_s = new Context(NULL); 89 OrxVerify(Context::rootContext_s != NULL, "Root Context is undefined"); 87 90 return Context::rootContext_s; 88 91 } … … 97 100 return this->objectLists_[classID]; 98 101 } 102 103 void Context::destroyObjectList(const Identifier* identifier) 104 { 105 ObjectListBase* objectList = this->getObjectList(identifier); 106 delete objectList; 107 this->objectLists_[identifier->getClassID()] = NULL; 108 } 99 109 } -
code/trunk/src/libraries/core/object/Context.h
r9667 r10624 47 47 public: 48 48 static void setRootContext(Context* context); 49 static void destroyRootContext(); 49 50 static Context* getRootContext(); 50 51 … … 71 72 } 72 73 74 void destroyObjectList(const Identifier* identifier); 75 73 76 private: 74 77 Context* parentContext_; -
code/trunk/src/libraries/core/object/Destroyable.cc
r9944 r10624 33 33 34 34 #include "Destroyable.h" 35 #include "DestroyLaterManager.h" 35 36 36 37 #include <cassert> … … 60 61 61 62 /** 62 @brief Deletes the object if no @ref orxonox::S martPtr "smartpointers" point to this object. Otherwise schedules the object to be deleted as soon as possible.63 Always call destroy() instead of using 'delete' directly, otherwise s martpointers won't work.63 @brief Deletes the object if no @ref orxonox::StrongPtr "strong pointers" point to this object. Otherwise schedules the object to be deleted as soon as possible. 64 Always call destroy() instead of using 'delete' directly, otherwise strong pointers won't work. 64 65 */ 65 66 void Destroyable::destroy() … … 74 75 } 75 76 } 77 78 /** 79 * Works like @ref destroy() but doesn't destroy the object until the current tick has ended. 80 */ 81 void Destroyable::destroyLater() 82 { 83 // register in DestroyLaterManager - this ensures that a strongPtr points to this object and keeps it alive for a while 84 DestroyLaterManager::getInstance().retain(this); 85 86 // request destruction -> object will be deleted after all strongPtrs (including the one in DestroyLaterManager) were destroyed. 87 this->destroy(); 88 } 76 89 } -
code/trunk/src/libraries/core/object/Destroyable.h
r9944 r10624 30 30 @file 31 31 @ingroup Object 32 @brief Declaration of Destroyable, the base class of all objects which can be used with S martPtr and WeakPtr.32 @brief Declaration of Destroyable, the base class of all objects which can be used with StrongPtr and WeakPtr. 33 33 */ 34 34 … … 43 43 { 44 44 /** 45 @brief Classes must inherit from this class if they should be used with S martPtr or WeakPtr.45 @brief Classes must inherit from this class if they should be used with StrongPtr or WeakPtr. 46 46 */ 47 47 class _CoreExport Destroyable 48 48 { 49 49 template <class T> 50 friend class S martPtr;50 friend class StrongPtr; 51 51 52 52 friend class DestructionListener; … … 57 57 58 58 void destroy(); 59 void destroyLater(); 59 60 60 /// Returns the number of @ref orxonox::S martPtr "smartpointers" that point to this object.61 /// Returns the number of @ref orxonox::StrongPtr "strong pointers" that point to this object. 61 62 inline unsigned int getReferenceCount() const 62 63 { return this->referenceCount_; } 63 64 64 65 protected: 65 /// This virtual function is called if destroy() is called and no S martPtr points to this object. Used in some cases to create a new SmartPtr to66 /// This virtual function is called if destroy() is called and no StrongPtr points to this object. Used in some cases to create a new StrongPtr to 66 67 /// prevent destruction. Don't call this function directly - use destroy() instead. 67 68 virtual void preDestroy() {} 68 69 69 70 private: 70 /// Increments the reference counter (for s martpointers).71 /// Increments the reference counter (for strong pointers). 71 72 inline void incrementReferenceCount() 72 73 { ++this->referenceCount_; } 73 /// Decrements the reference counter (for s martpointers).74 /// Decrements the reference counter (for strong pointers). 74 75 inline void decrementReferenceCount() 75 76 { … … 86 87 { this->destructionListeners_.erase(pointer); } 87 88 88 int referenceCount_; //!< Counts the references from s martpointers to this object89 int referenceCount_; //!< Counts the references from strong pointers to this object 89 90 bool requestedDestruction_; //!< Becomes true after someone called delete on this object 90 91 std::set<DestructionListener*> destructionListeners_; //!< All destruction listeners (for example weak pointers which point to this object and like to get notified if it dies) -
code/trunk/src/libraries/core/object/Iterator.h
r9667 r10624 76 76 @brief Constructor: Sets the element, whereon the iterator points, to zero. 77 77 */ 78 inline Iterator() : IteratorBase<T, Iterator<T> >( NULL) {}78 inline Iterator() : IteratorBase<T, Iterator<T> >() {} 79 79 80 80 /** … … 88 88 @param other The other Iterator 89 89 */ 90 inline Iterator(const Iterator <T>& other) : IteratorBase<T, Iterator<T> >(other) {}90 inline Iterator(const IteratorBase<T, Iterator<T> >& other) : IteratorBase<T, Iterator<T> >(other) {} 91 91 92 92 /** -
code/trunk/src/libraries/core/object/IteratorBase.h
r9667 r10624 37 37 38 38 #include "core/CorePrereqs.h" 39 40 #include <boost/static_assert.hpp> 41 #include <boost/type_traits/is_base_of.hpp> 39 42 40 43 #include "ObjectListBase.h" … … 49 52 class IteratorBase : public ObjectListElementRemovalListener 50 53 { 54 BOOST_STATIC_ASSERT((boost::is_base_of<Listable, T>::value)); 55 56 protected: 57 /** 58 @brief Constructor: Sets the element, whereon the iterator points, to the given element. 59 This constructor is protected and only for internal usage (don't mess with the BaseElements directly). 60 */ 61 inline IteratorBase(ObjectListBaseElement* element = NULL) 62 { 63 this->element_ = element; 64 this->registerIterator(); 65 } 66 67 51 68 public: 52 69 /** 53 @brief Constructor: Sets the element, whereon the iterator points, to zero. 54 */ 55 inline IteratorBase(ObjectListBaseElement* element) 56 { 70 @brief Constructor: Sets the element, whereon the iterator points, to the given element. 71 */ 72 inline IteratorBase(ObjectListElement<T>* element) 73 { 74 this->element_ = element; 75 this->registerIterator(); 76 } 77 78 /** 79 @brief Constructor: Sets the element, whereon the iterator points, to the given element of another type. 80 The element's type O must be a derivative of the Iterator's type T. 81 */ 82 template <class O> 83 inline IteratorBase(ObjectListElement<O>* element) 84 { 85 (void)static_cast<T*>((O*)NULL); // Check type: The element's type O must be a derivative of the Iterator's type T. 57 86 this->element_ = element; 58 87 this->registerIterator(); -
code/trunk/src/libraries/core/object/Listable.cc
r9667 r10624 39 39 namespace orxonox 40 40 { 41 RegisterClass(Listable) ;41 RegisterClass(Listable).virtualBase(); 42 42 43 43 /** -
code/trunk/src/libraries/core/object/ObjectList.h
r9667 r10624 47 47 #include "core/CorePrereqs.h" 48 48 49 #include <boost/static_assert.hpp> 50 #include <boost/type_traits/is_base_of.hpp> 51 49 52 #include "ObjectListBase.h" 50 53 #include "ObjectListIterator.h" … … 66 69 class ObjectList 67 70 { 71 BOOST_STATIC_ASSERT((boost::is_base_of<Listable, T>::value)); 72 68 73 public: 69 74 typedef ObjectListIterator<T> iterator; 70 75 76 /// Returns the size of the list (for the root context) 77 inline static size_t size() 78 { return size(Context::getRootContext()); } 71 79 /// Returns the size of the list 72 inline static size_t size( )80 inline static size_t size(Context* context) 73 81 { 74 return Context::getRootContext()->getObjectList<T>()->size();82 return context->getObjectList<T>()->size(); 75 83 } 76 84 85 /// Returns an Iterator to the first element in the list (for the root context). 86 inline static ObjectListElement<T>* begin() 87 { return begin(Context::getRootContext()); } 77 88 /// Returns an Iterator to the first element in the list. 78 inline static ObjectListElement<T>* begin( )89 inline static ObjectListElement<T>* begin(Context* context) 79 90 { 80 ObjectListBase* list = Context::getRootContext()->getObjectList<T>();91 ObjectListBase* list = context->getObjectList<T>(); 81 92 return static_cast<ObjectListElement<T>*>(list->begin()); 82 93 } 83 94 95 /// Returns an Iterator to the element after the last element in the list (for the root context). 96 inline static ObjectListElement<T>* end() 97 { return end(Context::getRootContext()); } 84 98 /// Returns an Iterator to the element after the last element in the list. 85 inline static ObjectListElement<T>* end( )99 inline static ObjectListElement<T>* end(Context* context) 86 100 { 87 ObjectListBase* list = Context::getRootContext()->getObjectList<T>();101 ObjectListBase* list = context->getObjectList<T>(); 88 102 return static_cast<ObjectListElement<T>*>(list->end()); 89 103 } 90 104 105 /// Returns an Iterator to the last element in the list (for the root context). 106 inline static ObjectListElement<T>* rbegin() 107 { return rbegin(Context::getRootContext()); } 91 108 /// Returns an Iterator to the last element in the list. 92 inline static ObjectListElement<T>* rbegin( )109 inline static ObjectListElement<T>* rbegin(Context* context) 93 110 { 94 ObjectListBase* list = Context::getRootContext()->getObjectList<T>();111 ObjectListBase* list = context->getObjectList<T>(); 95 112 return static_cast<ObjectListElement<T>*>(list->rbegin()); 96 113 } 97 114 115 /// Returns an Iterator to the element before the first element in the list (for the root context). 116 inline static ObjectListElement<T>* rend() 117 { return rend(Context::getRootContext()); } 98 118 /// Returns an Iterator to the element before the first element in the list. 99 inline static ObjectListElement<T>* rend( )119 inline static ObjectListElement<T>* rend(Context* context) 100 120 { 101 ObjectListBase* list = Context::getRootContext()->getObjectList<T>();121 ObjectListBase* list = context->getObjectList<T>(); 102 122 return static_cast<ObjectListElement<T>*>(list->rend()); 103 123 } -
code/trunk/src/libraries/core/object/ObjectListIterator.h
r9667 r10624 74 74 @brief Constructor: Sets the element, whereon the ObjectListIterator points, to zero. 75 75 */ 76 inline ObjectListIterator() : IteratorBase<T, ObjectListIterator<T> >( NULL) {}76 inline ObjectListIterator() : IteratorBase<T, ObjectListIterator<T> >() {} 77 77 78 78 /** -
code/trunk/src/libraries/core/object/WeakPtr.h
r9571 r10624 104 104 } 105 105 106 /// Constructor: Used to explicitly initialize the weak pointer with a null pointer107 inline WeakPtr(int) : pointer_(0), base_(0), callback_(0)108 {109 }110 111 106 /// Constructor: Initializes the weak pointer with a pointer to an object. 112 107 inline WeakPtr(T* pointer) : pointer_(pointer), base_(pointer), callback_(0) … … 132 127 { 133 128 this->unregisterAsDestructionListener(this->base_); 134 }135 136 /// Used to assign a null pointer.137 inline WeakPtr& operator=(int)138 {139 WeakPtr(0).swap(*this);140 return *this;141 129 } 142 130
Note: See TracChangeset
for help on using the changeset viewer.