Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 5, 2009, 1:34:10 AM (15 years ago)
Author:
rgrieder
Message:

Added new an option for the ScopedSingletonManager that can allow the Singleton to fail (throw an exception).
Also improved exception-safety in Scope so that when for a Singleton fails, the Scope will deactivate all activated listeners and properly destroy itself.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core5/src/libraries/util/Scope.h

    r5867 r5877  
    3535#include <map>
    3636#include <set>
     37
    3738#include "Debug.h"
     39#include "ScopeGuard.h"
    3840
    3941namespace orxonox
     
    6365        protected:
    6466            //! Constructor: Registers the instance.
    65             ScopeListener(ScopeID::Value scope) : scope_(scope)
     67            ScopeListener(ScopeID::Value scope) : scope_(scope), bActivated_(false)
    6668                { ScopeManager::listeners_s[this->scope_].insert(this); }
    6769            //! Destructor: Unregisters the instance.
     
    7678        private:
    7779            ScopeID::Value scope_; //!< Store the scope to unregister on destruction
     80            bool bActivated_;
    7881    };
    7982
     
    9194            Scope()
    9295            {
    93                 ScopeManager::instanceCounts_s[scope]++;
    94                 assert(ScopeManager::instanceCounts_s[scope] > 0);
    95                 if (ScopeManager::instanceCounts_s[scope] == 1)
     96                try
    9697                {
    97                     for (typename std::set<ScopeListener*>::iterator it = ScopeManager::listeners_s[scope].begin(); it != ScopeManager::listeners_s[scope].end(); )
    98                         (*(it++))->activated();
     98                    ScopeManager::instanceCounts_s[scope]++;
     99                    assert(ScopeManager::instanceCounts_s[scope] > 0);
     100                    if (ScopeManager::instanceCounts_s[scope] == 1)
     101                    {
     102                        Loki::ScopeGuard deactivator = Loki::MakeObjGuard(*this, &Scope::deactivateListeners);
     103                        for (typename std::set<ScopeListener*>::iterator it = ScopeManager::listeners_s[scope].begin(); it != ScopeManager::listeners_s[scope].end(); )
     104                        {
     105                            (*it)->activated();
     106                            (*(it++))->bActivated_ = true;
     107                        }
     108                        deactivator.Dismiss();
     109                    }
     110                }
     111                catch (...)
     112                {
     113                    ScopeManager::instanceCounts_s[scope]--;
     114                    throw;
    99115                }
    100116            }
     
    111127
    112128                if (ScopeManager::instanceCounts_s[scope] == 0)
     129                    this->deactivateListeners();
     130            }
     131
     132            void deactivateListeners()
     133            {
     134                for (typename std::set<ScopeListener*>::iterator it = ScopeManager::listeners_s[scope].begin(); it != ScopeManager::listeners_s[scope].end(); )
    113135                {
    114                     for (typename std::set<ScopeListener*>::iterator it = ScopeManager::listeners_s[scope].begin(); it != ScopeManager::listeners_s[scope].end(); )
    115                         (*(it++))->deactivated();
     136                    if ((*it)->bActivated_)
     137                    {
     138                        try
     139                            { (*it)->deactivated(); }
     140                        catch (...)
     141                            { COUT(0) << "ScopeListener::deactivated() failed! This MUST NOT happen, fix it!" << std::endl; }
     142                        (*(it++))->bActivated_ = false;
     143                    }
     144                    else
     145                        ++it;
    116146                }
    117147            }
Note: See TracChangeset for help on using the changeset viewer.