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:
+15
-9
@@ -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
@@ -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 );
|
||||
|
||||
@@ -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
@@ -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
@@ -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 );
|
||||
|
||||
@@ -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") );
|
||||
|
||||
@@ -15,6 +15,7 @@ class MenuTimer : public ActorFrame
|
||||
{
|
||||
public:
|
||||
MenuTimer();
|
||||
virtual ~MenuTimer();
|
||||
void Load( RString sMetricsGroup );
|
||||
|
||||
virtual void Update( float fDeltaTime );
|
||||
|
||||
+12
-8
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 )
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)();
|
||||
|
||||
@@ -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 ) \
|
||||
|
||||
@@ -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() );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
|
||||
@@ -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() );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user