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:
Devin J. Pohly
2013-04-27 00:05:14 -04:00
parent ef9c5294a0
commit feb919f0bf
33 changed files with 182 additions and 266 deletions
+9 -15
View File
@@ -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
View File
@@ -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 );
-6
View File
@@ -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 )
-2
View File
@@ -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 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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 );
-5
View File
@@ -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") );
-1
View File
@@ -15,7 +15,6 @@ class MenuTimer : public ActorFrame
{
public:
MenuTimer();
virtual ~MenuTimer();
void Load( RString sMetricsGroup );
virtual void Update( float fDeltaTime );
+8 -12
View File
@@ -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 -17
View File
@@ -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
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 lock( "ThreadSlots" );
return lock;
static RageMutex *pLock = new RageMutex( "ThreadSlots" );
return *pLock;
}
static int FindEmptyThreadSlot()
+10 -17
View File
@@ -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
View File
@@ -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
View File
@@ -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;
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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 )
-1
View File
@@ -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
View File
@@ -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];
}
}
+8 -7
View File
@@ -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)();
+1 -6
View File
@@ -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 ) \
+3 -1
View File
@@ -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() );
+2 -7
View File
@@ -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 )
+3 -1
View File
@@ -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() );
+2 -7
View File
@@ -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
+3 -1
View File
@@ -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 )
{
+2 -6
View File
@@ -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
+8 -5
View File
@@ -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)();
}
+2 -1
View File
@@ -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
+3 -1
View File
@@ -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() );
+2 -7
View File
@@ -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 )
+8 -6
View File
@@ -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;
}