Fixed a lot of memory leaks caused by static globals never getting

deleted and some other objects not getting deleted properly due to missing
destructors.
This commit is contained in:
Shenjoku
2013-04-18 21:17:57 -07:00
parent 5f7001ef0a
commit 01456ed0b9
29 changed files with 239 additions and 171 deletions
+15 -9
View File
@@ -14,22 +14,26 @@
// 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 )
{
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 )
{
if( g_pmapRegistrees == NULL )
g_pmapRegistrees = smnew map<RString,CreateActorFn>;
map<RString, CreateActorFn> & registrees = GetRegistrees();
map<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClassName );
ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Actor class '%s' already registered.", sClassName.c_str()) );
map<RString,CreateActorFn>::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<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClass );
if( iter == g_pmapRegistrees->end() )
map<RString, CreateActorFn> & registrees = GetRegistrees();
map<RString,CreateActorFn>::iterator iter = registrees.find( sClass );
if( iter == registrees.end() )
{
// sClass is invalid
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];
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 );
+8 -4
View File
@@ -4,7 +4,11 @@
#include "RageUtil.h"
#include "SubscriptionManager.h"
static SubscriptionManager<LocalizedString> m_Subscribers;
SubscriptionManager<LocalizedString> & GetSubscribers()
{
static SubscriptionManager<LocalizedString> 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 );
}
+12 -5
View File
@@ -5,18 +5,25 @@
#include "Foreach.h"
#include "SubscriptionManager.h"
static SubscriptionManager<LuaBinding> m_Subscribers;
SubscriptionManager<LuaBinding> & GetSubscribers()
{
static SubscriptionManager<LuaBinding> subscribers;
return subscribers;
}
namespace
{
void RegisterTypes( lua_State *L )
{
if( m_Subscribers.m_pSubscribers == NULL )
SubscriptionManager<LuaBinding> & subscribers = GetSubscribers();
if( subscribers.m_pSubscribers.empty() )
return;
/* Register base classes first. */
map<RString, LuaBinding *> mapToRegister;
FOREACHS( LuaBinding*, *m_Subscribers.m_pSubscribers, p )
FOREACHS( LuaBinding*, subscribers.m_pSubscribers, p )
mapToRegister[(*p)->GetClassName()] = (*p);
set<RString> 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 )
+11 -12
View File
@@ -226,17 +226,17 @@ static int LuaPanic( lua_State *L )
}
// Actor registration
static vector<RegisterWithLuaFn> *g_vRegisterActorTypes = NULL;
vector<RegisterWithLuaFn> & GetRegisteredActorTypes()
{
static vector<RegisterWithLuaFn> registeredActorTypes;
return registeredActorTypes;
}
void LuaManager::Register( RegisterWithLuaFn pfn )
{
if( g_vRegisterActorTypes == NULL )
g_vRegisterActorTypes = smnew vector<RegisterWithLuaFn>;
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<RegisterWithLuaFn> & registeredActorTypes = GetRegisteredActorTypes();
for( unsigned i=0; i<registeredActorTypes.size(); i++ )
{
for( unsigned i=0; i<g_vRegisterActorTypes->size(); i++ )
{
RegisterWithLuaFn fn = (*g_vRegisterActorTypes)[i];
fn( L );
}
RegisterWithLuaFn fn = registeredActorTypes[i];
fn( L );
}
Release( L );
+5
View File
@@ -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") );
+1
View File
@@ -15,6 +15,7 @@ class MenuTimer : public ActorFrame
{
public:
MenuTimer();
virtual ~MenuTimer();
void Load( RString sMetricsGroup );
virtual void Update( float fDeltaTime );
+12 -8
View File
@@ -7,23 +7,27 @@
#include "SubscriptionManager.h"
#include "Foreach.h"
static SubscriptionManager<IPreference> m_Subscribers;
SubscriptionManager<IPreference> & GetSubscribers()
{
static SubscriptionManager<IPreference> 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 );
}
+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). */
static RageMutex &GetThreadSlotsLock()
{
static RageMutex *pLock = smnew RageMutex( "ThreadSlots" );
return *pLock;
static RageMutex lock( "ThreadSlots" );
return lock;
}
static int FindEmptyThreadSlot()
+17 -10
View File
@@ -52,15 +52,18 @@ static LocalizedString ON ( "ScreenDebugOverlay", "on" );
static LocalizedString OFF ( "ScreenDebugOverlay", "off" );
class IDebugLine;
static vector<IDebugLine*> *g_pvpSubscribers = NULL;
vector<IDebugLine*> & GetSubscribers()
{
static vector<IDebugLine*> subscribers;
return subscribers;
}
class IDebugLine
{
public:
IDebugLine()
{
if( g_pvpSubscribers == NULL )
g_pvpSubscribers = smnew vector<IDebugLine*>;
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<RString,int> 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<IDebugLine*> & 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<IDebugLine*> & 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.
+14 -9
View File
@@ -79,7 +79,11 @@ static Preference<bool> g_bDelayedScreenLoad( "DelayedScreenLoad", false );
//static Preference<bool> g_bPruneFonts( "PruneFonts", true );
// 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. */
namespace ScreenManagerUtil
@@ -219,13 +223,12 @@ using namespace ScreenManagerUtil;
RegisterScreenClass::RegisterScreenClass( const RString& sClassName, CreateScreenFn pfn )
{
if( g_pmapRegistrees == NULL )
g_pmapRegistrees = smnew map<RString,CreateScreenFn>;
map<RString,CreateScreenFn> & registrees = GetRegistrees();
map<RString,CreateScreenFn>::iterator iter = g_pmapRegistrees->find( sClassName );
ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Screen class '%s' already registered.", sClassName.c_str()) );
map<RString,CreateScreenFn>::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<RString,CreateScreenFn>::iterator iter = g_pmapRegistrees->find( sClassName );
if( iter == g_pmapRegistrees->end() )
map<RString,CreateScreenFn> & registrees = GetRegistrees();
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() );
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;
+10 -7
View File
@@ -17,22 +17,25 @@ AutoScreenMessage(SM_Pause);
AutoScreenMessage(SM_Success);
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 )
{
if( m_pScreenMessages == NULL )
m_pScreenMessages = smnew map<RString, ScreenMessage>;
map<RString, ScreenMessage> & 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;
+17 -27
View File
@@ -5,46 +5,36 @@
#include <set>
// 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<T> & GetSubscribers()
// {
// static SubscriptionManager<T> subscribers;
// return subscribers;
// }
//
// This ensures that the object is always available when it's needed.
template<class T>
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<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 = smnew set<T*>;
return *m_pSubscribers;
}
set<T*> m_pSubscribers;
void Subscribe( T* p )
{
if( m_pSubscribers == NULL )
m_pSubscribers = smnew 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 );
}
};
+12 -13
View File
@@ -63,7 +63,12 @@ LoadedThemeData *g_pLoadedThemeData = NULL;
// For self-registering metrics
#include "SubscriptionManager.h"
static SubscriptionManager<IThemeMetric> g_Subscribers;
SubscriptionManager<IThemeMetric> & GetSubscribers()
{
static SubscriptionManager<IThemeMetric> subscribers;
return subscribers;
}
class LocalizedStringImplThemeMetric : public ILocalizedStringImpl, public ThemeMetric<RString>
{
@@ -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 )
+1
View File
@@ -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 );
+43 -16
View File
@@ -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<TimingSegment*> &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);
}
}
+7 -8
View File
@@ -3,14 +3,11 @@
#include "Foreach.h"
#include "RageLog.h"
map<istring, CreateDialogDriverFn> *RegisterDialogDriver::g_pRegistrees;
RegisterDialogDriver::RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn )
{
if( g_pRegistrees == NULL )
g_pRegistrees = smnew map<istring, CreateDialogDriverFn>;
ASSERT( g_pRegistrees->find(sName) == g_pRegistrees->end() );
(*g_pRegistrees)[sName] = pfn;
map<istring, CreateDialogDriverFn> & 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<istring, CreateDialogDriverFn> & registrees = RegisterDialogDriver::GetRegistrees();
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;
DialogDriver *pRet = (iter->second)();
+6 -1
View File
@@ -25,7 +25,12 @@ class DialogDriver_Null : public DialogDriver { };
typedef DialogDriver *(*CreateDialogDriverFn)();
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 );
};
#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." );
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 )
{
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() );
+7 -2
View File
@@ -23,7 +23,12 @@ class InputHandler: public RageDriver
{
public:
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) {}
virtual ~InputHandler() { }
@@ -69,7 +74,7 @@ private:
};
#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 )
+1 -3
View File
@@ -4,8 +4,6 @@
#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() );
@@ -15,7 +13,7 @@ void LightsDriver::Create( const RString &sDrivers, vector<LightsDriver *> &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() );
+7 -2
View File
@@ -10,7 +10,12 @@ class LightsDriver: public RageDriver
{
public:
static void Create( const RString &sDriver, vector<LightsDriver *> &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<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 )
#endif
+1 -3
View File
@@ -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 )
{
+6 -2
View File
@@ -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<RageMovieTextureDriver_##name, RageDriver> )
static RegisterRageDriver register_##name( &RageMovieTextureDriver::GetDriverList(), #name, CreateClass<RageMovieTextureDriver_##name, RageDriver> )
#endif
+5 -8
View File
@@ -3,20 +3,17 @@
void DriverList::Add( const istring &sName, CreateRageDriverFn pfn )
{
if( m_pRegistrees == NULL )
m_pRegistrees = smnew map<istring, CreateRageDriverFn>;
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<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)();
}
+1 -2
View File
@@ -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<istring, CreateRageDriverFn> *m_pRegistrees;
map<istring, CreateRageDriverFn> m_pRegistrees;
};
struct RegisterRageDriver
+1 -3
View File
@@ -5,8 +5,6 @@
#include "Foreach.h"
#include "arch/arch_default.h"
DriverList RageSoundDriver::m_pDriverList;
RageSoundDriver *RageSoundDriver::Create( const RString& sDrivers )
{
vector<RString> 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() );
+7 -2
View File
@@ -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<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 )
+6 -8
View File
@@ -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;
}