diff --git a/src/ActorUtil.cpp b/src/ActorUtil.cpp index 10ebe3900a..7ea333d5d5 100644 --- a/src/ActorUtil.cpp +++ b/src/ActorUtil.cpp @@ -14,22 +14,26 @@ // Actor registration -static map *g_pmapRegistrees = NULL; +map & GetRegistrees() +{ + static map registrees; + return registrees; +} static bool IsRegistered( const RString& sClassName ) { - return g_pmapRegistrees->find( sClassName ) != g_pmapRegistrees->end(); + map & registrees = GetRegistrees(); + return registrees.find( sClassName ) != registrees.end(); } void ActorUtil::Register( const RString& sClassName, CreateActorFn pfn ) { - if( g_pmapRegistrees == NULL ) - g_pmapRegistrees = smnew map; + map & registrees = GetRegistrees(); - map::iterator iter = g_pmapRegistrees->find( sClassName ); - ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Actor class '%s' already registered.", sClassName.c_str()) ); + map::iterator iter = registrees.find( sClassName ); + ASSERT_M( iter == registrees.end(), ssprintf("Actor class '%s' already registered.", sClassName.c_str()) ); - (*g_pmapRegistrees)[sClassName] = pfn; + registrees[sClassName] = pfn; } bool ActorUtil::ResolvePath( RString &sPath, const RString &sName ) @@ -119,8 +123,10 @@ Actor* ActorUtil::LoadFromNode( const XNode* pNode, Actor *pParentActor ) if( !bHasClass ) bHasClass = pNode->GetAttrValue( "Type", sClass ); - map::iterator iter = g_pmapRegistrees->find( sClass ); - if( iter == g_pmapRegistrees->end() ) + map & registrees = GetRegistrees(); + + map::iterator iter = registrees.find( sClass ); + if( iter == registrees.end() ) { // sClass is invalid RString sError = ssprintf( "%s: invalid Class \"%s\"", diff --git a/src/Font.cpp b/src/Font.cpp index 0fffb5cb92..1cc161929c 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -741,8 +741,6 @@ void Font::Load( const RString &sIniPath, RString sChars ) { const RString &sTexturePath = asTexturePaths[i]; - FontPage *pPage = smnew FontPage; - // Grab the page name, eg "foo" from "Normal [foo].png". RString sPagename = GetPageNameFromFileName( sTexturePath ); @@ -750,6 +748,9 @@ void Font::Load( const RString &sIniPath, RString sChars ) if( sTexturePath.find("-stroke") != string::npos ) continue; + // Create this down here so it doesn't leak if the continue gets triggered. + FontPage *pPage = smnew FontPage; + // Load settings for this page from the INI. FontPageSettings cfg; LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars ); diff --git a/src/LocalizedString.cpp b/src/LocalizedString.cpp index a025ec941b..a334a6ea7b 100644 --- a/src/LocalizedString.cpp +++ b/src/LocalizedString.cpp @@ -4,7 +4,11 @@ #include "RageUtil.h" #include "SubscriptionManager.h" -static SubscriptionManager m_Subscribers; +SubscriptionManager & GetSubscribers() +{ + static SubscriptionManager subscribers; + return subscribers; +} class LocalizedStringImplDefault: public ILocalizedStringImpl { @@ -27,7 +31,7 @@ static LocalizedString::MakeLocalizer g_pMakeLocalizedStringImpl = LocalizedStri void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc ) { g_pMakeLocalizedStringImpl = pFunc; - FOREACHS( LocalizedString*, *m_Subscribers.m_pSubscribers, l ) + FOREACHS( LocalizedString*, GetSubscribers().m_pSubscribers, l ) { LocalizedString *pLoc = *l; pLoc->CreateImpl(); @@ -36,7 +40,7 @@ void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc ) LocalizedString::LocalizedString( const RString& sGroup, const RString& sName ) { - m_Subscribers.Subscribe( this ); + GetSubscribers().Subscribe( this ); m_sGroup = sGroup; m_sName = sName; @@ -47,7 +51,7 @@ LocalizedString::LocalizedString( const RString& sGroup, const RString& sName ) LocalizedString::~LocalizedString() { - m_Subscribers.Unsubscribe( this ); + GetSubscribers().Unsubscribe( this ); SAFE_DELETE( m_pImpl ); } diff --git a/src/LuaBinding.cpp b/src/LuaBinding.cpp index f65d61cdc4..7399fb9321 100644 --- a/src/LuaBinding.cpp +++ b/src/LuaBinding.cpp @@ -5,18 +5,25 @@ #include "Foreach.h" #include "SubscriptionManager.h" -static SubscriptionManager m_Subscribers; + +SubscriptionManager & GetSubscribers() +{ + static SubscriptionManager subscribers; + return subscribers; +} namespace { void RegisterTypes( lua_State *L ) { - if( m_Subscribers.m_pSubscribers == NULL ) + SubscriptionManager & subscribers = GetSubscribers(); + + if( subscribers.m_pSubscribers.empty() ) return; /* Register base classes first. */ map mapToRegister; - FOREACHS( LuaBinding*, *m_Subscribers.m_pSubscribers, p ) + FOREACHS( LuaBinding*, subscribers.m_pSubscribers, p ) mapToRegister[(*p)->GetClassName()] = (*p); set setRegisteredAlready; @@ -59,12 +66,12 @@ REGISTER_WITH_LUA_FUNCTION( RegisterTypes ); LuaBinding::LuaBinding() { - m_Subscribers.Subscribe( this ); + GetSubscribers().Subscribe( this ); } LuaBinding::~LuaBinding() { - m_Subscribers.Unsubscribe( this ); + GetSubscribers().Unsubscribe( this ); } void LuaBinding::Register( lua_State *L ) diff --git a/src/LuaManager.cpp b/src/LuaManager.cpp index 9d54f92b3b..d81d9cade1 100644 --- a/src/LuaManager.cpp +++ b/src/LuaManager.cpp @@ -226,17 +226,17 @@ static int LuaPanic( lua_State *L ) } // Actor registration -static vector *g_vRegisterActorTypes = NULL; +vector & GetRegisteredActorTypes() +{ + static vector registeredActorTypes; + return registeredActorTypes; +} void LuaManager::Register( RegisterWithLuaFn pfn ) { - if( g_vRegisterActorTypes == NULL ) - g_vRegisterActorTypes = smnew vector; - - g_vRegisterActorTypes->push_back( pfn ); + GetRegisteredActorTypes().push_back( pfn ); } - LuaManager::LuaManager() { pImpl = smnew Impl; @@ -360,13 +360,12 @@ void LuaManager::RegisterTypes() { Lua *L = Get(); - if( g_vRegisterActorTypes ) + vector & registeredActorTypes = GetRegisteredActorTypes(); + + for( unsigned i=0; isize(); i++ ) - { - RegisterWithLuaFn fn = (*g_vRegisterActorTypes)[i]; - fn( L ); - } + RegisterWithLuaFn fn = registeredActorTypes[i]; + fn( L ); } Release( L ); diff --git a/src/MenuTimer.cpp b/src/MenuTimer.cpp index 4435370484..6211dc203b 100644 --- a/src/MenuTimer.cpp +++ b/src/MenuTimer.cpp @@ -22,6 +22,11 @@ MenuTimer::MenuTimer() WARNING_COMMAND = NULL; } +MenuTimer::~MenuTimer() +{ + delete WARNING_COMMAND; +} + void MenuTimer::Load( RString sMetricsGroup ) { m_sprFrame.Load( THEME->GetPathG(sMetricsGroup, "Frame") ); diff --git a/src/MenuTimer.h b/src/MenuTimer.h index cd3a211c54..f95c5c5c1b 100644 --- a/src/MenuTimer.h +++ b/src/MenuTimer.h @@ -15,6 +15,7 @@ class MenuTimer : public ActorFrame { public: MenuTimer(); + virtual ~MenuTimer(); void Load( RString sMetricsGroup ); virtual void Update( float fDeltaTime ); diff --git a/src/Preference.cpp b/src/Preference.cpp index 50792ed0b5..15ccdeafe8 100644 --- a/src/Preference.cpp +++ b/src/Preference.cpp @@ -7,23 +7,27 @@ #include "SubscriptionManager.h" #include "Foreach.h" -static SubscriptionManager m_Subscribers; +SubscriptionManager & GetSubscribers() +{ + static SubscriptionManager subscribers; + return subscribers; +} IPreference::IPreference( const RString& sName ): m_sName( sName ), m_bIsStatic( false ) { - m_Subscribers.Subscribe( this ); + GetSubscribers().Subscribe( this ); } IPreference::~IPreference() { - m_Subscribers.Unsubscribe( this ); + GetSubscribers().Unsubscribe( this ); } IPreference *IPreference::GetPreferenceByName( const RString &sName ) { - FOREACHS( IPreference*, *m_Subscribers.m_pSubscribers, p ) + FOREACHS( IPreference*, GetSubscribers().m_pSubscribers, p ) { if( !(*p)->GetName().CompareNoCase( sName ) ) return *p; @@ -34,20 +38,20 @@ IPreference *IPreference::GetPreferenceByName( const RString &sName ) void IPreference::LoadAllDefaults() { - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) + FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p ) (*p)->LoadDefault(); } void IPreference::ReadAllPrefsFromNode( const XNode* pNode, bool bIsStatic ) { ASSERT( pNode != NULL ); - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) + FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p ) (*p)->ReadFrom( pNode, bIsStatic ); } void IPreference::SavePrefsToNode( XNode* pNode ) { - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) + FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p ) (*p)->WriteTo( pNode ); } @@ -55,7 +59,7 @@ void IPreference::ReadAllDefaultsFromNode( const XNode* pNode ) { if( pNode == NULL ) return; - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) + FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p ) (*p)->ReadDefaultFrom( pNode ); } diff --git a/src/RageThreads.cpp b/src/RageThreads.cpp index bbd02d5294..d1d0121341 100644 --- a/src/RageThreads.cpp +++ b/src/RageThreads.cpp @@ -138,8 +138,8 @@ struct ThreadSlot *g_pUnknownThreadSlot = NULL; * so possibly racing over them is harmless (simply using a stale thread ID, etc). */ static RageMutex &GetThreadSlotsLock() { - static RageMutex *pLock = smnew RageMutex( "ThreadSlots" ); - return *pLock; + static RageMutex lock( "ThreadSlots" ); + return lock; } static int FindEmptyThreadSlot() diff --git a/src/ScreenDebugOverlay.cpp b/src/ScreenDebugOverlay.cpp index d043581972..74c8e16cba 100644 --- a/src/ScreenDebugOverlay.cpp +++ b/src/ScreenDebugOverlay.cpp @@ -52,15 +52,18 @@ static LocalizedString ON ( "ScreenDebugOverlay", "on" ); static LocalizedString OFF ( "ScreenDebugOverlay", "off" ); class IDebugLine; -static vector *g_pvpSubscribers = NULL; +vector & GetSubscribers() +{ + static vector subscribers; + return subscribers; +} + class IDebugLine { public: IDebugLine() { - if( g_pvpSubscribers == NULL ) - g_pvpSubscribers = smnew vector; - g_pvpSubscribers->push_back( this ); + GetSubscribers().push_back( this ); } virtual ~IDebugLine() { } enum Type { all_screens, gameplay_only }; @@ -215,7 +218,7 @@ void ScreenDebugOverlay::Init() map iNextDebugButton; int iNextGameplayButton = 0; - FOREACH( IDebugLine*, *g_pvpSubscribers, p ) + FOREACH( IDebugLine*, GetSubscribers(), p ) { RString sPageName = (*p)->GetPageName(); @@ -271,7 +274,7 @@ void ScreenDebugOverlay::Init() this->AddChild( p ); } - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + FOREACH_CONST( IDebugLine*, GetSubscribers(), p ) { { BitmapText *bt = smnew BitmapText; @@ -350,13 +353,15 @@ void ScreenDebugOverlay::UpdateText() m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" ); } + vector & subscribers = GetSubscribers(); + // todo: allow changing of various spacing/location things -aj int iOffset = 0; - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + FOREACH_CONST( IDebugLine*, subscribers, p ) { RString sPageName = (*p)->GetPageName(); - int i = p-g_pvpSubscribers->begin(); + int i = p-subscribers.begin(); float fY = LINE_START_Y + iOffset * LINE_SPACING; @@ -447,11 +452,13 @@ bool ScreenDebugOverlay::Input( const InputEventPlus &input ) return true; } - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + vector & subscribers = GetSubscribers(); + + FOREACH_CONST( IDebugLine*, subscribers, p ) { RString sPageName = (*p)->GetPageName(); - int i = p-g_pvpSubscribers->begin(); + int i = p-subscribers.begin(); // Gameplay buttons are available only in gameplay. Non-gameplay buttons // are only available when the screen is displayed. diff --git a/src/ScreenManager.cpp b/src/ScreenManager.cpp index 0039d0047d..8aae275fc4 100644 --- a/src/ScreenManager.cpp +++ b/src/ScreenManager.cpp @@ -79,7 +79,11 @@ static Preference g_bDelayedScreenLoad( "DelayedScreenLoad", false ); //static Preference g_bPruneFonts( "PruneFonts", true ); // Screen registration -static map *g_pmapRegistrees = NULL; +map & GetRegistrees() +{ + static map registrees; + return registrees; +} /** @brief Utility functions for the ScreenManager. */ namespace ScreenManagerUtil @@ -219,13 +223,12 @@ using namespace ScreenManagerUtil; RegisterScreenClass::RegisterScreenClass( const RString& sClassName, CreateScreenFn pfn ) { - if( g_pmapRegistrees == NULL ) - g_pmapRegistrees = smnew map; + map & registrees = GetRegistrees(); - map::iterator iter = g_pmapRegistrees->find( sClassName ); - ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Screen class '%s' already registered.", sClassName.c_str()) ); + map::iterator iter = registrees.find( sClassName ); + ASSERT_M( iter == registrees.end(), ssprintf("Screen class '%s' already registered.", sClassName.c_str()) ); - (*g_pmapRegistrees)[sClassName] = pfn; + registrees[sClassName] = pfn; } @@ -532,8 +535,10 @@ Screen* ScreenManager::MakeNewScreen( const RString &sScreenName ) RString sClassName = THEME->GetMetric( sScreenName,"Class" ); - map::iterator iter = g_pmapRegistrees->find( sClassName ); - if( iter == g_pmapRegistrees->end() ) + map & registrees = GetRegistrees(); + + map::iterator iter = registrees.find( sClassName ); + if( iter == registrees.end() ) RageException::Throw( "Screen \"%s\" has an invalid class \"%s\".", sScreenName.c_str(), sClassName.c_str() ); this->ZeroNextUpdate(); @@ -871,7 +876,7 @@ public: } static int SystemMessage( T* p, lua_State *L ) { p->SystemMessage( SArg(1) ); return 0; } static int ScreenIsPrepped( T* p, lua_State *L ) { lua_pushboolean( L, ScreenManagerUtil::ScreenIsPrepped( SArg(1) ) ); return 1; } - static int ScreenClassExists( T* p, lua_State *L ) { lua_pushboolean( L, g_pmapRegistrees->find( SArg(1) ) != g_pmapRegistrees->end() ); return 1; } + static int ScreenClassExists( T* p, lua_State *L ) { lua_pushboolean( L, GetRegistrees().find( SArg(1) ) != GetRegistrees().end() ); return 1; } static int AddNewScreenToTop( T* p, lua_State *L ) { ScreenMessage SM = SM_None; diff --git a/src/ScreenMessage.cpp b/src/ScreenMessage.cpp index 9bc4b4eb4f..aacff90ec7 100644 --- a/src/ScreenMessage.cpp +++ b/src/ScreenMessage.cpp @@ -17,22 +17,25 @@ AutoScreenMessage(SM_Pause); AutoScreenMessage(SM_Success); AutoScreenMessage(SM_Failure); -static map *m_pScreenMessages; +map & GetScreenMessages() +{ + static map screenMessages; + return screenMessages; +} ScreenMessage ScreenMessageHelpers::ToScreenMessage( const RString &sName ) { - if( m_pScreenMessages == NULL ) - m_pScreenMessages = smnew map; + map & screenMessages = GetScreenMessages(); - if( m_pScreenMessages->find( sName ) == m_pScreenMessages->end() ) - (*m_pScreenMessages)[sName] = (ScreenMessage)sName; + if( screenMessages.find( sName ) == screenMessages.end() ) + screenMessages[sName] = (ScreenMessage)sName; - return (*m_pScreenMessages)[sName]; + return screenMessages[sName]; } RString ScreenMessageHelpers::ScreenMessageToString( ScreenMessage SM ) { - FOREACHM( RString, ScreenMessage, *m_pScreenMessages, it ) + FOREACHM( RString, ScreenMessage, GetScreenMessages(), it ) if( SM == it->second ) return (*it).first; diff --git a/src/SubscriptionManager.h b/src/SubscriptionManager.h index fc6d9bda6b..386760aa26 100644 --- a/src/SubscriptionManager.h +++ b/src/SubscriptionManager.h @@ -5,46 +5,36 @@ #include -// Since this class has only POD types and no constructor, there's no -// initialize order problem. +// When using this class be sure to use the global static initializer trick by wrapping the static object in a function like the +// following example: +// +// SubscriptionManager & GetSubscribers() +// { +// static SubscriptionManager subscribers; +// return subscribers; +// } +// +// This ensures that the object is always available when it's needed. template class SubscriptionManager { public: - // TRICKY: If we make this a global instead of a global pointer, - // then we'd have to be careful that the static constructors of all - // subscribers are called before the collection constructor. It's - // impossible to enfore that in C++. Instead, we'll allocate the - // collection ourself on first use. SubscriptionHandler itself is - // a POD type, so a static SubscriptionHandler will always have - // m_pSubscribers == NULL (before any static constructors are called). - set* m_pSubscribers; - - // Use this to access m_pSubscribers, so you don't have to worry about - // it being NULL. - set &Get() - { - if( m_pSubscribers == NULL ) - m_pSubscribers = smnew set; - return *m_pSubscribers; - } + set m_pSubscribers; void Subscribe( T* p ) { - if( m_pSubscribers == NULL ) - m_pSubscribers = smnew set; #ifdef DEBUG - typename set::iterator iter = m_pSubscribers->find( p ); - ASSERT_M( iter == m_pSubscribers->end(), "already subscribed" ); + typename set::iterator iter = m_pSubscribers.find( p ); + ASSERT_M( iter == m_pSubscribers.end(), "already subscribed" ); #endif - m_pSubscribers->insert( p ); + m_pSubscribers.insert( p ); } void Unsubscribe( T* p ) { - typename set::iterator iter = m_pSubscribers->find( p ); - ASSERT( iter != m_pSubscribers->end() ); - m_pSubscribers->erase( iter ); + typename set::iterator iter = m_pSubscribers.find( p ); + ASSERT( iter != m_pSubscribers.end() ); + m_pSubscribers.erase( iter ); } }; diff --git a/src/ThemeManager.cpp b/src/ThemeManager.cpp index 8f80da9d1c..f0485fad12 100644 --- a/src/ThemeManager.cpp +++ b/src/ThemeManager.cpp @@ -63,7 +63,12 @@ LoadedThemeData *g_pLoadedThemeData = NULL; // For self-registering metrics #include "SubscriptionManager.h" -static SubscriptionManager g_Subscribers; + +SubscriptionManager & GetSubscribers() +{ + static SubscriptionManager subscribers; + return subscribers; +} class LocalizedStringImplThemeMetric : public ILocalizedStringImpl, public ThemeMetric { @@ -95,7 +100,7 @@ public: void ThemeManager::Subscribe( IThemeMetric *p ) { - g_Subscribers.Subscribe( p ); + GetSubscribers().Subscribe( p ); // It's ThemeManager's responsibility to make sure all of its subscribers // are updated with current data. If a metric is created after @@ -107,7 +112,7 @@ void ThemeManager::Subscribe( IThemeMetric *p ) void ThemeManager::Unsubscribe( IThemeMetric *p ) { - g_Subscribers.Unsubscribe( p ); + GetSubscribers().Unsubscribe( p ); } @@ -429,20 +434,14 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt void ThemeManager::ReloadSubscribers() { // reload subscribers - if( g_Subscribers.m_pSubscribers ) - { - FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p ) - (*p)->Read(); - } + FOREACHS_CONST( IThemeMetric*, GetSubscribers().m_pSubscribers, p ) + (*p)->Read(); } void ThemeManager::ClearSubscribers() { - if( g_Subscribers.m_pSubscribers ) - { - FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p ) - (*p)->Clear(); - } + FOREACHS_CONST( IThemeMetric*, GetSubscribers().m_pSubscribers, p ) + (*p)->Clear(); } void ThemeManager::RunLuaScripts( const RString &sMask, bool bUseThemeDir ) diff --git a/src/ThemeMetric.h b/src/ThemeMetric.h index a4073ffa1a..faa5d6e61c 100644 --- a/src/ThemeMetric.h +++ b/src/ThemeMetric.h @@ -187,6 +187,7 @@ public: { Load( RString(), NULL, 0 ); } + virtual ~ThemeMetric1D() { } void Load( const RString& sGroup, MetricName1D pfn, size_t N ) { m_metric.resize( N ); diff --git a/src/TimingData.cpp b/src/TimingData.cpp index e64b1b5e66..8e30d3531b 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -268,28 +268,55 @@ bool TimingData::IsFakeAtRow( int iNoteRow ) const * * Note that types whose SegmentEffectAreas are "Indefinite" are NULL here, * because they should never need to be used; we always have at least one such - * segment in the TimingData, and if not, we'll crash anyway. -- vyhd */ -static const TimingSegment* DummySegments[NUM_TimingSegmentType] = + * segment in the TimingData, and if not, we'll crash anyway. -- vyhd + * + * I've modified the dummy segments a bit to use a static function trick to make + * sure the objects gets destructed instead of leaking a bunch of pointers. + */ +TimingSegment * GetDummyTimingSegment( TimingSegmentType tst ) { - NULL, // BPMSegment - smnew StopSegment, - smnew DelaySegment, - NULL, // TimeSignatureSegment - smnew WarpSegment, - NULL, // LabelSegment - NULL, // TickcountSegment - NULL, // ComboSegment - NULL, // SpeedSegment - NULL, // ScrollSegment - smnew FakeSegment -}; + TimingSegment * result = NULL; + + switch( tst ) + { + case SEGMENT_STOP: + { + static StopSegment stopSegment; + result = &stopSegment; + break; + } + + case SEGMENT_DELAY: + { + static DelaySegment delaySegment; + result = &delaySegment; + break; + } + + case SEGMENT_WARP: + { + static WarpSegment warpSegment; + result = &warpSegment; + break; + } + + case SEGMENT_FAKE: + { + static FakeSegment fakeSegment; + result = &fakeSegment; + break; + } + } + + return result; +} const TimingSegment* TimingData::GetSegmentAtRow( int iNoteRow, TimingSegmentType tst ) const { const vector &vSegments = GetTimingSegments(tst); if( vSegments.empty() ) - return DummySegments[tst]; + return GetDummyTimingSegment(tst); int index = GetSegmentIndexAtRow( tst, iNoteRow ); const TimingSegment *seg = vSegments[index]; @@ -308,7 +335,7 @@ const TimingSegment* TimingData::GetSegmentAtRow( int iNoteRow, TimingSegmentTyp if( seg->GetRow() == iNoteRow ) return seg; else - return DummySegments[tst]; + return GetDummyTimingSegment(tst); } } diff --git a/src/arch/Dialog/DialogDriver.cpp b/src/arch/Dialog/DialogDriver.cpp index d905b7c051..03d850a330 100644 --- a/src/arch/Dialog/DialogDriver.cpp +++ b/src/arch/Dialog/DialogDriver.cpp @@ -3,14 +3,11 @@ #include "Foreach.h" #include "RageLog.h" -map *RegisterDialogDriver::g_pRegistrees; RegisterDialogDriver::RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn ) { - if( g_pRegistrees == NULL ) - g_pRegistrees = smnew map; - - ASSERT( g_pRegistrees->find(sName) == g_pRegistrees->end() ); - (*g_pRegistrees)[sName] = pfn; + map & registrees = GetRegistrees(); + ASSERT( registrees.find(sName) == registrees.end() ); + registrees[sName] = pfn; } REGISTER_DIALOG_DRIVER_CLASS( Null ); @@ -23,11 +20,13 @@ DialogDriver *DialogDriver::Create() ASSERT( asDriversToTry.size() != 0 ); + map & registrees = RegisterDialogDriver::GetRegistrees(); + FOREACH_CONST( RString, asDriversToTry, Driver ) { - map::const_iterator iter = RegisterDialogDriver::g_pRegistrees->find( istring(*Driver) ); + map::const_iterator iter = registrees.find( istring(*Driver) ); - if( iter == RegisterDialogDriver::g_pRegistrees->end() ) + if( iter == registrees.end() ) continue; DialogDriver *pRet = (iter->second)(); diff --git a/src/arch/Dialog/DialogDriver.h b/src/arch/Dialog/DialogDriver.h index 5e377328ba..ff60e136a2 100644 --- a/src/arch/Dialog/DialogDriver.h +++ b/src/arch/Dialog/DialogDriver.h @@ -25,7 +25,12 @@ class DialogDriver_Null : public DialogDriver { }; typedef DialogDriver *(*CreateDialogDriverFn)(); struct RegisterDialogDriver { - static map *g_pRegistrees; + static map & GetRegistrees() + { + static map registrees; + return registrees; + } + RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn ); }; #define REGISTER_DIALOG_DRIVER_CLASS( name ) \ diff --git a/src/arch/InputHandler/InputHandler.cpp b/src/arch/InputHandler/InputHandler.cpp index 0cc86be886..06de1e9f6d 100644 --- a/src/arch/InputHandler/InputHandler.cpp +++ b/src/arch/InputHandler/InputHandler.cpp @@ -164,8 +164,6 @@ RString InputHandler::GetLocalizedInputString( const DeviceInput &di ) } } -DriverList InputHandler::m_pDriverList; - static LocalizedString INPUT_HANDLERS_EMPTY( "Arch", "Input Handlers cannot be empty." ); void InputHandler::Create( const RString &drivers_, vector &Add ) { @@ -178,7 +176,7 @@ void InputHandler::Create( const RString &drivers_, vector &Add FOREACH_CONST( RString, DriversToTry, s ) { - RageDriver *pDriver = InputHandler::m_pDriverList.Create( *s ); + RageDriver *pDriver = InputHandler::GetDriverList().Create( *s ); if( pDriver == NULL ) { LOG->Trace( "Unknown Input Handler name: %s", s->c_str() ); diff --git a/src/arch/InputHandler/InputHandler.h b/src/arch/InputHandler/InputHandler.h index 2afaa75066..7e4c18542d 100644 --- a/src/arch/InputHandler/InputHandler.h +++ b/src/arch/InputHandler/InputHandler.h @@ -23,7 +23,12 @@ class InputHandler: public RageDriver { public: static void Create( const RString &sDrivers, vector &apAdd ); - static DriverList m_pDriverList; + + static DriverList & GetDriverList() + { + static DriverList driverList; + return driverList; + } InputHandler(): m_LastUpdate(), m_iInputsSinceUpdate(0) {} virtual ~InputHandler() { } @@ -69,7 +74,7 @@ private: }; #define REGISTER_INPUT_HANDLER_CLASS2( name, x ) \ - static RegisterRageDriver register_##name( &InputHandler::m_pDriverList, #name, CreateClass ) + static RegisterRageDriver register_##name( &InputHandler::GetDriverList(), #name, CreateClass ) #define REGISTER_INPUT_HANDLER_CLASS( name ) REGISTER_INPUT_HANDLER_CLASS2( name, name ) diff --git a/src/arch/Lights/LightsDriver.cpp b/src/arch/Lights/LightsDriver.cpp index 0d48c59cad..38b79350ae 100644 --- a/src/arch/Lights/LightsDriver.cpp +++ b/src/arch/Lights/LightsDriver.cpp @@ -4,8 +4,6 @@ #include "Foreach.h" #include "arch/arch_default.h" -DriverList LightsDriver::m_pDriverList; - void LightsDriver::Create( const RString &sDrivers, vector &Add ) { LOG->Trace( "Initializing lights drivers: %s", sDrivers.c_str() ); @@ -15,7 +13,7 @@ void LightsDriver::Create( const RString &sDrivers, vector &Add FOREACH_CONST( RString, asDriversToTry, Driver ) { - RageDriver *pRet = m_pDriverList.Create( *Driver ); + RageDriver *pRet = GetDriverList().Create( *Driver ); if( pRet == NULL ) { LOG->Trace( "Unknown lights driver: %s", Driver->c_str() ); diff --git a/src/arch/Lights/LightsDriver.h b/src/arch/Lights/LightsDriver.h index 5420f25cf5..145e453073 100644 --- a/src/arch/Lights/LightsDriver.h +++ b/src/arch/Lights/LightsDriver.h @@ -10,7 +10,12 @@ class LightsDriver: public RageDriver { public: static void Create( const RString &sDriver, vector &apAdd ); - static DriverList m_pDriverList; + + static DriverList & GetDriverList() + { + static DriverList driverList; + return driverList; + } LightsDriver() {}; virtual ~LightsDriver() {}; @@ -19,7 +24,7 @@ public: }; #define REGISTER_SOUND_DRIVER_CLASS2( name, x ) \ - static RegisterRageDriver register_##x( &LightsDriver::m_pDriverList, #name, CreateClass ) + static RegisterRageDriver register_##x( &LightsDriver::GetDriverList(), #name, CreateClass ) #define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name ) #endif diff --git a/src/arch/MovieTexture/MovieTexture.cpp b/src/arch/MovieTexture/MovieTexture.cpp index 8c9190117f..e0fc9132ea 100644 --- a/src/arch/MovieTexture/MovieTexture.cpp +++ b/src/arch/MovieTexture/MovieTexture.cpp @@ -62,8 +62,6 @@ bool RageMovieTexture::GetFourCC( RString fn, RString &handler, RString &type ) #undef HANDLE_ERROR } -DriverList RageMovieTextureDriver::m_pDriverList; - // Helper for MakeRageMovieTexture() static void DumpAVIDebugInfo( const RString& fn ) { @@ -97,7 +95,7 @@ RageMovieTexture *RageMovieTexture::Create( RageTextureID ID ) FOREACH_CONST( RString, DriversToTry, Driver ) { LOG->Trace( "Initializing driver: %s", Driver->c_str() ); - RageDriver *pDriverBase = RageMovieTextureDriver::m_pDriverList.Create( *Driver ); + RageDriver *pDriverBase = RageMovieTextureDriver::GetDriverList().Create( *Driver ); if( pDriverBase == NULL ) { diff --git a/src/arch/MovieTexture/MovieTexture.h b/src/arch/MovieTexture/MovieTexture.h index 4ab84e843c..9a29d03d74 100644 --- a/src/arch/MovieTexture/MovieTexture.h +++ b/src/arch/MovieTexture/MovieTexture.h @@ -32,11 +32,15 @@ class RageMovieTextureDriver: public RageDriver public: virtual ~RageMovieTextureDriver() { } virtual RageMovieTexture *Create( RageTextureID ID, RString &sError ) = 0; - static DriverList m_pDriverList; + static DriverList & GetDriverList() + { + static DriverList driverList; + return driverList; + } }; #define REGISTER_MOVIE_TEXTURE_CLASS( name ) \ - static RegisterRageDriver register_##name( &RageMovieTextureDriver::m_pDriverList, #name, CreateClass ) + static RegisterRageDriver register_##name( &RageMovieTextureDriver::GetDriverList(), #name, CreateClass ) #endif diff --git a/src/arch/RageDriver.cpp b/src/arch/RageDriver.cpp index ef0a4f238d..d7782d577a 100644 --- a/src/arch/RageDriver.cpp +++ b/src/arch/RageDriver.cpp @@ -3,20 +3,17 @@ void DriverList::Add( const istring &sName, CreateRageDriverFn pfn ) { - if( m_pRegistrees == NULL ) - m_pRegistrees = smnew map; - - ASSERT( m_pRegistrees->find(sName) == m_pRegistrees->end() ); - (*m_pRegistrees)[sName] = pfn; + ASSERT( m_pRegistrees.find(sName) == m_pRegistrees.end() ); + m_pRegistrees[sName] = pfn; } RageDriver *DriverList::Create( const RString &sDriverName ) { - if( m_pRegistrees == NULL ) + if( m_pRegistrees.empty()) return NULL; - map::const_iterator iter = m_pRegistrees->find( istring(sDriverName) ); - if( iter == m_pRegistrees->end() ) + map::const_iterator iter = m_pRegistrees.find( istring(sDriverName) ); + if( iter == m_pRegistrees.end() ) return NULL; return (iter->second)(); } diff --git a/src/arch/RageDriver.h b/src/arch/RageDriver.h index fa2f3a32ad..44b2b7a529 100644 --- a/src/arch/RageDriver.h +++ b/src/arch/RageDriver.h @@ -11,12 +11,11 @@ public: typedef RageDriver *(*CreateRageDriverFn)(); -/* This is created and accessed during C++ static initialization; it must be a POD. */ struct DriverList { void Add( const istring &sName, CreateRageDriverFn pfn ); RageDriver *Create( const RString &sDriverName ); - map *m_pRegistrees; + map m_pRegistrees; }; struct RegisterRageDriver diff --git a/src/arch/Sound/RageSoundDriver.cpp b/src/arch/Sound/RageSoundDriver.cpp index a491a5096f..9c263ba349 100644 --- a/src/arch/Sound/RageSoundDriver.cpp +++ b/src/arch/Sound/RageSoundDriver.cpp @@ -5,8 +5,6 @@ #include "Foreach.h" #include "arch/arch_default.h" -DriverList RageSoundDriver::m_pDriverList; - RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers ) { vector DriversToTry; @@ -14,7 +12,7 @@ RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers ) FOREACH_CONST( RString, DriversToTry, Driver ) { - RageDriver *pDriver = m_pDriverList.Create( *Driver ); + RageDriver *pDriver = GetDriverList().Create( *Driver ); if( pDriver == NULL ) { LOG->Trace( "Unknown sound driver: %s", Driver->c_str() ); diff --git a/src/arch/Sound/RageSoundDriver.h b/src/arch/Sound/RageSoundDriver.h index a377e10f0d..a27a23810b 100644 --- a/src/arch/Sound/RageSoundDriver.h +++ b/src/arch/Sound/RageSoundDriver.h @@ -17,7 +17,12 @@ class RageSoundDriver: public RageDriver public: /* Pass an empty string to get the default sound driver list. */ static RageSoundDriver *Create( const RString &sDrivers ); - static DriverList m_pDriverList; + + static DriverList & GetDriverList() + { + static DriverList driverList; + return driverList; + } friend class RageSoundManager; @@ -209,7 +214,7 @@ private: // Can't use Create##name because many of these have -sw suffixes. #define REGISTER_SOUND_DRIVER_CLASS2( name, x ) \ - static RegisterRageDriver register_##x( &RageSoundDriver::m_pDriverList, #name, CreateClass ) + static RegisterRageDriver register_##x( &RageSoundDriver::GetDriverList(), #name, CreateClass ) #define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name ) diff --git a/src/arch/Threads/Threads_Win32.cpp b/src/arch/Threads/Threads_Win32.cpp index f5a178c9cd..20ba4c2197 100644 --- a/src/arch/Threads/Threads_Win32.cpp +++ b/src/arch/Threads/Threads_Win32.cpp @@ -7,12 +7,10 @@ const int MAX_THREADS=128; -static MutexImpl_Win32 *g_pThreadIdMutex = NULL; -static void InitThreadIdMutex() +MutexImpl_Win32 & GetThreadMutex() { - if( g_pThreadIdMutex != NULL ) - return; - g_pThreadIdMutex = smnew MutexImpl_Win32(NULL); + static MutexImpl_Win32 mutex(NULL); + return mutex; } static uint64_t g_ThreadIds[MAX_THREADS]; @@ -108,9 +106,9 @@ static DWORD WINAPI StartThread( LPVOID pData ) static int GetOpenSlot( uint64_t iID ) { - InitThreadIdMutex(); + MutexImpl_Win32 & mutex = GetThreadMutex(); - g_pThreadIdMutex->Lock(); + mutex.Lock(); // Find an open slot in g_ThreadIds. int slot = 0; @@ -120,7 +118,7 @@ static int GetOpenSlot( uint64_t iID ) g_ThreadIds[slot] = iID; - g_pThreadIdMutex->Unlock(); + mutex.Unlock(); return slot; }