Revert memory leak commits
5f7001e: "Added a new branch"01456ed: "Fixed a lot of memory leaks"dac4493: "Fixed all remaining memory leaks that I could figure out"0792db7: "Removed the smnew macro and the call to _CrtSetDbgFlag()" Some of these caused destructor-time problems due to static initialization order fiasco and related issues. Notably, the program would no longer exit on OSX and had to be killed. There were probably legitimate fixes in here, but since these are monolithic commits it's too much work to extract them now. Let's reapply them individually and in the forward direction.
This commit is contained in:
+9
-15
@@ -14,26 +14,22 @@
|
||||
|
||||
|
||||
// Actor registration
|
||||
map<RString,CreateActorFn> & GetActorUtilRegistrees()
|
||||
{
|
||||
static map<RString, CreateActorFn> registrees;
|
||||
return registrees;
|
||||
}
|
||||
static map<RString,CreateActorFn> *g_pmapRegistrees = NULL;
|
||||
|
||||
static bool IsRegistered( const RString& sClassName )
|
||||
{
|
||||
map<RString, CreateActorFn> & registrees = GetActorUtilRegistrees();
|
||||
return registrees.find( sClassName ) != registrees.end();
|
||||
return g_pmapRegistrees->find( sClassName ) != g_pmapRegistrees->end();
|
||||
}
|
||||
|
||||
void ActorUtil::Register( const RString& sClassName, CreateActorFn pfn )
|
||||
{
|
||||
map<RString, CreateActorFn> & registrees = GetActorUtilRegistrees();
|
||||
if( g_pmapRegistrees == NULL )
|
||||
g_pmapRegistrees = new map<RString,CreateActorFn>;
|
||||
|
||||
map<RString,CreateActorFn>::iterator iter = registrees.find( sClassName );
|
||||
ASSERT_M( iter == registrees.end(), ssprintf("Actor class '%s' already registered.", sClassName.c_str()) );
|
||||
map<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClassName );
|
||||
ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Actor class '%s' already registered.", sClassName.c_str()) );
|
||||
|
||||
registrees[sClassName] = pfn;
|
||||
(*g_pmapRegistrees)[sClassName] = pfn;
|
||||
}
|
||||
|
||||
bool ActorUtil::ResolvePath( RString &sPath, const RString &sName )
|
||||
@@ -123,10 +119,8 @@ Actor* ActorUtil::LoadFromNode( const XNode* pNode, Actor *pParentActor )
|
||||
if( !bHasClass )
|
||||
bHasClass = pNode->GetAttrValue( "Type", sClass );
|
||||
|
||||
map<RString, CreateActorFn> & registrees = GetActorUtilRegistrees();
|
||||
|
||||
map<RString,CreateActorFn>::iterator iter = registrees.find( sClass );
|
||||
if( iter == registrees.end() )
|
||||
map<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClass );
|
||||
if( iter == g_pmapRegistrees->end() )
|
||||
{
|
||||
// sClass is invalid
|
||||
RString sError = ssprintf( "%s: invalid Class \"%s\"",
|
||||
|
||||
+2
-3
@@ -741,6 +741,8 @@ void Font::Load( const RString &sIniPath, RString sChars )
|
||||
{
|
||||
const RString &sTexturePath = asTexturePaths[i];
|
||||
|
||||
FontPage *pPage = new FontPage;
|
||||
|
||||
// Grab the page name, eg "foo" from "Normal [foo].png".
|
||||
RString sPagename = GetPageNameFromFileName( sTexturePath );
|
||||
|
||||
@@ -748,9 +750,6 @@ 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 = new FontPage;
|
||||
|
||||
// Load settings for this page from the INI.
|
||||
FontPageSettings cfg;
|
||||
LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars );
|
||||
|
||||
@@ -48,12 +48,6 @@ LifeMeterTime::LifeMeterTime()
|
||||
{
|
||||
m_fLifeTotalGainedSeconds = 0;
|
||||
m_fLifeTotalLostSeconds = 0;
|
||||
m_pStream = NULL;
|
||||
}
|
||||
|
||||
LifeMeterTime::~LifeMeterTime()
|
||||
{
|
||||
delete m_pStream;
|
||||
}
|
||||
|
||||
void LifeMeterTime::Load( const PlayerState *pPlayerState, PlayerStageStats *pPlayerStageStats )
|
||||
|
||||
@@ -16,8 +16,6 @@ class LifeMeterTime : public LifeMeter
|
||||
public:
|
||||
LifeMeterTime();
|
||||
|
||||
virtual ~LifeMeterTime();
|
||||
|
||||
virtual void Load( const PlayerState *pPlayerState, PlayerStageStats *pPlayerStageStats );
|
||||
|
||||
virtual void Update( float fDeltaTime );
|
||||
|
||||
@@ -4,11 +4,7 @@
|
||||
#include "RageUtil.h"
|
||||
#include "SubscriptionManager.h"
|
||||
|
||||
SubscriptionManager<LocalizedString> & GetLocalizedSubscribers()
|
||||
{
|
||||
static SubscriptionManager<LocalizedString> subscribers;
|
||||
return subscribers;
|
||||
}
|
||||
static SubscriptionManager<LocalizedString> m_Subscribers;
|
||||
|
||||
class LocalizedStringImplDefault: public ILocalizedStringImpl
|
||||
{
|
||||
@@ -31,7 +27,7 @@ static LocalizedString::MakeLocalizer g_pMakeLocalizedStringImpl = LocalizedStri
|
||||
void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc )
|
||||
{
|
||||
g_pMakeLocalizedStringImpl = pFunc;
|
||||
FOREACHS( LocalizedString*, GetLocalizedSubscribers().m_pSubscribers, l )
|
||||
FOREACHS( LocalizedString*, *m_Subscribers.m_pSubscribers, l )
|
||||
{
|
||||
LocalizedString *pLoc = *l;
|
||||
pLoc->CreateImpl();
|
||||
@@ -40,7 +36,7 @@ void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc )
|
||||
|
||||
LocalizedString::LocalizedString( const RString& sGroup, const RString& sName )
|
||||
{
|
||||
GetLocalizedSubscribers().Subscribe( this );
|
||||
m_Subscribers.Subscribe( this );
|
||||
|
||||
m_sGroup = sGroup;
|
||||
m_sName = sName;
|
||||
@@ -51,7 +47,7 @@ LocalizedString::LocalizedString( const RString& sGroup, const RString& sName )
|
||||
|
||||
LocalizedString::~LocalizedString()
|
||||
{
|
||||
GetLocalizedSubscribers().Unsubscribe( this );
|
||||
m_Subscribers.Unsubscribe( this );
|
||||
|
||||
SAFE_DELETE( m_pImpl );
|
||||
}
|
||||
|
||||
+5
-12
@@ -5,25 +5,18 @@
|
||||
#include "Foreach.h"
|
||||
|
||||
#include "SubscriptionManager.h"
|
||||
|
||||
SubscriptionManager<LuaBinding> & GetBindingSubscribers()
|
||||
{
|
||||
static SubscriptionManager<LuaBinding> subscribers;
|
||||
return subscribers;
|
||||
}
|
||||
static SubscriptionManager<LuaBinding> m_Subscribers;
|
||||
|
||||
namespace
|
||||
{
|
||||
void RegisterTypes( lua_State *L )
|
||||
{
|
||||
SubscriptionManager<LuaBinding> & subscribers = GetBindingSubscribers();
|
||||
|
||||
if( subscribers.m_pSubscribers.empty() )
|
||||
if( m_Subscribers.m_pSubscribers == NULL )
|
||||
return;
|
||||
|
||||
/* Register base classes first. */
|
||||
map<RString, LuaBinding *> mapToRegister;
|
||||
FOREACHS( LuaBinding*, subscribers.m_pSubscribers, p )
|
||||
FOREACHS( LuaBinding*, *m_Subscribers.m_pSubscribers, p )
|
||||
mapToRegister[(*p)->GetClassName()] = (*p);
|
||||
|
||||
set<RString> setRegisteredAlready;
|
||||
@@ -66,12 +59,12 @@ REGISTER_WITH_LUA_FUNCTION( RegisterTypes );
|
||||
|
||||
LuaBinding::LuaBinding()
|
||||
{
|
||||
GetBindingSubscribers().Subscribe( this );
|
||||
m_Subscribers.Subscribe( this );
|
||||
}
|
||||
|
||||
LuaBinding::~LuaBinding()
|
||||
{
|
||||
GetBindingSubscribers().Unsubscribe( this );
|
||||
m_Subscribers.Unsubscribe( this );
|
||||
}
|
||||
|
||||
void LuaBinding::Register( lua_State *L )
|
||||
|
||||
+12
-11
@@ -226,17 +226,17 @@ static int LuaPanic( lua_State *L )
|
||||
}
|
||||
|
||||
// Actor registration
|
||||
vector<RegisterWithLuaFn> & GetRegisteredActorTypes()
|
||||
{
|
||||
static vector<RegisterWithLuaFn> registeredActorTypes;
|
||||
return registeredActorTypes;
|
||||
}
|
||||
static vector<RegisterWithLuaFn> *g_vRegisterActorTypes = NULL;
|
||||
|
||||
void LuaManager::Register( RegisterWithLuaFn pfn )
|
||||
{
|
||||
GetRegisteredActorTypes().push_back( pfn );
|
||||
if( g_vRegisterActorTypes == NULL )
|
||||
g_vRegisterActorTypes = new vector<RegisterWithLuaFn>;
|
||||
|
||||
g_vRegisterActorTypes->push_back( pfn );
|
||||
}
|
||||
|
||||
|
||||
LuaManager::LuaManager()
|
||||
{
|
||||
pImpl = new Impl;
|
||||
@@ -360,12 +360,13 @@ void LuaManager::RegisterTypes()
|
||||
{
|
||||
Lua *L = Get();
|
||||
|
||||
vector<RegisterWithLuaFn> & registeredActorTypes = GetRegisteredActorTypes();
|
||||
|
||||
for( unsigned i=0; i<registeredActorTypes.size(); i++ )
|
||||
if( g_vRegisterActorTypes )
|
||||
{
|
||||
RegisterWithLuaFn fn = registeredActorTypes[i];
|
||||
fn( L );
|
||||
for( unsigned i=0; i<g_vRegisterActorTypes->size(); i++ )
|
||||
{
|
||||
RegisterWithLuaFn fn = (*g_vRegisterActorTypes)[i];
|
||||
fn( L );
|
||||
}
|
||||
}
|
||||
|
||||
Release( L );
|
||||
|
||||
@@ -22,11 +22,6 @@ MenuTimer::MenuTimer()
|
||||
WARNING_COMMAND = NULL;
|
||||
}
|
||||
|
||||
MenuTimer::~MenuTimer()
|
||||
{
|
||||
delete WARNING_COMMAND;
|
||||
}
|
||||
|
||||
void MenuTimer::Load( RString sMetricsGroup )
|
||||
{
|
||||
m_sprFrame.Load( THEME->GetPathG(sMetricsGroup, "Frame") );
|
||||
|
||||
@@ -15,7 +15,6 @@ class MenuTimer : public ActorFrame
|
||||
{
|
||||
public:
|
||||
MenuTimer();
|
||||
virtual ~MenuTimer();
|
||||
void Load( RString sMetricsGroup );
|
||||
|
||||
virtual void Update( float fDeltaTime );
|
||||
|
||||
+8
-12
@@ -7,27 +7,23 @@
|
||||
#include "SubscriptionManager.h"
|
||||
#include "Foreach.h"
|
||||
|
||||
SubscriptionManager<IPreference> & GetPreferenceSubscribers()
|
||||
{
|
||||
static SubscriptionManager<IPreference> subscribers;
|
||||
return subscribers;
|
||||
}
|
||||
static SubscriptionManager<IPreference> m_Subscribers;
|
||||
|
||||
IPreference::IPreference( const RString& sName ):
|
||||
m_sName( sName ),
|
||||
m_bIsStatic( false )
|
||||
{
|
||||
GetPreferenceSubscribers().Subscribe( this );
|
||||
m_Subscribers.Subscribe( this );
|
||||
}
|
||||
|
||||
IPreference::~IPreference()
|
||||
{
|
||||
GetPreferenceSubscribers().Unsubscribe( this );
|
||||
m_Subscribers.Unsubscribe( this );
|
||||
}
|
||||
|
||||
IPreference *IPreference::GetPreferenceByName( const RString &sName )
|
||||
{
|
||||
FOREACHS( IPreference*, GetPreferenceSubscribers().m_pSubscribers, p )
|
||||
FOREACHS( IPreference*, *m_Subscribers.m_pSubscribers, p )
|
||||
{
|
||||
if( !(*p)->GetName().CompareNoCase( sName ) )
|
||||
return *p;
|
||||
@@ -38,20 +34,20 @@ IPreference *IPreference::GetPreferenceByName( const RString &sName )
|
||||
|
||||
void IPreference::LoadAllDefaults()
|
||||
{
|
||||
FOREACHS_CONST( IPreference*, GetPreferenceSubscribers().m_pSubscribers, p )
|
||||
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p )
|
||||
(*p)->LoadDefault();
|
||||
}
|
||||
|
||||
void IPreference::ReadAllPrefsFromNode( const XNode* pNode, bool bIsStatic )
|
||||
{
|
||||
ASSERT( pNode != NULL );
|
||||
FOREACHS_CONST( IPreference*, GetPreferenceSubscribers().m_pSubscribers, p )
|
||||
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p )
|
||||
(*p)->ReadFrom( pNode, bIsStatic );
|
||||
}
|
||||
|
||||
void IPreference::SavePrefsToNode( XNode* pNode )
|
||||
{
|
||||
FOREACHS_CONST( IPreference*, GetPreferenceSubscribers().m_pSubscribers, p )
|
||||
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p )
|
||||
(*p)->WriteTo( pNode );
|
||||
}
|
||||
|
||||
@@ -59,7 +55,7 @@ void IPreference::ReadAllDefaultsFromNode( const XNode* pNode )
|
||||
{
|
||||
if( pNode == NULL )
|
||||
return;
|
||||
FOREACHS_CONST( IPreference*, GetPreferenceSubscribers().m_pSubscribers, p )
|
||||
FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p )
|
||||
(*p)->ReadDefaultFrom( pNode );
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "RageUtil.h"
|
||||
#include "RageMath.h"
|
||||
#include "RageThreads.h"
|
||||
#include "RageUtil_AutoPtr.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
@@ -398,28 +397,25 @@ int PolyphaseFilter::NumInputsForOutputSamples( const State &State, int iOut, in
|
||||
return iIn;
|
||||
}
|
||||
/** @brief Utilities for working with the PolyphaseFilter cache. */
|
||||
typedef AutoPtrCopyOnWrite<PolyphaseFilter> PolyphaseFilterAutoPtr;
|
||||
namespace PolyphaseFilterCache
|
||||
{
|
||||
/* Cache filter data, and reuse it without copying. All operations after creation
|
||||
* are const, so this doesn't cause thread-safety problems. */
|
||||
typedef map<pair<int,float>, PolyphaseFilterAutoPtr> FilterMap;
|
||||
typedef map<pair<int,float>, PolyphaseFilter *> FilterMap;
|
||||
static RageMutex PolyphaseFiltersLock("PolyphaseFiltersLock");
|
||||
static FilterMap g_mapPolyphaseFilters;
|
||||
|
||||
const PolyphaseFilterAutoPtr MakePolyphaseFilter( int iUpFactor, float fCutoffFrequency )
|
||||
const PolyphaseFilter *MakePolyphaseFilter( int iUpFactor, float fCutoffFrequency )
|
||||
{
|
||||
PolyphaseFilterAutoPtr result;
|
||||
|
||||
PolyphaseFiltersLock.Lock();
|
||||
pair<int,float> params( make_pair(iUpFactor, fCutoffFrequency) );
|
||||
FilterMap::const_iterator it = g_mapPolyphaseFilters.find(params);
|
||||
if( it != g_mapPolyphaseFilters.end() )
|
||||
{
|
||||
/* We already have a filter for this upsampling factor and cutoff; use it. */
|
||||
result = it->second;
|
||||
PolyphaseFilter *pPolyphase = it->second;
|
||||
PolyphaseFiltersLock.Unlock();
|
||||
return result;
|
||||
return pPolyphase;
|
||||
}
|
||||
int iWinSize = L*iUpFactor;
|
||||
float *pFIR = new float[iWinSize];
|
||||
@@ -432,14 +428,12 @@ namespace PolyphaseFilterCache
|
||||
pPolyphase->Generate( pFIR );
|
||||
delete [] pFIR;
|
||||
|
||||
result = PolyphaseFilterAutoPtr(pPolyphase);
|
||||
|
||||
g_mapPolyphaseFilters[params] = result;
|
||||
g_mapPolyphaseFilters[params] = pPolyphase;
|
||||
PolyphaseFiltersLock.Unlock();
|
||||
return result;
|
||||
return pPolyphase;
|
||||
}
|
||||
|
||||
const PolyphaseFilterAutoPtr FindNearestPolyphaseFilter( int iUpFactor, float fCutoffFrequency )
|
||||
const PolyphaseFilter *FindNearestPolyphaseFilter( int iUpFactor, float fCutoffFrequency )
|
||||
{
|
||||
/* 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
|
||||
@@ -450,7 +444,7 @@ namespace PolyphaseFilterCache
|
||||
if( it != g_mapPolyphaseFilters.begin() )
|
||||
--it;
|
||||
ASSERT( it->first.first == iUpFactor );
|
||||
PolyphaseFilterAutoPtr pPolyphase = it->second;
|
||||
PolyphaseFilter *pPolyphase = it->second;
|
||||
PolyphaseFiltersLock.Unlock();
|
||||
return pPolyphase;
|
||||
}
|
||||
@@ -473,7 +467,7 @@ public:
|
||||
* when filtering. This will only cause the low-pass filter to be rounded;
|
||||
* the conversion ratio will always be exact. */
|
||||
m_iUpFactor = iUpFactor;
|
||||
m_pPolyphase = PolyphaseFilterAutoPtr(NULL);
|
||||
m_pPolyphase = NULL;
|
||||
|
||||
int iFilterIncrement = max( (iMaxDownFactor - iMinDownFactor)/10, 1 );
|
||||
for( int iDownFactor = iMinDownFactor; iDownFactor <= iMaxDownFactor; iDownFactor += iFilterIncrement )
|
||||
@@ -538,13 +532,13 @@ private:
|
||||
return fCutoffFrequency;
|
||||
}
|
||||
|
||||
const PolyphaseFilterAutoPtr GetFilter( int iDownFactor ) const
|
||||
const PolyphaseFilter *GetFilter( int iDownFactor ) const
|
||||
{
|
||||
float fCutoffFrequency = GetCutoffFrequency( iDownFactor );
|
||||
return PolyphaseFilterCache::FindNearestPolyphaseFilter( m_iUpFactor, fCutoffFrequency );
|
||||
}
|
||||
|
||||
PolyphaseFilterAutoPtr m_pPolyphase;
|
||||
const PolyphaseFilter *m_pPolyphase;
|
||||
PolyphaseFilter::State *m_pState;
|
||||
int m_iUpFactor;
|
||||
int m_iDownFactor;
|
||||
|
||||
+2
-2
@@ -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 lock( "ThreadSlots" );
|
||||
return lock;
|
||||
static RageMutex *pLock = new RageMutex( "ThreadSlots" );
|
||||
return *pLock;
|
||||
}
|
||||
|
||||
static int FindEmptyThreadSlot()
|
||||
|
||||
+10
-17
@@ -52,18 +52,15 @@ static LocalizedString ON ( "ScreenDebugOverlay", "on" );
|
||||
static LocalizedString OFF ( "ScreenDebugOverlay", "off" );
|
||||
|
||||
class IDebugLine;
|
||||
vector<IDebugLine*> & GetSubscribers()
|
||||
{
|
||||
static vector<IDebugLine*> subscribers;
|
||||
return subscribers;
|
||||
}
|
||||
|
||||
static vector<IDebugLine*> *g_pvpSubscribers = NULL;
|
||||
class IDebugLine
|
||||
{
|
||||
public:
|
||||
IDebugLine()
|
||||
{
|
||||
GetSubscribers().push_back( this );
|
||||
if( g_pvpSubscribers == NULL )
|
||||
g_pvpSubscribers = new vector<IDebugLine*>;
|
||||
g_pvpSubscribers->push_back( this );
|
||||
}
|
||||
virtual ~IDebugLine() { }
|
||||
enum Type { all_screens, gameplay_only };
|
||||
@@ -218,7 +215,7 @@ void ScreenDebugOverlay::Init()
|
||||
|
||||
map<RString,int> iNextDebugButton;
|
||||
int iNextGameplayButton = 0;
|
||||
FOREACH( IDebugLine*, GetSubscribers(), p )
|
||||
FOREACH( IDebugLine*, *g_pvpSubscribers, p )
|
||||
{
|
||||
RString sPageName = (*p)->GetPageName();
|
||||
|
||||
@@ -274,7 +271,7 @@ void ScreenDebugOverlay::Init()
|
||||
this->AddChild( p );
|
||||
}
|
||||
|
||||
FOREACH_CONST( IDebugLine*, GetSubscribers(), p )
|
||||
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p )
|
||||
{
|
||||
{
|
||||
BitmapText *bt = new BitmapText;
|
||||
@@ -353,15 +350,13 @@ void ScreenDebugOverlay::UpdateText()
|
||||
m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" );
|
||||
}
|
||||
|
||||
vector<IDebugLine*> & subscribers = GetSubscribers();
|
||||
|
||||
// todo: allow changing of various spacing/location things -aj
|
||||
int iOffset = 0;
|
||||
FOREACH_CONST( IDebugLine*, subscribers, p )
|
||||
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p )
|
||||
{
|
||||
RString sPageName = (*p)->GetPageName();
|
||||
|
||||
int i = p-subscribers.begin();
|
||||
int i = p-g_pvpSubscribers->begin();
|
||||
|
||||
float fY = LINE_START_Y + iOffset * LINE_SPACING;
|
||||
|
||||
@@ -452,13 +447,11 @@ bool ScreenDebugOverlay::Input( const InputEventPlus &input )
|
||||
return true;
|
||||
}
|
||||
|
||||
vector<IDebugLine*> & subscribers = GetSubscribers();
|
||||
|
||||
FOREACH_CONST( IDebugLine*, subscribers, p )
|
||||
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p )
|
||||
{
|
||||
RString sPageName = (*p)->GetPageName();
|
||||
|
||||
int i = p-subscribers.begin();
|
||||
int i = p-g_pvpSubscribers->begin();
|
||||
|
||||
// Gameplay buttons are available only in gameplay. Non-gameplay buttons
|
||||
// are only available when the screen is displayed.
|
||||
|
||||
+9
-14
@@ -79,11 +79,7 @@ static Preference<bool> g_bDelayedScreenLoad( "DelayedScreenLoad", false );
|
||||
//static Preference<bool> g_bPruneFonts( "PruneFonts", true );
|
||||
|
||||
// Screen registration
|
||||
map<RString, CreateScreenFn> & GetRegistrees()
|
||||
{
|
||||
static map<RString, CreateScreenFn> registrees;
|
||||
return registrees;
|
||||
}
|
||||
static map<RString,CreateScreenFn> *g_pmapRegistrees = NULL;
|
||||
|
||||
/** @brief Utility functions for the ScreenManager. */
|
||||
namespace ScreenManagerUtil
|
||||
@@ -223,12 +219,13 @@ using namespace ScreenManagerUtil;
|
||||
|
||||
RegisterScreenClass::RegisterScreenClass( const RString& sClassName, CreateScreenFn pfn )
|
||||
{
|
||||
map<RString,CreateScreenFn> & registrees = GetRegistrees();
|
||||
if( g_pmapRegistrees == NULL )
|
||||
g_pmapRegistrees = new map<RString,CreateScreenFn>;
|
||||
|
||||
map<RString,CreateScreenFn>::iterator iter = registrees.find( sClassName );
|
||||
ASSERT_M( iter == registrees.end(), ssprintf("Screen class '%s' already registered.", sClassName.c_str()) );
|
||||
map<RString,CreateScreenFn>::iterator iter = g_pmapRegistrees->find( sClassName );
|
||||
ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Screen class '%s' already registered.", sClassName.c_str()) );
|
||||
|
||||
registrees[sClassName] = pfn;
|
||||
(*g_pmapRegistrees)[sClassName] = pfn;
|
||||
}
|
||||
|
||||
|
||||
@@ -535,10 +532,8 @@ Screen* ScreenManager::MakeNewScreen( const RString &sScreenName )
|
||||
|
||||
RString sClassName = THEME->GetMetric( sScreenName,"Class" );
|
||||
|
||||
map<RString,CreateScreenFn> & registrees = GetRegistrees();
|
||||
|
||||
map<RString,CreateScreenFn>::iterator iter = registrees.find( sClassName );
|
||||
if( iter == registrees.end() )
|
||||
map<RString,CreateScreenFn>::iterator iter = g_pmapRegistrees->find( sClassName );
|
||||
if( iter == g_pmapRegistrees->end() )
|
||||
RageException::Throw( "Screen \"%s\" has an invalid class \"%s\".", sScreenName.c_str(), sClassName.c_str() );
|
||||
|
||||
this->ZeroNextUpdate();
|
||||
@@ -876,7 +871,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, GetRegistrees().find( SArg(1) ) != GetRegistrees().end() ); 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 AddNewScreenToTop( T* p, lua_State *L )
|
||||
{
|
||||
ScreenMessage SM = SM_None;
|
||||
|
||||
+7
-10
@@ -17,25 +17,22 @@ AutoScreenMessage(SM_Pause);
|
||||
AutoScreenMessage(SM_Success);
|
||||
AutoScreenMessage(SM_Failure);
|
||||
|
||||
map<RString, ScreenMessage> & GetScreenMessages()
|
||||
{
|
||||
static map<RString, ScreenMessage> screenMessages;
|
||||
return screenMessages;
|
||||
}
|
||||
static map<RString, ScreenMessage> *m_pScreenMessages;
|
||||
|
||||
ScreenMessage ScreenMessageHelpers::ToScreenMessage( const RString &sName )
|
||||
{
|
||||
map<RString, ScreenMessage> & screenMessages = GetScreenMessages();
|
||||
if( m_pScreenMessages == NULL )
|
||||
m_pScreenMessages = new map<RString, ScreenMessage>;
|
||||
|
||||
if( screenMessages.find( sName ) == screenMessages.end() )
|
||||
screenMessages[sName] = (ScreenMessage)sName;
|
||||
if( m_pScreenMessages->find( sName ) == m_pScreenMessages->end() )
|
||||
(*m_pScreenMessages)[sName] = (ScreenMessage)sName;
|
||||
|
||||
return screenMessages[sName];
|
||||
return (*m_pScreenMessages)[sName];
|
||||
}
|
||||
|
||||
RString ScreenMessageHelpers::ScreenMessageToString( ScreenMessage SM )
|
||||
{
|
||||
FOREACHM( RString, ScreenMessage, GetScreenMessages(), it )
|
||||
FOREACHM( RString, ScreenMessage, *m_pScreenMessages, it )
|
||||
if( SM == it->second )
|
||||
return (*it).first;
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ StreamDisplay::StreamDisplay()
|
||||
m_fPassingAlpha = 0;
|
||||
m_fHotAlpha = 0;
|
||||
m_bAlwaysBounce = false;
|
||||
|
||||
m_bDeleteChildren = true;
|
||||
}
|
||||
|
||||
void StreamDisplay::Load( const RString & /* unreferenced: _sMetricsGroup */)
|
||||
|
||||
+27
-17
@@ -5,36 +5,46 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
// 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<T> & GetSubscribers()
|
||||
// {
|
||||
// static SubscriptionManager<T> subscribers;
|
||||
// return subscribers;
|
||||
// }
|
||||
//
|
||||
// This ensures that the object is always available when it's needed.
|
||||
// Since this class has only POD types and no constructor, there's no
|
||||
// initialize order problem.
|
||||
template<class T>
|
||||
class SubscriptionManager
|
||||
{
|
||||
public:
|
||||
set<T*> m_pSubscribers;
|
||||
// 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<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 )
|
||||
{
|
||||
if( m_pSubscribers == NULL )
|
||||
m_pSubscribers = new set<T*>;
|
||||
#ifdef DEBUG
|
||||
typename set<T*>::iterator iter = m_pSubscribers.find( p );
|
||||
ASSERT_M( iter == m_pSubscribers.end(), "already subscribed" );
|
||||
typename set<T*>::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<T*>::iterator iter = m_pSubscribers.find( p );
|
||||
ASSERT( iter != m_pSubscribers.end() );
|
||||
m_pSubscribers.erase( iter );
|
||||
typename set<T*>::iterator iter = m_pSubscribers->find( p );
|
||||
ASSERT( iter != m_pSubscribers->end() );
|
||||
m_pSubscribers->erase( iter );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+13
-12
@@ -63,12 +63,7 @@ LoadedThemeData *g_pLoadedThemeData = NULL;
|
||||
|
||||
// For self-registering metrics
|
||||
#include "SubscriptionManager.h"
|
||||
|
||||
SubscriptionManager<IThemeMetric> & GetMetricSubscribers()
|
||||
{
|
||||
static SubscriptionManager<IThemeMetric> subscribers;
|
||||
return subscribers;
|
||||
}
|
||||
static SubscriptionManager<IThemeMetric> g_Subscribers;
|
||||
|
||||
class LocalizedStringImplThemeMetric : public ILocalizedStringImpl, public ThemeMetric<RString>
|
||||
{
|
||||
@@ -100,7 +95,7 @@ public:
|
||||
|
||||
void ThemeManager::Subscribe( IThemeMetric *p )
|
||||
{
|
||||
GetMetricSubscribers().Subscribe( p );
|
||||
g_Subscribers.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
|
||||
@@ -112,7 +107,7 @@ void ThemeManager::Subscribe( IThemeMetric *p )
|
||||
|
||||
void ThemeManager::Unsubscribe( IThemeMetric *p )
|
||||
{
|
||||
GetMetricSubscribers().Unsubscribe( p );
|
||||
g_Subscribers.Unsubscribe( p );
|
||||
}
|
||||
|
||||
|
||||
@@ -434,14 +429,20 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt
|
||||
void ThemeManager::ReloadSubscribers()
|
||||
{
|
||||
// reload subscribers
|
||||
FOREACHS_CONST( IThemeMetric*, GetMetricSubscribers().m_pSubscribers, p )
|
||||
(*p)->Read();
|
||||
if( g_Subscribers.m_pSubscribers )
|
||||
{
|
||||
FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p )
|
||||
(*p)->Read();
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeManager::ClearSubscribers()
|
||||
{
|
||||
FOREACHS_CONST( IThemeMetric*, GetMetricSubscribers().m_pSubscribers, p )
|
||||
(*p)->Clear();
|
||||
if( g_Subscribers.m_pSubscribers )
|
||||
{
|
||||
FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p )
|
||||
(*p)->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeManager::RunLuaScripts( const RString &sMask, bool bUseThemeDir )
|
||||
|
||||
@@ -187,7 +187,6 @@ public:
|
||||
{
|
||||
Load( RString(), NULL, 0 );
|
||||
}
|
||||
virtual ~ThemeMetric1D() { }
|
||||
void Load( const RString& sGroup, MetricName1D pfn, size_t N )
|
||||
{
|
||||
m_metric.resize( N );
|
||||
|
||||
+16
-43
@@ -268,55 +268,28 @@ 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
|
||||
*
|
||||
* 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 )
|
||||
* segment in the TimingData, and if not, we'll crash anyway. -- vyhd */
|
||||
static const TimingSegment* DummySegments[NUM_TimingSegmentType] =
|
||||
{
|
||||
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;
|
||||
}
|
||||
NULL, // BPMSegment
|
||||
new StopSegment,
|
||||
new DelaySegment,
|
||||
NULL, // TimeSignatureSegment
|
||||
new WarpSegment,
|
||||
NULL, // LabelSegment
|
||||
NULL, // TickcountSegment
|
||||
NULL, // ComboSegment
|
||||
NULL, // SpeedSegment
|
||||
NULL, // ScrollSegment
|
||||
new FakeSegment
|
||||
};
|
||||
|
||||
const TimingSegment* TimingData::GetSegmentAtRow( int iNoteRow, TimingSegmentType tst ) const
|
||||
{
|
||||
const vector<TimingSegment*> &vSegments = GetTimingSegments(tst);
|
||||
|
||||
if( vSegments.empty() )
|
||||
return GetDummyTimingSegment(tst);
|
||||
return DummySegments[tst];
|
||||
|
||||
int index = GetSegmentIndexAtRow( tst, iNoteRow );
|
||||
const TimingSegment *seg = vSegments[index];
|
||||
@@ -335,7 +308,7 @@ const TimingSegment* TimingData::GetSegmentAtRow( int iNoteRow, TimingSegmentTyp
|
||||
if( seg->GetRow() == iNoteRow )
|
||||
return seg;
|
||||
else
|
||||
return GetDummyTimingSegment(tst);
|
||||
return DummySegments[tst];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
#include "Foreach.h"
|
||||
#include "RageLog.h"
|
||||
|
||||
map<istring, CreateDialogDriverFn> *RegisterDialogDriver::g_pRegistrees;
|
||||
RegisterDialogDriver::RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn )
|
||||
{
|
||||
map<istring, CreateDialogDriverFn> & registrees = GetRegistrees();
|
||||
ASSERT( registrees.find(sName) == registrees.end() );
|
||||
registrees[sName] = pfn;
|
||||
if( g_pRegistrees == NULL )
|
||||
g_pRegistrees = new map<istring, CreateDialogDriverFn>;
|
||||
|
||||
ASSERT( g_pRegistrees->find(sName) == g_pRegistrees->end() );
|
||||
(*g_pRegistrees)[sName] = pfn;
|
||||
}
|
||||
|
||||
REGISTER_DIALOG_DRIVER_CLASS( Null );
|
||||
@@ -20,13 +23,11 @@ DialogDriver *DialogDriver::Create()
|
||||
|
||||
ASSERT( asDriversToTry.size() != 0 );
|
||||
|
||||
map<istring, CreateDialogDriverFn> & registrees = RegisterDialogDriver::GetRegistrees();
|
||||
|
||||
FOREACH_CONST( RString, asDriversToTry, Driver )
|
||||
{
|
||||
map<istring, CreateDialogDriverFn>::const_iterator iter = registrees.find( istring(*Driver) );
|
||||
map<istring, CreateDialogDriverFn>::const_iterator iter = RegisterDialogDriver::g_pRegistrees->find( istring(*Driver) );
|
||||
|
||||
if( iter == registrees.end() )
|
||||
if( iter == RegisterDialogDriver::g_pRegistrees->end() )
|
||||
continue;
|
||||
|
||||
DialogDriver *pRet = (iter->second)();
|
||||
|
||||
@@ -25,12 +25,7 @@ class DialogDriver_Null : public DialogDriver { };
|
||||
typedef DialogDriver *(*CreateDialogDriverFn)();
|
||||
struct RegisterDialogDriver
|
||||
{
|
||||
static map<istring, CreateDialogDriverFn> & GetRegistrees()
|
||||
{
|
||||
static map<istring, CreateDialogDriverFn> registrees;
|
||||
return registrees;
|
||||
}
|
||||
|
||||
static map<istring, CreateDialogDriverFn> *g_pRegistrees;
|
||||
RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn );
|
||||
};
|
||||
#define REGISTER_DIALOG_DRIVER_CLASS( name ) \
|
||||
|
||||
@@ -164,6 +164,8 @@ 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<InputHandler *> &Add )
|
||||
{
|
||||
@@ -176,7 +178,7 @@ void InputHandler::Create( const RString &drivers_, vector<InputHandler *> &Add
|
||||
|
||||
FOREACH_CONST( RString, DriversToTry, s )
|
||||
{
|
||||
RageDriver *pDriver = InputHandler::GetDriverList().Create( *s );
|
||||
RageDriver *pDriver = InputHandler::m_pDriverList.Create( *s );
|
||||
if( pDriver == NULL )
|
||||
{
|
||||
LOG->Trace( "Unknown Input Handler name: %s", s->c_str() );
|
||||
|
||||
@@ -23,12 +23,7 @@ class InputHandler: public RageDriver
|
||||
{
|
||||
public:
|
||||
static void Create( const RString &sDrivers, vector<InputHandler *> &apAdd );
|
||||
|
||||
static DriverList & GetDriverList()
|
||||
{
|
||||
static DriverList driverList;
|
||||
return driverList;
|
||||
}
|
||||
static DriverList m_pDriverList;
|
||||
|
||||
InputHandler(): m_LastUpdate(), m_iInputsSinceUpdate(0) {}
|
||||
virtual ~InputHandler() { }
|
||||
@@ -74,7 +69,7 @@ private:
|
||||
};
|
||||
|
||||
#define REGISTER_INPUT_HANDLER_CLASS2( name, x ) \
|
||||
static RegisterRageDriver register_##name( &InputHandler::GetDriverList(), #name, CreateClass<InputHandler_##x, RageDriver> )
|
||||
static RegisterRageDriver register_##name( &InputHandler::m_pDriverList, #name, CreateClass<InputHandler_##x, RageDriver> )
|
||||
#define REGISTER_INPUT_HANDLER_CLASS( name ) REGISTER_INPUT_HANDLER_CLASS2( name, name )
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "Foreach.h"
|
||||
#include "arch/arch_default.h"
|
||||
|
||||
DriverList LightsDriver::m_pDriverList;
|
||||
|
||||
void LightsDriver::Create( const RString &sDrivers, vector<LightsDriver *> &Add )
|
||||
{
|
||||
LOG->Trace( "Initializing lights drivers: %s", sDrivers.c_str() );
|
||||
@@ -13,7 +15,7 @@ void LightsDriver::Create( const RString &sDrivers, vector<LightsDriver *> &Add
|
||||
|
||||
FOREACH_CONST( RString, asDriversToTry, Driver )
|
||||
{
|
||||
RageDriver *pRet = GetDriverList().Create( *Driver );
|
||||
RageDriver *pRet = m_pDriverList.Create( *Driver );
|
||||
if( pRet == NULL )
|
||||
{
|
||||
LOG->Trace( "Unknown lights driver: %s", Driver->c_str() );
|
||||
|
||||
@@ -10,12 +10,7 @@ class LightsDriver: public RageDriver
|
||||
{
|
||||
public:
|
||||
static void Create( const RString &sDriver, vector<LightsDriver *> &apAdd );
|
||||
|
||||
static DriverList & GetDriverList()
|
||||
{
|
||||
static DriverList driverList;
|
||||
return driverList;
|
||||
}
|
||||
static DriverList m_pDriverList;
|
||||
|
||||
LightsDriver() {};
|
||||
virtual ~LightsDriver() {};
|
||||
@@ -24,7 +19,7 @@ public:
|
||||
};
|
||||
|
||||
#define REGISTER_SOUND_DRIVER_CLASS2( name, x ) \
|
||||
static RegisterRageDriver register_##x( &LightsDriver::GetDriverList(), #name, CreateClass<LightsDriver_##x, RageDriver> )
|
||||
static RegisterRageDriver register_##x( &LightsDriver::m_pDriverList, #name, CreateClass<LightsDriver_##x, RageDriver> )
|
||||
#define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name )
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,6 +62,8 @@ 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 )
|
||||
{
|
||||
@@ -95,7 +97,7 @@ RageMovieTexture *RageMovieTexture::Create( RageTextureID ID )
|
||||
FOREACH_CONST( RString, DriversToTry, Driver )
|
||||
{
|
||||
LOG->Trace( "Initializing driver: %s", Driver->c_str() );
|
||||
RageDriver *pDriverBase = RageMovieTextureDriver::GetDriverList().Create( *Driver );
|
||||
RageDriver *pDriverBase = RageMovieTextureDriver::m_pDriverList.Create( *Driver );
|
||||
|
||||
if( pDriverBase == NULL )
|
||||
{
|
||||
|
||||
@@ -32,15 +32,11 @@ class RageMovieTextureDriver: public RageDriver
|
||||
public:
|
||||
virtual ~RageMovieTextureDriver() { }
|
||||
virtual RageMovieTexture *Create( RageTextureID ID, RString &sError ) = 0;
|
||||
static DriverList & GetDriverList()
|
||||
{
|
||||
static DriverList driverList;
|
||||
return driverList;
|
||||
}
|
||||
static DriverList m_pDriverList;
|
||||
};
|
||||
|
||||
#define REGISTER_MOVIE_TEXTURE_CLASS( name ) \
|
||||
static RegisterRageDriver register_##name( &RageMovieTextureDriver::GetDriverList(), #name, CreateClass<RageMovieTextureDriver_##name, RageDriver> )
|
||||
static RegisterRageDriver register_##name( &RageMovieTextureDriver::m_pDriverList, #name, CreateClass<RageMovieTextureDriver_##name, RageDriver> )
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,17 +3,20 @@
|
||||
|
||||
void DriverList::Add( const istring &sName, CreateRageDriverFn pfn )
|
||||
{
|
||||
ASSERT( m_pRegistrees.find(sName) == m_pRegistrees.end() );
|
||||
m_pRegistrees[sName] = pfn;
|
||||
if( m_pRegistrees == NULL )
|
||||
m_pRegistrees = new map<istring, CreateRageDriverFn>;
|
||||
|
||||
ASSERT( m_pRegistrees->find(sName) == m_pRegistrees->end() );
|
||||
(*m_pRegistrees)[sName] = pfn;
|
||||
}
|
||||
|
||||
RageDriver *DriverList::Create( const RString &sDriverName )
|
||||
{
|
||||
if( m_pRegistrees.empty())
|
||||
if( m_pRegistrees == NULL )
|
||||
return NULL;
|
||||
|
||||
map<istring, CreateRageDriverFn>::const_iterator iter = m_pRegistrees.find( istring(sDriverName) );
|
||||
if( iter == m_pRegistrees.end() )
|
||||
map<istring, CreateRageDriverFn>::const_iterator iter = m_pRegistrees->find( istring(sDriverName) );
|
||||
if( iter == m_pRegistrees->end() )
|
||||
return NULL;
|
||||
return (iter->second)();
|
||||
}
|
||||
|
||||
@@ -11,11 +11,12 @@ 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<istring, CreateRageDriverFn> m_pRegistrees;
|
||||
map<istring, CreateRageDriverFn> *m_pRegistrees;
|
||||
};
|
||||
|
||||
struct RegisterRageDriver
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "Foreach.h"
|
||||
#include "arch/arch_default.h"
|
||||
|
||||
DriverList RageSoundDriver::m_pDriverList;
|
||||
|
||||
RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers )
|
||||
{
|
||||
vector<RString> DriversToTry;
|
||||
@@ -12,7 +14,7 @@ RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers )
|
||||
|
||||
FOREACH_CONST( RString, DriversToTry, Driver )
|
||||
{
|
||||
RageDriver *pDriver = GetDriverList().Create( *Driver );
|
||||
RageDriver *pDriver = m_pDriverList.Create( *Driver );
|
||||
if( pDriver == NULL )
|
||||
{
|
||||
LOG->Trace( "Unknown sound driver: %s", Driver->c_str() );
|
||||
|
||||
@@ -17,12 +17,7 @@ class RageSoundDriver: public RageDriver
|
||||
public:
|
||||
/* Pass an empty string to get the default sound driver list. */
|
||||
static RageSoundDriver *Create( const RString &sDrivers );
|
||||
|
||||
static DriverList & GetDriverList()
|
||||
{
|
||||
static DriverList driverList;
|
||||
return driverList;
|
||||
}
|
||||
static DriverList m_pDriverList;
|
||||
|
||||
friend class RageSoundManager;
|
||||
|
||||
@@ -214,7 +209,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::GetDriverList(), #name, CreateClass<RageSoundDriver_##x, RageDriver> )
|
||||
static RegisterRageDriver register_##x( &RageSoundDriver::m_pDriverList, #name, CreateClass<RageSoundDriver_##x, RageDriver> )
|
||||
#define REGISTER_SOUND_DRIVER_CLASS( name ) REGISTER_SOUND_DRIVER_CLASS2( name, name )
|
||||
|
||||
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
|
||||
const int MAX_THREADS=128;
|
||||
|
||||
MutexImpl_Win32 & GetThreadMutex()
|
||||
static MutexImpl_Win32 *g_pThreadIdMutex = NULL;
|
||||
static void InitThreadIdMutex()
|
||||
{
|
||||
static MutexImpl_Win32 mutex(NULL);
|
||||
return mutex;
|
||||
if( g_pThreadIdMutex != NULL )
|
||||
return;
|
||||
g_pThreadIdMutex = new MutexImpl_Win32(NULL);
|
||||
}
|
||||
|
||||
static uint64_t g_ThreadIds[MAX_THREADS];
|
||||
@@ -106,9 +108,9 @@ static DWORD WINAPI StartThread( LPVOID pData )
|
||||
|
||||
static int GetOpenSlot( uint64_t iID )
|
||||
{
|
||||
MutexImpl_Win32 & mutex = GetThreadMutex();
|
||||
InitThreadIdMutex();
|
||||
|
||||
mutex.Lock();
|
||||
g_pThreadIdMutex->Lock();
|
||||
|
||||
// Find an open slot in g_ThreadIds.
|
||||
int slot = 0;
|
||||
@@ -118,7 +120,7 @@ static int GetOpenSlot( uint64_t iID )
|
||||
|
||||
g_ThreadIds[slot] = iID;
|
||||
|
||||
mutex.Unlock();
|
||||
g_pThreadIdMutex->Unlock();
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user