- Timestamp:
- May 24, 2015, 11:29:21 PM (9 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core7/src/libraries/core/singleton/ScopeManager.h
r10460 r10461 30 30 @file 31 31 @ingroup SingletonScope 32 @brief Declaration of the classes that are needed to use Scopes: 33 orxonox::Scope, orxonox::ScopeListener, and orxonox::ScopeManager. 34 35 @anchor Scope 36 37 A virtual scope can be represented by an instance of class orxonox::Scope. orxonox::Scope<@a scope> is a template 38 an its template argument defines the name of the virtual scope. See orxonox::ScopeID for an enumeration of the 39 available values for @a scope. The orxonox::Scope object for a given @a scope can be activated or deactivated. 40 Instances of orxonox::ScopeListener can register for a given @a scope and will get a notification if the 41 corresponding orxonox::Scope object changes its state. 42 43 To avoid multiple instances of orxonox::Scope<@a scope> in different libraries, each instance of orxonox::Scope 44 registers in orxonox::ScopeManager, where they are linked statically in the core library. 45 46 Scopes are usually used to control the creation and destruction of Singletons. 47 48 @see orxonox::Singleton 32 @brief Declaration of orxonox::ScopeManager. 49 33 */ 50 34 51 #ifndef __ Core_Scope_H__52 #define __ Core_Scope_H__35 #ifndef __ScopeManager_H__ 36 #define __ScopeManager_H__ 53 37 54 38 #include "core/CorePrereqs.h" 55 39 56 #include <cassert>57 40 #include <map> 58 41 #include <set> 59 #include <loki/ScopeGuard.h>60 61 #include "util/Output.h"62 42 63 43 namespace orxonox … … 82 62 static std::map<ScopeID::Value, std::set<ScopeListener*> >& getListeners(); //!< Stores all listeners for a scope 83 63 }; 84 85 /**86 @brief ScopeListeners register themselves in the corresponding Scope and wait for notifications.87 Notifications are sent if a Scope is activated or deactivated.88 89 @see See @ref Scope "this description" for details about the interrelationship of Scope, ScopeListener, and ScopeManager.90 */91 class _CoreExport ScopeListener92 {93 template <ScopeID::Value scope>94 friend class Scope;95 96 protected:97 ScopeListener(ScopeID::Value scope) : scope_(scope), bActivated_(false) { }98 virtual ~ScopeListener() { }99 100 //! Gets called if the scope is activated101 virtual void activated() = 0;102 //! Gets called if the scope is deactivated103 virtual void deactivated() = 0;104 105 public:106 inline ScopeID::Value getScope() const107 { return this->scope_; }108 109 private:110 ScopeID::Value scope_; //!< Store the scope to unregister on destruction111 bool bActivated_;112 };113 114 /**115 @brief A scope for a given template argument is either active or not.116 117 Objects inheriting from a ScopeListener are registered in a list (different for each scope).118 If the scope gets activated or deactivated, all objects in this list are notified.119 120 @see See @ref Scope "this description" for details about the interrelationship of Scope, ScopeListener, and ScopeManager.121 */122 template <ScopeID::Value scope>123 class Scope124 {125 public:126 //! Constructor: Increases the instance counter and activates the scope if the count went from 0 to 1. Counts >1 don't change anything.127 Scope()128 {129 orxout(internal_status) << "creating scope... (" << scope << ")" << endl;130 131 try132 {133 ScopeManager::getInstanceCounts()[scope]++;134 assert(ScopeManager::getInstanceCounts()[scope] > 0);135 if (ScopeManager::getInstanceCounts()[scope] == 1)136 {137 Loki::ScopeGuard deactivator = Loki::MakeObjGuard(*this, &Scope::deactivateListeners);138 for (typename std::set<ScopeListener*>::iterator it = ScopeManager::getListeners()[scope].begin(); it != ScopeManager::getListeners()[scope].end(); )139 {140 (*it)->activated();141 (*(it++))->bActivated_ = true;142 }143 deactivator.Dismiss();144 }145 }146 catch (...)147 {148 ScopeManager::getInstanceCounts()[scope]--;149 throw;150 }151 152 orxout(internal_status) << "created scope (" << scope << ")" << endl;153 }154 155 //! Destructor: Decreases the instance counter and deactivates the scope if the count went from 1 to 0. Counts >0 don't change anything.156 ~Scope()157 {158 orxout(internal_status) << "destroying scope... (" << scope << ")" << endl;159 160 ScopeManager::getInstanceCounts()[scope]--;161 162 // This shouldn't happen but just to be sure: check if the count is positive163 assert(ScopeManager::getInstanceCounts()[scope] >= 0);164 if (ScopeManager::getInstanceCounts()[scope] < 0)165 ScopeManager::getInstanceCounts()[scope] = 0;166 167 if (ScopeManager::getInstanceCounts()[scope] == 0)168 this->deactivateListeners();169 170 orxout(internal_status) << "destroyed scope (" << scope << ")" << endl;171 }172 173 //! Deactivates the listeners of this scope in case the scope is destroyed or the construction fails.174 void deactivateListeners()175 {176 for (typename std::set<ScopeListener*>::iterator it = ScopeManager::getListeners()[scope].begin(); it != ScopeManager::getListeners()[scope].end(); )177 {178 if ((*it)->bActivated_)179 {180 try181 { (*it)->deactivated(); }182 catch (...)183 { orxout(internal_warning) << "ScopeListener::deactivated() failed! This MUST NOT happen, fix it!" << endl; }184 (*(it++))->bActivated_ = false;185 }186 else187 ++it;188 }189 }190 191 //! Returns true if the scope is active.192 static bool isActive()193 {194 return (ScopeManager::getInstanceCounts()[scope] > 0);195 }196 };197 64 } 198 65 199 #endif /* __ Core_Scope_H__ */66 #endif /* __ScopeManager_H__ */
Note: See TracChangeset
for help on using the changeset viewer.