Changeset 10461
- Timestamp:
- May 24, 2015, 11:29:21 PM (10 years ago)
- Location:
- code/branches/core7/src/libraries/core/singleton
- Files:
-
- 2 edited
- 1 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core7/src/libraries/core/singleton/CMakeLists.txt
r10460 r10461 1 1 ADD_SOURCE_FILES(CORE_SRC_FILES 2 Scope .cc2 ScopeManager.cc 3 3 ScopedSingletonIncludes.cc 4 4 ) -
code/branches/core7/src/libraries/core/singleton/Scope.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. 32 @brief Declaration of the classes that are needed to use Scopes: orxonox::Scope and orxonox::ScopeListener. 34 33 35 34 @anchor Scope … … 38 37 an its template argument defines the name of the virtual scope. See orxonox::ScopeID for an enumeration of the 39 38 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 the41 corresponding orxonox::Scope object changes its state.39 Instances of orxonox::ScopeListener can register in orxonox::ScopeMAnager for a given @a scope and will get a 40 notification if the corresponding orxonox::Scope object changes its state. 42 41 43 42 To avoid multiple instances of orxonox::Scope<@a scope> in different libraries, each instance of orxonox::Scope … … 60 59 61 60 #include "util/Output.h" 61 #include "ScopeManager.h" 62 62 63 63 namespace orxonox 64 64 { 65 /**66 @brief The ScopeManager stores the variables of the Scope templates in a statically linked context.67 68 If all Scope objects are managed by this class, they are statically linked in the core library.69 Without this, a new instance of Scope<T> for each T would be created in every library of Orxonox,70 which is of course not the desired behavior.71 72 @see See @ref Scope "this description" for details about the interrelationship of Scope, ScopeListener, and ScopeManager.73 */74 class _CoreExport ScopeManager75 {76 template <ScopeID::Value scope>77 friend class Scope;78 friend class StaticallyInitializedScopedSingletonWrapper;79 80 private:81 static std::map<ScopeID::Value, int>& getInstanceCounts(); //!< Counts the number of active instances (>0 means active) for a scope82 static std::map<ScopeID::Value, std::set<ScopeListener*> >& getListeners(); //!< Stores all listeners for a scope83 };84 85 65 /** 86 66 @brief ScopeListeners register themselves in the corresponding Scope and wait for notifications. -
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.