Merge with memoryLeakDetection branch.

This commit is contained in:
Shenjoku
2013-04-19 20:36:59 -07:00
33 changed files with 266 additions and 182 deletions
+15 -9
View File
@@ -14,22 +14,26 @@
// Actor registration // Actor registration
static map<RString,CreateActorFn> *g_pmapRegistrees = NULL; map<RString,CreateActorFn> & GetRegistrees()
{
static map<RString, CreateActorFn> registrees;
return registrees;
}
static bool IsRegistered( const RString& sClassName ) static bool IsRegistered( const RString& sClassName )
{ {
return g_pmapRegistrees->find( sClassName ) != g_pmapRegistrees->end(); map<RString, CreateActorFn> & registrees = GetRegistrees();
return registrees.find( sClassName ) != registrees.end();
} }
void ActorUtil::Register( const RString& sClassName, CreateActorFn pfn ) void ActorUtil::Register( const RString& sClassName, CreateActorFn pfn )
{ {
if( g_pmapRegistrees == NULL ) map<RString, CreateActorFn> & registrees = GetRegistrees();
g_pmapRegistrees = new map<RString,CreateActorFn>;
map<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClassName ); map<RString,CreateActorFn>::iterator iter = registrees.find( sClassName );
ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Actor class '%s' already registered.", sClassName.c_str()) ); 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 ) bool ActorUtil::ResolvePath( RString &sPath, const RString &sName )
@@ -119,8 +123,10 @@ Actor* ActorUtil::LoadFromNode( const XNode* pNode, Actor *pParentActor )
if( !bHasClass ) if( !bHasClass )
bHasClass = pNode->GetAttrValue( "Type", sClass ); bHasClass = pNode->GetAttrValue( "Type", sClass );
map<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClass ); map<RString, CreateActorFn> & registrees = GetRegistrees();
if( iter == g_pmapRegistrees->end() )
map<RString,CreateActorFn>::iterator iter = registrees.find( sClass );
if( iter == registrees.end() )
{ {
// sClass is invalid // sClass is invalid
RString sError = ssprintf( "%s: invalid Class \"%s\"", RString sError = ssprintf( "%s: invalid Class \"%s\"",
+3 -2
View File
@@ -741,8 +741,6 @@ void Font::Load( const RString &sIniPath, RString sChars )
{ {
const RString &sTexturePath = asTexturePaths[i]; const RString &sTexturePath = asTexturePaths[i];
FontPage *pPage = new FontPage;
// Grab the page name, eg "foo" from "Normal [foo].png". // Grab the page name, eg "foo" from "Normal [foo].png".
RString sPagename = GetPageNameFromFileName( sTexturePath ); RString sPagename = GetPageNameFromFileName( sTexturePath );
@@ -750,6 +748,9 @@ void Font::Load( const RString &sIniPath, RString sChars )
if( sTexturePath.find("-stroke") != string::npos ) if( sTexturePath.find("-stroke") != string::npos )
continue; continue;
// Create this down here so it doesn't leak if the continue gets triggered.
FontPage *pPage = new FontPage;
// Load settings for this page from the INI. // Load settings for this page from the INI.
FontPageSettings cfg; FontPageSettings cfg;
LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars ); LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars );
+6
View File
@@ -48,6 +48,12 @@ LifeMeterTime::LifeMeterTime()
{ {
m_fLifeTotalGainedSeconds = 0; m_fLifeTotalGainedSeconds = 0;
m_fLifeTotalLostSeconds = 0; m_fLifeTotalLostSeconds = 0;
m_pStream = NULL;
}
LifeMeterTime::~LifeMeterTime()
{
delete m_pStream;
} }
void LifeMeterTime::Load( const PlayerState *pPlayerState, PlayerStageStats *pPlayerStageStats ) void LifeMeterTime::Load( const PlayerState *pPlayerState, PlayerStageStats *pPlayerStageStats )
+2
View File
@@ -16,6 +16,8 @@ class LifeMeterTime : public LifeMeter
public: public:
LifeMeterTime(); LifeMeterTime();
virtual ~LifeMeterTime();
virtual void Load( const PlayerState *pPlayerState, PlayerStageStats *pPlayerStageStats ); virtual void Load( const PlayerState *pPlayerState, PlayerStageStats *pPlayerStageStats );
virtual void Update( float fDeltaTime ); virtual void Update( float fDeltaTime );
+8 -4
View File
@@ -4,7 +4,11 @@
#include "RageUtil.h" #include "RageUtil.h"
#include "SubscriptionManager.h" #include "SubscriptionManager.h"
static SubscriptionManager<LocalizedString> m_Subscribers; SubscriptionManager<LocalizedString> & GetSubscribers()
{
static SubscriptionManager<LocalizedString> subscribers;
return subscribers;
}
class LocalizedStringImplDefault: public ILocalizedStringImpl class LocalizedStringImplDefault: public ILocalizedStringImpl
{ {
@@ -27,7 +31,7 @@ static LocalizedString::MakeLocalizer g_pMakeLocalizedStringImpl = LocalizedStri
void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc ) void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc )
{ {
g_pMakeLocalizedStringImpl = pFunc; g_pMakeLocalizedStringImpl = pFunc;
FOREACHS( LocalizedString*, *m_Subscribers.m_pSubscribers, l ) FOREACHS( LocalizedString*, GetSubscribers().m_pSubscribers, l )
{ {
LocalizedString *pLoc = *l; LocalizedString *pLoc = *l;
pLoc->CreateImpl(); pLoc->CreateImpl();
@@ -36,7 +40,7 @@ void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc )
LocalizedString::LocalizedString( const RString& sGroup, const RString& sName ) LocalizedString::LocalizedString( const RString& sGroup, const RString& sName )
{ {
m_Subscribers.Subscribe( this ); GetSubscribers().Subscribe( this );
m_sGroup = sGroup; m_sGroup = sGroup;
m_sName = sName; m_sName = sName;
@@ -47,7 +51,7 @@ LocalizedString::LocalizedString( const RString& sGroup, const RString& sName )
LocalizedString::~LocalizedString() LocalizedString::~LocalizedString()
{ {
m_Subscribers.Unsubscribe( this ); GetSubscribers().Unsubscribe( this );
SAFE_DELETE( m_pImpl ); SAFE_DELETE( m_pImpl );
} }
+12 -5
View File
@@ -5,18 +5,25 @@
#include "Foreach.h" #include "Foreach.h"
#include "SubscriptionManager.h" #include "SubscriptionManager.h"
static SubscriptionManager<LuaBinding> m_Subscribers;
SubscriptionManager<LuaBinding> & GetSubscribers()
{
static SubscriptionManager<LuaBinding> subscribers;
return subscribers;
}
namespace namespace
{ {
void RegisterTypes( lua_State *L ) void RegisterTypes( lua_State *L )
{ {
if( m_Subscribers.m_pSubscribers == NULL ) SubscriptionManager<LuaBinding> & subscribers = GetSubscribers();
if( subscribers.m_pSubscribers.empty() )
return; return;
/* Register base classes first. */ /* Register base classes first. */
map<RString, LuaBinding *> mapToRegister; map<RString, LuaBinding *> mapToRegister;
FOREACHS( LuaBinding*, *m_Subscribers.m_pSubscribers, p ) FOREACHS( LuaBinding*, subscribers.m_pSubscribers, p )
mapToRegister[(*p)->GetClassName()] = (*p); mapToRegister[(*p)->GetClassName()] = (*p);
set<RString> setRegisteredAlready; set<RString> setRegisteredAlready;
@@ -59,12 +66,12 @@ REGISTER_WITH_LUA_FUNCTION( RegisterTypes );
LuaBinding::LuaBinding() LuaBinding::LuaBinding()
{ {
m_Subscribers.Subscribe( this ); GetSubscribers().Subscribe( this );
} }
LuaBinding::~LuaBinding() LuaBinding::~LuaBinding()
{ {
m_Subscribers.Unsubscribe( this ); GetSubscribers().Unsubscribe( this );
} }
void LuaBinding::Register( lua_State *L ) void LuaBinding::Register( lua_State *L )
+10 -11
View File
@@ -226,17 +226,17 @@ static int LuaPanic( lua_State *L )
} }
// Actor registration // Actor registration
static vector<RegisterWithLuaFn> *g_vRegisterActorTypes = NULL; vector<RegisterWithLuaFn> & GetRegisteredActorTypes()
{
static vector<RegisterWithLuaFn> registeredActorTypes;
return registeredActorTypes;
}
void LuaManager::Register( RegisterWithLuaFn pfn ) void LuaManager::Register( RegisterWithLuaFn pfn )
{ {
if( g_vRegisterActorTypes == NULL ) GetRegisteredActorTypes().push_back( pfn );
g_vRegisterActorTypes = new vector<RegisterWithLuaFn>;
g_vRegisterActorTypes->push_back( pfn );
} }
LuaManager::LuaManager() LuaManager::LuaManager()
{ {
pImpl = new Impl; pImpl = new Impl;
@@ -360,14 +360,13 @@ void LuaManager::RegisterTypes()
{ {
Lua *L = Get(); Lua *L = Get();
if( g_vRegisterActorTypes ) vector<RegisterWithLuaFn> & registeredActorTypes = GetRegisteredActorTypes();
for( unsigned i=0; i<registeredActorTypes.size(); i++ )
{ {
for( unsigned i=0; i<g_vRegisterActorTypes->size(); i++ ) RegisterWithLuaFn fn = registeredActorTypes[i];
{
RegisterWithLuaFn fn = (*g_vRegisterActorTypes)[i];
fn( L ); fn( L );
} }
}
Release( L ); Release( L );
} }
+5
View File
@@ -22,6 +22,11 @@ MenuTimer::MenuTimer()
WARNING_COMMAND = NULL; WARNING_COMMAND = NULL;
} }
MenuTimer::~MenuTimer()
{
delete WARNING_COMMAND;
}
void MenuTimer::Load( RString sMetricsGroup ) void MenuTimer::Load( RString sMetricsGroup )
{ {
m_sprFrame.Load( THEME->GetPathG(sMetricsGroup, "Frame") ); m_sprFrame.Load( THEME->GetPathG(sMetricsGroup, "Frame") );
+1
View File
@@ -15,6 +15,7 @@ class MenuTimer : public ActorFrame
{ {
public: public:
MenuTimer(); MenuTimer();
virtual ~MenuTimer();
void Load( RString sMetricsGroup ); void Load( RString sMetricsGroup );
virtual void Update( float fDeltaTime ); virtual void Update( float fDeltaTime );
+12 -8
View File
@@ -7,23 +7,27 @@
#include "SubscriptionManager.h" #include "SubscriptionManager.h"
#include "Foreach.h" #include "Foreach.h"
static SubscriptionManager<IPreference> m_Subscribers; SubscriptionManager<IPreference> & GetSubscribers()
{
static SubscriptionManager<IPreference> subscribers;
return subscribers;
}
IPreference::IPreference( const RString& sName ): IPreference::IPreference( const RString& sName ):
m_sName( sName ), m_sName( sName ),
m_bIsStatic( false ) m_bIsStatic( false )
{ {
m_Subscribers.Subscribe( this ); GetSubscribers().Subscribe( this );
} }
IPreference::~IPreference() IPreference::~IPreference()
{ {
m_Subscribers.Unsubscribe( this ); GetSubscribers().Unsubscribe( this );
} }
IPreference *IPreference::GetPreferenceByName( const RString &sName ) IPreference *IPreference::GetPreferenceByName( const RString &sName )
{ {
FOREACHS( IPreference*, *m_Subscribers.m_pSubscribers, p ) FOREACHS( IPreference*, GetSubscribers().m_pSubscribers, p )
{ {
if( !(*p)->GetName().CompareNoCase( sName ) ) if( !(*p)->GetName().CompareNoCase( sName ) )
return *p; return *p;
@@ -34,20 +38,20 @@ IPreference *IPreference::GetPreferenceByName( const RString &sName )
void IPreference::LoadAllDefaults() void IPreference::LoadAllDefaults()
{ {
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p )
(*p)->LoadDefault(); (*p)->LoadDefault();
} }
void IPreference::ReadAllPrefsFromNode( const XNode* pNode, bool bIsStatic ) void IPreference::ReadAllPrefsFromNode( const XNode* pNode, bool bIsStatic )
{ {
ASSERT( pNode != NULL ); ASSERT( pNode != NULL );
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p )
(*p)->ReadFrom( pNode, bIsStatic ); (*p)->ReadFrom( pNode, bIsStatic );
} }
void IPreference::SavePrefsToNode( XNode* pNode ) void IPreference::SavePrefsToNode( XNode* pNode )
{ {
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p )
(*p)->WriteTo( pNode ); (*p)->WriteTo( pNode );
} }
@@ -55,7 +59,7 @@ void IPreference::ReadAllDefaultsFromNode( const XNode* pNode )
{ {
if( pNode == NULL ) if( pNode == NULL )
return; return;
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) FOREACHS_CONST( IPreference*, GetSubscribers().m_pSubscribers, p )
(*p)->ReadDefaultFrom( pNode ); (*p)->ReadDefaultFrom( pNode );
} }
+17 -11
View File
@@ -11,6 +11,7 @@
#include "RageUtil.h" #include "RageUtil.h"
#include "RageMath.h" #include "RageMath.h"
#include "RageThreads.h" #include "RageThreads.h"
#include "RageUtil_AutoPtr.h"
#include <numeric> #include <numeric>
@@ -397,25 +398,28 @@ int PolyphaseFilter::NumInputsForOutputSamples( const State &State, int iOut, in
return iIn; return iIn;
} }
/** @brief Utilities for working with the PolyphaseFilter cache. */ /** @brief Utilities for working with the PolyphaseFilter cache. */
typedef AutoPtrCopyOnWrite<PolyphaseFilter> PolyphaseFilterAutoPtr;
namespace PolyphaseFilterCache namespace PolyphaseFilterCache
{ {
/* Cache filter data, and reuse it without copying. All operations after creation /* Cache filter data, and reuse it without copying. All operations after creation
* are const, so this doesn't cause thread-safety problems. */ * are const, so this doesn't cause thread-safety problems. */
typedef map<pair<int,float>, PolyphaseFilter *> FilterMap; typedef map<pair<int,float>, PolyphaseFilterAutoPtr> FilterMap;
static RageMutex PolyphaseFiltersLock("PolyphaseFiltersLock"); static RageMutex PolyphaseFiltersLock("PolyphaseFiltersLock");
static FilterMap g_mapPolyphaseFilters; static FilterMap g_mapPolyphaseFilters;
const PolyphaseFilter *MakePolyphaseFilter( int iUpFactor, float fCutoffFrequency ) const PolyphaseFilterAutoPtr MakePolyphaseFilter( int iUpFactor, float fCutoffFrequency )
{ {
PolyphaseFilterAutoPtr result;
PolyphaseFiltersLock.Lock(); PolyphaseFiltersLock.Lock();
pair<int,float> params( make_pair(iUpFactor, fCutoffFrequency) ); pair<int,float> params( make_pair(iUpFactor, fCutoffFrequency) );
FilterMap::const_iterator it = g_mapPolyphaseFilters.find(params); FilterMap::const_iterator it = g_mapPolyphaseFilters.find(params);
if( it != g_mapPolyphaseFilters.end() ) if( it != g_mapPolyphaseFilters.end() )
{ {
/* We already have a filter for this upsampling factor and cutoff; use it. */ /* We already have a filter for this upsampling factor and cutoff; use it. */
PolyphaseFilter *pPolyphase = it->second; result = it->second;
PolyphaseFiltersLock.Unlock(); PolyphaseFiltersLock.Unlock();
return pPolyphase; return result;
} }
int iWinSize = L*iUpFactor; int iWinSize = L*iUpFactor;
float *pFIR = new float[iWinSize]; float *pFIR = new float[iWinSize];
@@ -428,12 +432,14 @@ namespace PolyphaseFilterCache
pPolyphase->Generate( pFIR ); pPolyphase->Generate( pFIR );
delete [] pFIR; delete [] pFIR;
g_mapPolyphaseFilters[params] = pPolyphase; result = PolyphaseFilterAutoPtr(pPolyphase);
g_mapPolyphaseFilters[params] = result;
PolyphaseFiltersLock.Unlock(); PolyphaseFiltersLock.Unlock();
return pPolyphase; return result;
} }
const PolyphaseFilter *FindNearestPolyphaseFilter( int iUpFactor, float fCutoffFrequency ) const PolyphaseFilterAutoPtr FindNearestPolyphaseFilter( int iUpFactor, float fCutoffFrequency )
{ {
/* Find a cached filter with the same iUpFactor and a nearby cutoff frequency. /* Find a cached filter with the same iUpFactor and a nearby cutoff frequency.
* Round the cutoff down, if possible; it's better to filter out too much than * Round the cutoff down, if possible; it's better to filter out too much than
@@ -444,7 +450,7 @@ namespace PolyphaseFilterCache
if( it != g_mapPolyphaseFilters.begin() ) if( it != g_mapPolyphaseFilters.begin() )
--it; --it;
ASSERT( it->first.first == iUpFactor ); ASSERT( it->first.first == iUpFactor );
PolyphaseFilter *pPolyphase = it->second; PolyphaseFilterAutoPtr pPolyphase = it->second;
PolyphaseFiltersLock.Unlock(); PolyphaseFiltersLock.Unlock();
return pPolyphase; return pPolyphase;
} }
@@ -467,7 +473,7 @@ public:
* when filtering. This will only cause the low-pass filter to be rounded; * when filtering. This will only cause the low-pass filter to be rounded;
* the conversion ratio will always be exact. */ * the conversion ratio will always be exact. */
m_iUpFactor = iUpFactor; m_iUpFactor = iUpFactor;
m_pPolyphase = NULL; m_pPolyphase = PolyphaseFilterAutoPtr(NULL);
int iFilterIncrement = max( (iMaxDownFactor - iMinDownFactor)/10, 1 ); int iFilterIncrement = max( (iMaxDownFactor - iMinDownFactor)/10, 1 );
for( int iDownFactor = iMinDownFactor; iDownFactor <= iMaxDownFactor; iDownFactor += iFilterIncrement ) for( int iDownFactor = iMinDownFactor; iDownFactor <= iMaxDownFactor; iDownFactor += iFilterIncrement )
@@ -532,13 +538,13 @@ private:
return fCutoffFrequency; return fCutoffFrequency;
} }
const PolyphaseFilter *GetFilter( int iDownFactor ) const const PolyphaseFilterAutoPtr GetFilter( int iDownFactor ) const
{ {
float fCutoffFrequency = GetCutoffFrequency( iDownFactor ); float fCutoffFrequency = GetCutoffFrequency( iDownFactor );
return PolyphaseFilterCache::FindNearestPolyphaseFilter( m_iUpFactor, fCutoffFrequency ); return PolyphaseFilterCache::FindNearestPolyphaseFilter( m_iUpFactor, fCutoffFrequency );
} }
const PolyphaseFilter *m_pPolyphase; PolyphaseFilterAutoPtr m_pPolyphase;
PolyphaseFilter::State *m_pState; PolyphaseFilter::State *m_pState;
int m_iUpFactor; int m_iUpFactor;
int m_iDownFactor; int m_iDownFactor;
+2 -2
View File
@@ -138,8 +138,8 @@ struct ThreadSlot *g_pUnknownThreadSlot = NULL;
* so possibly racing over them is harmless (simply using a stale thread ID, etc). */ * so possibly racing over them is harmless (simply using a stale thread ID, etc). */
static RageMutex &GetThreadSlotsLock() static RageMutex &GetThreadSlotsLock()
{ {
static RageMutex *pLock = new RageMutex( "ThreadSlots" ); static RageMutex lock( "ThreadSlots" );
return *pLock; return lock;
} }
static int FindEmptyThreadSlot() static int FindEmptyThreadSlot()
+17 -10
View File
@@ -52,15 +52,18 @@ static LocalizedString ON ( "ScreenDebugOverlay", "on" );
static LocalizedString OFF ( "ScreenDebugOverlay", "off" ); static LocalizedString OFF ( "ScreenDebugOverlay", "off" );
class IDebugLine; class IDebugLine;
static vector<IDebugLine*> *g_pvpSubscribers = NULL; vector<IDebugLine*> & GetSubscribers()
{
static vector<IDebugLine*> subscribers;
return subscribers;
}
class IDebugLine class IDebugLine
{ {
public: public:
IDebugLine() IDebugLine()
{ {
if( g_pvpSubscribers == NULL ) GetSubscribers().push_back( this );
g_pvpSubscribers = new vector<IDebugLine*>;
g_pvpSubscribers->push_back( this );
} }
virtual ~IDebugLine() { } virtual ~IDebugLine() { }
enum Type { all_screens, gameplay_only }; enum Type { all_screens, gameplay_only };
@@ -215,7 +218,7 @@ void ScreenDebugOverlay::Init()
map<RString,int> iNextDebugButton; map<RString,int> iNextDebugButton;
int iNextGameplayButton = 0; int iNextGameplayButton = 0;
FOREACH( IDebugLine*, *g_pvpSubscribers, p ) FOREACH( IDebugLine*, GetSubscribers(), p )
{ {
RString sPageName = (*p)->GetPageName(); RString sPageName = (*p)->GetPageName();
@@ -271,7 +274,7 @@ void ScreenDebugOverlay::Init()
this->AddChild( p ); this->AddChild( p );
} }
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) FOREACH_CONST( IDebugLine*, GetSubscribers(), p )
{ {
{ {
BitmapText *bt = new BitmapText; BitmapText *bt = new BitmapText;
@@ -350,13 +353,15 @@ void ScreenDebugOverlay::UpdateText()
m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" ); m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" );
} }
vector<IDebugLine*> & subscribers = GetSubscribers();
// todo: allow changing of various spacing/location things -aj // todo: allow changing of various spacing/location things -aj
int iOffset = 0; int iOffset = 0;
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) FOREACH_CONST( IDebugLine*, subscribers, p )
{ {
RString sPageName = (*p)->GetPageName(); RString sPageName = (*p)->GetPageName();
int i = p-g_pvpSubscribers->begin(); int i = p-subscribers.begin();
float fY = LINE_START_Y + iOffset * LINE_SPACING; float fY = LINE_START_Y + iOffset * LINE_SPACING;
@@ -447,11 +452,13 @@ bool ScreenDebugOverlay::Input( const InputEventPlus &input )
return true; return true;
} }
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) vector<IDebugLine*> & subscribers = GetSubscribers();
FOREACH_CONST( IDebugLine*, subscribers, p )
{ {
RString sPageName = (*p)->GetPageName(); 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 // Gameplay buttons are available only in gameplay. Non-gameplay buttons
// are only available when the screen is displayed. // are only available when the screen is displayed.
+14 -9
View File
@@ -79,7 +79,11 @@ static Preference<bool> g_bDelayedScreenLoad( "DelayedScreenLoad", false );
//static Preference<bool> g_bPruneFonts( "PruneFonts", true ); //static Preference<bool> g_bPruneFonts( "PruneFonts", true );
// Screen registration // Screen registration
static map<RString,CreateScreenFn> *g_pmapRegistrees = NULL; map<RString, CreateScreenFn> & GetRegistrees()
{
static map<RString, CreateScreenFn> registrees;
return registrees;
}
/** @brief Utility functions for the ScreenManager. */ /** @brief Utility functions for the ScreenManager. */
namespace ScreenManagerUtil namespace ScreenManagerUtil
@@ -219,13 +223,12 @@ using namespace ScreenManagerUtil;
RegisterScreenClass::RegisterScreenClass( const RString& sClassName, CreateScreenFn pfn ) RegisterScreenClass::RegisterScreenClass( const RString& sClassName, CreateScreenFn pfn )
{ {
if( g_pmapRegistrees == NULL ) map<RString,CreateScreenFn> & registrees = GetRegistrees();
g_pmapRegistrees = new map<RString,CreateScreenFn>;
map<RString,CreateScreenFn>::iterator iter = g_pmapRegistrees->find( sClassName ); map<RString,CreateScreenFn>::iterator iter = registrees.find( sClassName );
ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Screen class '%s' already registered.", sClassName.c_str()) ); 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" ); RString sClassName = THEME->GetMetric( sScreenName,"Class" );
map<RString,CreateScreenFn>::iterator iter = g_pmapRegistrees->find( sClassName ); map<RString,CreateScreenFn> & registrees = GetRegistrees();
if( iter == g_pmapRegistrees->end() )
map<RString,CreateScreenFn>::iterator iter = registrees.find( sClassName );
if( iter == registrees.end() )
RageException::Throw( "Screen \"%s\" has an invalid class \"%s\".", sScreenName.c_str(), sClassName.c_str() ); RageException::Throw( "Screen \"%s\" has an invalid class \"%s\".", sScreenName.c_str(), sClassName.c_str() );
this->ZeroNextUpdate(); this->ZeroNextUpdate();
@@ -871,7 +876,7 @@ public:
} }
static int SystemMessage( T* p, lua_State *L ) { p->SystemMessage( SArg(1) ); return 0; } 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 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 ) static int AddNewScreenToTop( T* p, lua_State *L )
{ {
ScreenMessage SM = SM_None; ScreenMessage SM = SM_None;
+10 -7
View File
@@ -17,22 +17,25 @@ AutoScreenMessage(SM_Pause);
AutoScreenMessage(SM_Success); AutoScreenMessage(SM_Success);
AutoScreenMessage(SM_Failure); AutoScreenMessage(SM_Failure);
static map<RString, ScreenMessage> *m_pScreenMessages; map<RString, ScreenMessage> & GetScreenMessages()
{
static map<RString, ScreenMessage> screenMessages;
return screenMessages;
}
ScreenMessage ScreenMessageHelpers::ToScreenMessage( const RString &sName ) ScreenMessage ScreenMessageHelpers::ToScreenMessage( const RString &sName )
{ {
if( m_pScreenMessages == NULL ) map<RString, ScreenMessage> & screenMessages = GetScreenMessages();
m_pScreenMessages = new map<RString, ScreenMessage>;
if( m_pScreenMessages->find( sName ) == m_pScreenMessages->end() ) if( screenMessages.find( sName ) == screenMessages.end() )
(*m_pScreenMessages)[sName] = (ScreenMessage)sName; screenMessages[sName] = (ScreenMessage)sName;
return (*m_pScreenMessages)[sName]; return screenMessages[sName];
} }
RString ScreenMessageHelpers::ScreenMessageToString( ScreenMessage SM ) RString ScreenMessageHelpers::ScreenMessageToString( ScreenMessage SM )
{ {
FOREACHM( RString, ScreenMessage, *m_pScreenMessages, it ) FOREACHM( RString, ScreenMessage, GetScreenMessages(), it )
if( SM == it->second ) if( SM == it->second )
return (*it).first; return (*it).first;
+2
View File
@@ -21,6 +21,8 @@ StreamDisplay::StreamDisplay()
m_fPassingAlpha = 0; m_fPassingAlpha = 0;
m_fHotAlpha = 0; m_fHotAlpha = 0;
m_bAlwaysBounce = false; m_bAlwaysBounce = false;
m_bDeleteChildren = true;
} }
void StreamDisplay::Load( const RString & /* unreferenced: _sMetricsGroup */) void StreamDisplay::Load( const RString & /* unreferenced: _sMetricsGroup */)
+17 -27
View File
@@ -5,46 +5,36 @@
#include <set> #include <set>
// Since this class has only POD types and no constructor, there's no // When using this class be sure to use the global static initializer trick by wrapping the static object in a function like the
// initialize order problem. // following example:
//
// SubscriptionManager<T> & GetSubscribers()
// {
// static SubscriptionManager<T> subscribers;
// return subscribers;
// }
//
// This ensures that the object is always available when it's needed.
template<class T> template<class T>
class SubscriptionManager class SubscriptionManager
{ {
public: public:
// TRICKY: If we make this a global instead of a global pointer, set<T*> m_pSubscribers;
// 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<T*>* m_pSubscribers;
// Use this to access m_pSubscribers, so you don't have to worry about
// it being NULL.
set<T*> &Get()
{
if( m_pSubscribers == NULL )
m_pSubscribers = new set<T*>;
return *m_pSubscribers;
}
void Subscribe( T* p ) void Subscribe( T* p )
{ {
if( m_pSubscribers == NULL )
m_pSubscribers = new set<T*>;
#ifdef DEBUG #ifdef DEBUG
typename set<T*>::iterator iter = m_pSubscribers->find( p ); typename set<T*>::iterator iter = m_pSubscribers.find( p );
ASSERT_M( iter == m_pSubscribers->end(), "already subscribed" ); ASSERT_M( iter == m_pSubscribers.end(), "already subscribed" );
#endif #endif
m_pSubscribers->insert( p ); m_pSubscribers.insert( p );
} }
void Unsubscribe( T* p ) void Unsubscribe( T* p )
{ {
typename set<T*>::iterator iter = m_pSubscribers->find( p ); typename set<T*>::iterator iter = m_pSubscribers.find( p );
ASSERT( iter != m_pSubscribers->end() ); ASSERT( iter != m_pSubscribers.end() );
m_pSubscribers->erase( iter ); m_pSubscribers.erase( iter );
} }
}; };
+10 -11
View File
@@ -63,7 +63,12 @@ LoadedThemeData *g_pLoadedThemeData = NULL;
// For self-registering metrics // For self-registering metrics
#include "SubscriptionManager.h" #include "SubscriptionManager.h"
static SubscriptionManager<IThemeMetric> g_Subscribers;
SubscriptionManager<IThemeMetric> & GetSubscribers()
{
static SubscriptionManager<IThemeMetric> subscribers;
return subscribers;
}
class LocalizedStringImplThemeMetric : public ILocalizedStringImpl, public ThemeMetric<RString> class LocalizedStringImplThemeMetric : public ILocalizedStringImpl, public ThemeMetric<RString>
{ {
@@ -95,7 +100,7 @@ public:
void ThemeManager::Subscribe( IThemeMetric *p ) void ThemeManager::Subscribe( IThemeMetric *p )
{ {
g_Subscribers.Subscribe( p ); GetSubscribers().Subscribe( p );
// It's ThemeManager's responsibility to make sure all of its subscribers // It's ThemeManager's responsibility to make sure all of its subscribers
// are updated with current data. If a metric is created after // 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 ) void ThemeManager::Unsubscribe( IThemeMetric *p )
{ {
g_Subscribers.Unsubscribe( p ); GetSubscribers().Unsubscribe( p );
} }
@@ -429,21 +434,15 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt
void ThemeManager::ReloadSubscribers() void ThemeManager::ReloadSubscribers()
{ {
// reload subscribers // reload subscribers
if( g_Subscribers.m_pSubscribers ) FOREACHS_CONST( IThemeMetric*, GetSubscribers().m_pSubscribers, p )
{
FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p )
(*p)->Read(); (*p)->Read();
} }
}
void ThemeManager::ClearSubscribers() void ThemeManager::ClearSubscribers()
{ {
if( g_Subscribers.m_pSubscribers ) FOREACHS_CONST( IThemeMetric*, GetSubscribers().m_pSubscribers, p )
{
FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p )
(*p)->Clear(); (*p)->Clear();
} }
}
void ThemeManager::RunLuaScripts( const RString &sMask, bool bUseThemeDir ) void ThemeManager::RunLuaScripts( const RString &sMask, bool bUseThemeDir )
{ {
+1
View File
@@ -187,6 +187,7 @@ public:
{ {
Load( RString(), NULL, 0 ); Load( RString(), NULL, 0 );
} }
virtual ~ThemeMetric1D() { }
void Load( const RString& sGroup, MetricName1D pfn, size_t N ) void Load( const RString& sGroup, MetricName1D pfn, size_t N )
{ {
m_metric.resize( N ); m_metric.resize( N );
+43 -16
View File
@@ -268,28 +268,55 @@ bool TimingData::IsFakeAtRow( int iNoteRow ) const
* *
* Note that types whose SegmentEffectAreas are "Indefinite" are NULL here, * 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 * 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 */ * segment in the TimingData, and if not, we'll crash anyway. -- vyhd
static const TimingSegment* DummySegments[NUM_TimingSegmentType] = *
* 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 TimingSegment * result = NULL;
new StopSegment,
new DelaySegment, switch( tst )
NULL, // TimeSignatureSegment {
new WarpSegment, case SEGMENT_STOP:
NULL, // LabelSegment {
NULL, // TickcountSegment static StopSegment stopSegment;
NULL, // ComboSegment result = &stopSegment;
NULL, // SpeedSegment break;
NULL, // ScrollSegment }
new FakeSegment
}; 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 TimingSegment* TimingData::GetSegmentAtRow( int iNoteRow, TimingSegmentType tst ) const
{ {
const vector<TimingSegment*> &vSegments = GetTimingSegments(tst); const vector<TimingSegment*> &vSegments = GetTimingSegments(tst);
if( vSegments.empty() ) if( vSegments.empty() )
return DummySegments[tst]; return GetDummyTimingSegment(tst);
int index = GetSegmentIndexAtRow( tst, iNoteRow ); int index = GetSegmentIndexAtRow( tst, iNoteRow );
const TimingSegment *seg = vSegments[index]; const TimingSegment *seg = vSegments[index];
@@ -308,7 +335,7 @@ const TimingSegment* TimingData::GetSegmentAtRow( int iNoteRow, TimingSegmentTyp
if( seg->GetRow() == iNoteRow ) if( seg->GetRow() == iNoteRow )
return seg; return seg;
else else
return DummySegments[tst]; return GetDummyTimingSegment(tst);
} }
} }
+7 -8
View File
@@ -3,14 +3,11 @@
#include "Foreach.h" #include "Foreach.h"
#include "RageLog.h" #include "RageLog.h"
map<istring, CreateDialogDriverFn> *RegisterDialogDriver::g_pRegistrees;
RegisterDialogDriver::RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn ) RegisterDialogDriver::RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn )
{ {
if( g_pRegistrees == NULL ) map<istring, CreateDialogDriverFn> & registrees = GetRegistrees();
g_pRegistrees = new map<istring, CreateDialogDriverFn>; ASSERT( registrees.find(sName) == registrees.end() );
registrees[sName] = pfn;
ASSERT( g_pRegistrees->find(sName) == g_pRegistrees->end() );
(*g_pRegistrees)[sName] = pfn;
} }
REGISTER_DIALOG_DRIVER_CLASS( Null ); REGISTER_DIALOG_DRIVER_CLASS( Null );
@@ -23,11 +20,13 @@ DialogDriver *DialogDriver::Create()
ASSERT( asDriversToTry.size() != 0 ); ASSERT( asDriversToTry.size() != 0 );
map<istring, CreateDialogDriverFn> & registrees = RegisterDialogDriver::GetRegistrees();
FOREACH_CONST( RString, asDriversToTry, Driver ) FOREACH_CONST( RString, asDriversToTry, Driver )
{ {
map<istring, CreateDialogDriverFn>::const_iterator iter = RegisterDialogDriver::g_pRegistrees->find( istring(*Driver) ); map<istring, CreateDialogDriverFn>::const_iterator iter = registrees.find( istring(*Driver) );
if( iter == RegisterDialogDriver::g_pRegistrees->end() ) if( iter == registrees.end() )
continue; continue;
DialogDriver *pRet = (iter->second)(); DialogDriver *pRet = (iter->second)();
+6 -1
View File
@@ -25,7 +25,12 @@ class DialogDriver_Null : public DialogDriver { };
typedef DialogDriver *(*CreateDialogDriverFn)(); typedef DialogDriver *(*CreateDialogDriverFn)();
struct RegisterDialogDriver struct RegisterDialogDriver
{ {
static map<istring, CreateDialogDriverFn> *g_pRegistrees; static map<istring, CreateDialogDriverFn> & GetRegistrees()
{
static map<istring, CreateDialogDriverFn> registrees;
return registrees;
}
RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn ); RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn );
}; };
#define REGISTER_DIALOG_DRIVER_CLASS( name ) \ #define REGISTER_DIALOG_DRIVER_CLASS( name ) \
+1 -3
View File
@@ -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." ); static LocalizedString INPUT_HANDLERS_EMPTY( "Arch", "Input Handlers cannot be empty." );
void InputHandler::Create( const RString &drivers_, vector<InputHandler *> &Add ) void InputHandler::Create( const RString &drivers_, vector<InputHandler *> &Add )
{ {
@@ -178,7 +176,7 @@ void InputHandler::Create( const RString &drivers_, vector<InputHandler *> &Add
FOREACH_CONST( RString, DriversToTry, s ) FOREACH_CONST( RString, DriversToTry, s )
{ {
RageDriver *pDriver = InputHandler::m_pDriverList.Create( *s ); RageDriver *pDriver = InputHandler::GetDriverList().Create( *s );
if( pDriver == NULL ) if( pDriver == NULL )
{ {
LOG->Trace( "Unknown Input Handler name: %s", s->c_str() ); LOG->Trace( "Unknown Input Handler name: %s", s->c_str() );
+7 -2
View File
@@ -23,7 +23,12 @@ class InputHandler: public RageDriver
{ {
public: public:
static void Create( const RString &sDrivers, vector<InputHandler *> &apAdd ); static void Create( const RString &sDrivers, vector<InputHandler *> &apAdd );
static DriverList m_pDriverList;
static DriverList & GetDriverList()
{
static DriverList driverList;
return driverList;
}
InputHandler(): m_LastUpdate(), m_iInputsSinceUpdate(0) {} InputHandler(): m_LastUpdate(), m_iInputsSinceUpdate(0) {}
virtual ~InputHandler() { } virtual ~InputHandler() { }
@@ -69,7 +74,7 @@ private:
}; };
#define REGISTER_INPUT_HANDLER_CLASS2( name, x ) \ #define REGISTER_INPUT_HANDLER_CLASS2( name, x ) \
static RegisterRageDriver register_##name( &InputHandler::m_pDriverList, #name, CreateClass<InputHandler_##x, RageDriver> ) static RegisterRageDriver register_##name( &InputHandler::GetDriverList(), #name, CreateClass<InputHandler_##x, RageDriver> )
#define REGISTER_INPUT_HANDLER_CLASS( name ) REGISTER_INPUT_HANDLER_CLASS2( name, name ) #define REGISTER_INPUT_HANDLER_CLASS( name ) REGISTER_INPUT_HANDLER_CLASS2( name, name )
+1 -3
View File
@@ -4,8 +4,6 @@
#include "Foreach.h" #include "Foreach.h"
#include "arch/arch_default.h" #include "arch/arch_default.h"
DriverList LightsDriver::m_pDriverList;
void LightsDriver::Create( const RString &sDrivers, vector<LightsDriver *> &Add ) void LightsDriver::Create( const RString &sDrivers, vector<LightsDriver *> &Add )
{ {
LOG->Trace( "Initializing lights drivers: %s", sDrivers.c_str() ); LOG->Trace( "Initializing lights drivers: %s", sDrivers.c_str() );
@@ -15,7 +13,7 @@ void LightsDriver::Create( const RString &sDrivers, vector<LightsDriver *> &Add
FOREACH_CONST( RString, asDriversToTry, Driver ) FOREACH_CONST( RString, asDriversToTry, Driver )
{ {
RageDriver *pRet = m_pDriverList.Create( *Driver ); RageDriver *pRet = GetDriverList().Create( *Driver );
if( pRet == NULL ) if( pRet == NULL )
{ {
LOG->Trace( "Unknown lights driver: %s", Driver->c_str() ); LOG->Trace( "Unknown lights driver: %s", Driver->c_str() );
+7 -2
View File
@@ -10,7 +10,12 @@ class LightsDriver: public RageDriver
{ {
public: public:
static void Create( const RString &sDriver, vector<LightsDriver *> &apAdd ); static void Create( const RString &sDriver, vector<LightsDriver *> &apAdd );
static DriverList m_pDriverList;
static DriverList & GetDriverList()
{
static DriverList driverList;
return driverList;
}
LightsDriver() {}; LightsDriver() {};
virtual ~LightsDriver() {}; virtual ~LightsDriver() {};
@@ -19,7 +24,7 @@ public:
}; };
#define REGISTER_SOUND_DRIVER_CLASS2( name, x ) \ #define REGISTER_SOUND_DRIVER_CLASS2( name, x ) \
static RegisterRageDriver register_##x( &LightsDriver::m_pDriverList, #name, CreateClass<LightsDriver_##x, RageDriver> ) static RegisterRageDriver register_##x( &LightsDriver::GetDriverList(), #name, CreateClass<LightsDriver_##x, RageDriver> )
#define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name ) #define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name )
#endif #endif
+1 -3
View File
@@ -62,8 +62,6 @@ bool RageMovieTexture::GetFourCC( RString fn, RString &handler, RString &type )
#undef HANDLE_ERROR #undef HANDLE_ERROR
} }
DriverList RageMovieTextureDriver::m_pDriverList;
// Helper for MakeRageMovieTexture() // Helper for MakeRageMovieTexture()
static void DumpAVIDebugInfo( const RString& fn ) static void DumpAVIDebugInfo( const RString& fn )
{ {
@@ -97,7 +95,7 @@ RageMovieTexture *RageMovieTexture::Create( RageTextureID ID )
FOREACH_CONST( RString, DriversToTry, Driver ) FOREACH_CONST( RString, DriversToTry, Driver )
{ {
LOG->Trace( "Initializing driver: %s", Driver->c_str() ); LOG->Trace( "Initializing driver: %s", Driver->c_str() );
RageDriver *pDriverBase = RageMovieTextureDriver::m_pDriverList.Create( *Driver ); RageDriver *pDriverBase = RageMovieTextureDriver::GetDriverList().Create( *Driver );
if( pDriverBase == NULL ) if( pDriverBase == NULL )
{ {
+6 -2
View File
@@ -32,11 +32,15 @@ class RageMovieTextureDriver: public RageDriver
public: public:
virtual ~RageMovieTextureDriver() { } virtual ~RageMovieTextureDriver() { }
virtual RageMovieTexture *Create( RageTextureID ID, RString &sError ) = 0; 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 ) \ #define REGISTER_MOVIE_TEXTURE_CLASS( name ) \
static RegisterRageDriver register_##name( &RageMovieTextureDriver::m_pDriverList, #name, CreateClass<RageMovieTextureDriver_##name, RageDriver> ) static RegisterRageDriver register_##name( &RageMovieTextureDriver::GetDriverList(), #name, CreateClass<RageMovieTextureDriver_##name, RageDriver> )
#endif #endif
+5 -8
View File
@@ -3,20 +3,17 @@
void DriverList::Add( const istring &sName, CreateRageDriverFn pfn ) void DriverList::Add( const istring &sName, CreateRageDriverFn pfn )
{ {
if( m_pRegistrees == NULL ) ASSERT( m_pRegistrees.find(sName) == m_pRegistrees.end() );
m_pRegistrees = new map<istring, CreateRageDriverFn>; m_pRegistrees[sName] = pfn;
ASSERT( m_pRegistrees->find(sName) == m_pRegistrees->end() );
(*m_pRegistrees)[sName] = pfn;
} }
RageDriver *DriverList::Create( const RString &sDriverName ) RageDriver *DriverList::Create( const RString &sDriverName )
{ {
if( m_pRegistrees == NULL ) if( m_pRegistrees.empty())
return NULL; return NULL;
map<istring, CreateRageDriverFn>::const_iterator iter = m_pRegistrees->find( istring(sDriverName) ); map<istring, CreateRageDriverFn>::const_iterator iter = m_pRegistrees.find( istring(sDriverName) );
if( iter == m_pRegistrees->end() ) if( iter == m_pRegistrees.end() )
return NULL; return NULL;
return (iter->second)(); return (iter->second)();
} }
+1 -2
View File
@@ -11,12 +11,11 @@ public:
typedef RageDriver *(*CreateRageDriverFn)(); typedef RageDriver *(*CreateRageDriverFn)();
/* This is created and accessed during C++ static initialization; it must be a POD. */
struct DriverList struct DriverList
{ {
void Add( const istring &sName, CreateRageDriverFn pfn ); void Add( const istring &sName, CreateRageDriverFn pfn );
RageDriver *Create( const RString &sDriverName ); RageDriver *Create( const RString &sDriverName );
map<istring, CreateRageDriverFn> *m_pRegistrees; map<istring, CreateRageDriverFn> m_pRegistrees;
}; };
struct RegisterRageDriver struct RegisterRageDriver
+1 -3
View File
@@ -5,8 +5,6 @@
#include "Foreach.h" #include "Foreach.h"
#include "arch/arch_default.h" #include "arch/arch_default.h"
DriverList RageSoundDriver::m_pDriverList;
RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers ) RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers )
{ {
vector<RString> DriversToTry; vector<RString> DriversToTry;
@@ -14,7 +12,7 @@ RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers )
FOREACH_CONST( RString, DriversToTry, Driver ) FOREACH_CONST( RString, DriversToTry, Driver )
{ {
RageDriver *pDriver = m_pDriverList.Create( *Driver ); RageDriver *pDriver = GetDriverList().Create( *Driver );
if( pDriver == NULL ) if( pDriver == NULL )
{ {
LOG->Trace( "Unknown sound driver: %s", Driver->c_str() ); LOG->Trace( "Unknown sound driver: %s", Driver->c_str() );
+7 -2
View File
@@ -17,7 +17,12 @@ class RageSoundDriver: public RageDriver
public: public:
/* Pass an empty string to get the default sound driver list. */ /* Pass an empty string to get the default sound driver list. */
static RageSoundDriver *Create( const RString &sDrivers ); static RageSoundDriver *Create( const RString &sDrivers );
static DriverList m_pDriverList;
static DriverList & GetDriverList()
{
static DriverList driverList;
return driverList;
}
friend class RageSoundManager; friend class RageSoundManager;
@@ -209,7 +214,7 @@ private:
// Can't use Create##name because many of these have -sw suffixes. // Can't use Create##name because many of these have -sw suffixes.
#define REGISTER_SOUND_DRIVER_CLASS2( name, x ) \ #define REGISTER_SOUND_DRIVER_CLASS2( name, x ) \
static RegisterRageDriver register_##x( &RageSoundDriver::m_pDriverList, #name, CreateClass<RageSoundDriver_##x, RageDriver> ) static RegisterRageDriver register_##x( &RageSoundDriver::GetDriverList(), #name, CreateClass<RageSoundDriver_##x, RageDriver> )
#define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name ) #define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name )
+6 -8
View File
@@ -7,12 +7,10 @@
const int MAX_THREADS=128; const int MAX_THREADS=128;
static MutexImpl_Win32 *g_pThreadIdMutex = NULL; MutexImpl_Win32 & GetThreadMutex()
static void InitThreadIdMutex()
{ {
if( g_pThreadIdMutex != NULL ) static MutexImpl_Win32 mutex(NULL);
return; return mutex;
g_pThreadIdMutex = new MutexImpl_Win32(NULL);
} }
static uint64_t g_ThreadIds[MAX_THREADS]; static uint64_t g_ThreadIds[MAX_THREADS];
@@ -108,9 +106,9 @@ static DWORD WINAPI StartThread( LPVOID pData )
static int GetOpenSlot( uint64_t iID ) static int GetOpenSlot( uint64_t iID )
{ {
InitThreadIdMutex(); MutexImpl_Win32 & mutex = GetThreadMutex();
g_pThreadIdMutex->Lock(); mutex.Lock();
// Find an open slot in g_ThreadIds. // Find an open slot in g_ThreadIds.
int slot = 0; int slot = 0;
@@ -120,7 +118,7 @@ static int GetOpenSlot( uint64_t iID )
g_ThreadIds[slot] = iID; g_ThreadIds[slot] = iID;
g_pThreadIdMutex->Unlock(); mutex.Unlock();
return slot; return slot;
} }