Remove RageUtil_CachedObject

I don't notice any performance drawback in gameplay, but it was
massively slowing down ScreenReloadSongs.
This commit is contained in:
Martin Natano
2022-06-10 19:33:23 +02:00
parent 62f8ed5c5c
commit 49127f6a92
17 changed files with 19 additions and 338 deletions
-2
View File
@@ -3,7 +3,6 @@
list(APPEND SMDATA_RAGE_UTILS_SRC
"RageUtil.cpp"
"RageUtil_BackgroundLoader.cpp"
"RageUtil_CachedObject.cpp"
"RageUtil_CharConversions.cpp"
"RageUtil_FileDB.cpp"
"RageUtil_WorkerThread.cpp")
@@ -13,7 +12,6 @@ list(APPEND SMDATA_RAGE_UTILS_HPP
"RageUtil_AutoPtr.h" # TODO: Remove the need for this and replace
# with c++11 smart pointers
"RageUtil_BackgroundLoader.h"
"RageUtil_CachedObject.h"
"RageUtil_CharConversions.h"
"RageUtil_CircularBuffer.h"
"RageUtil_FileDB.h"
+1 -1
View File
@@ -94,7 +94,7 @@ Course::Course(): m_bIsAutogen(false), m_sPath(""), m_sMainTitle(""),
m_bIncomplete(false), m_vEntries(), m_SortOrder_TotalDifficulty(0),
m_SortOrder_Ranking(0), m_LoadedFromProfile(ProfileSlot_Invalid),
m_TrailCache(), m_iTrailCacheSeed(0), m_RadarCache(),
m_setStyles(), m_CachedObject()
m_setStyles()
{
FOREACH_ENUM( Difficulty,dc)
m_iCustomMeter[dc] = -1;
-3
View File
@@ -6,7 +6,6 @@
#include "EnumHelper.h"
#include "Trail.h"
#include "RageTypes.h"
#include "RageUtil_CachedObject.h"
#include "SongUtil.h"
#include "StepsUtil.h"
#include <map>
@@ -204,8 +203,6 @@ public:
// Preferred styles:
set<RString> m_setStyles;
CachedObject<Course> m_CachedObject;
};
#endif
+1 -12
View File
@@ -537,17 +537,11 @@ void CourseID::FromCourse( const Course *p )
// Strip off leading "/". 2005/05/21 file layer changes added a leading slash.
if( sPath.Left(1) == "/" )
sPath.erase( sPath.begin() );
m_Cache.Unset();
}
Course *CourseID::ToCourse() const
{
Course *pCourse = nullptr;
if(m_Cache.Get(&pCourse))
{
return pCourse;
}
if(!sPath.empty())
{
// HACK for backwards compatibility:
@@ -558,17 +552,13 @@ Course *CourseID::ToCourse() const
slash_path = "/" + slash_path;
}
if(pCourse == nullptr)
{
pCourse = SONGMAN->GetCourseFromPath(slash_path);
}
pCourse = SONGMAN->GetCourseFromPath(slash_path);
}
if( pCourse == nullptr && !sFullTitle.empty() )
{
pCourse = SONGMAN->GetCourseFromName( sFullTitle );
}
m_Cache.Set( pCourse );
return pCourse;
}
@@ -592,7 +582,6 @@ void CourseID::LoadFromNode( const XNode* pNode )
sPath = RString();
if( !pNode->GetAttrValue("Path", sPath) )
pNode->GetAttrValue( "FullTitle", sFullTitle );
m_Cache.Unset();
// HACK for backwards compatibility: /AdditionalCourses has been merged into /Courses
if (sPath.Left(18) == "AdditionalCourses/")
+1 -3
View File
@@ -3,7 +3,6 @@
#include "GameConstantsAndTypes.h"
#include "Difficulty.h"
#include "RageUtil_CachedObject.h"
class Course;
class Profile;
@@ -72,7 +71,7 @@ namespace EditCourseUtil
class CourseID
{
public:
CourseID(): sPath(""), sFullTitle(""), m_Cache() { Unset(); }
CourseID(): sPath(""), sFullTitle("") { Unset(); }
void Unset() { FromCourse(nullptr); }
void FromCourse( const Course *p );
Course *ToCourse() const;
@@ -92,7 +91,6 @@ public:
private:
RString sPath;
RString sFullTitle;
mutable CachedObjectPointer<Course> m_Cache;
};
#endif
-72
View File
@@ -1,72 +0,0 @@
#include "global.h"
#include "RageUtil_CachedObject.h"
#include "RageThreads.h"
#if 0
/* Example use: */
struct Object
{
CachedObject<Object> m_CachedObject;
Object() { }
};
struct User
{
CachedObjectPointer<Object> cache;
Object *foobar()
{
Object *p;
if( !cache.Get(&p) )
{
p = nullptr;
cache.Set(p);
}
return p;
}
};
void test()
{
Object p;
User gar;
gar.foobar();
}
#endif
static RageMutex m_Mutex("CachedObjects");
void CachedObjectHelpers::Lock()
{
m_Mutex.Lock();
}
void CachedObjectHelpers::Unlock()
{
m_Mutex.Unlock();
}
/*
* (c) 2007 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-193
View File
@@ -1,193 +0,0 @@
#ifndef RAGE_UTIL_CACHED_OBJECT_H
#define RAGE_UTIL_CACHED_OBJECT_H
#include <set>
template<typename T>
class CachedObjectPointer;
/** @brief Utilities for working with the
<a class="el" href="class_cachedobject.html">CachedObjects</a>. */
namespace CachedObjectHelpers
{
void Lock();
void Unlock();
}
/** @brief Cached object pointers with automatic invalidation. */
template<typename T>
class CachedObject
{
public:
CachedObject(): m_pObject(nullptr)
{
/* A new object is being constructed, so invalidate negative caching. */
ClearCacheNegative();
}
CachedObject( const CachedObject &cpy ): m_pObject(nullptr)
{
ClearCacheNegative();
}
~CachedObject()
{
if( m_pObject != nullptr )
ClearCacheSpecific( m_pObject );
}
CachedObject &operator=( const CachedObject &rhs ) { return *this; }
/* Clear all cached entries for this type. */
static void ClearCacheAll()
{
CachedObjectHelpers::Lock();
for( typename set<ObjectPointer *>::iterator p = m_spObjectPointers.begin(); p != m_spObjectPointers.end(); ++p )
{
(*p)->m_pCache = nullptr;
(*p)->m_bCacheIsSet = false;
}
CachedObjectHelpers::Unlock();
}
/* Clear all cached entries pointing to a specific object. */
static void ClearCacheSpecific( const T *pObject )
{
CachedObjectHelpers::Lock();
for( typename set<ObjectPointer *>::iterator p = m_spObjectPointers.begin(); p != m_spObjectPointers.end(); ++p )
{
if( (*p)->m_pCache == pObject )
{
(*p)->m_pCache = nullptr;
(*p)->m_bCacheIsSet = false;
}
}
CachedObjectHelpers::Unlock();
}
/* Clear all negative cached entries of this type. */
static void ClearCacheNegative()
{
CachedObjectHelpers::Lock();
for( typename set<ObjectPointer *>::iterator p = m_spObjectPointers.begin(); p != m_spObjectPointers.end(); ++p )
{
if( (*p)->m_pCache == nullptr )
(*p)->m_bCacheIsSet = false;
}
CachedObjectHelpers::Unlock();
}
private:
typedef CachedObjectPointer<T> ObjectPointer;
friend class CachedObjectPointer<T>;
static void Register( ObjectPointer *p )
{
m_spObjectPointers.insert( p );
}
static void Unregister( ObjectPointer *p )
{
typename set<ObjectPointer *>::iterator it = m_spObjectPointers.find( p );
ASSERT( it != m_spObjectPointers.end() );
m_spObjectPointers.erase( it );
}
/* This points to the actual T this object is contained in. This is set
* the first time CachedObjectPointer::Set() is called for this object.
* That's more convenient than setting it ourselves; we don't need to
* do anything special in T's copy ctor. This works because there's no
* need to clear cache for an object before any CachedObjectPointers have
* ever been set for it. */
const T *m_pObject;
static set<ObjectPointer *> m_spObjectPointers;
};
template<typename T> set<CachedObjectPointer<T> *> CachedObject<T>::m_spObjectPointers = set<CachedObjectPointer<T> *>();
template<typename T>
class CachedObjectPointer
{
public:
typedef CachedObject<T> Object;
CachedObjectPointer() : m_pCache(nullptr), m_bCacheIsSet(false)
{
Object::Register( this );
}
CachedObjectPointer( const CachedObjectPointer &cpy ):
m_pCache(cpy.m_pCache), m_bCacheIsSet(cpy.m_bCacheIsSet)
{
CachedObjectHelpers::Lock();
Object::Register( this );
CachedObjectHelpers::Unlock();
}
~CachedObjectPointer()
{
Object::Unregister( this );
}
bool Get( T **pRet ) const
{
CachedObjectHelpers::Lock();
if( !m_bCacheIsSet )
{
CachedObjectHelpers::Unlock();
return false;
}
*pRet = m_pCache;
CachedObjectHelpers::Unlock();
return true;
}
void Set( T *p )
{
CachedObjectHelpers::Lock();
m_pCache = p;
m_bCacheIsSet = true;
if( p != nullptr )
p->m_CachedObject.m_pObject = p;
CachedObjectHelpers::Unlock();
}
void Unset()
{
CachedObjectHelpers::Lock();
m_pCache = nullptr;
m_bCacheIsSet = false;
CachedObjectHelpers::Unlock();
}
private:
friend class CachedObject<T>;
T *m_pCache;
bool m_bCacheIsSet;
};
#endif
/*
* (c) 2007 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-3
View File
@@ -6,7 +6,6 @@
#include "Difficulty.h"
#include "EnumHelper.h"
#include "RageUtil_AutoPtr.h"
#include "RageUtil_CachedObject.h"
#include "RageTypes.h"
#include "Steps.h"
#include <set>
@@ -457,8 +456,6 @@ public:
* means "this note doesn't have a keysound". */
vector<RString> m_vsKeysoundFile;
CachedObject<Song> m_CachedObject;
RString GetAttackString() const
{
return join(":", this->m_sAttackString);
+2 -2
View File
@@ -75,9 +75,9 @@ SongManager::SongManager()
}
NUM_SONG_GROUP_COLORS .Load( "SongManager", "NumSongGroupColors" );
SONG_GROUP_COLOR .Load( "SongManager", SONG_GROUP_COLOR_NAME, NUM_SONG_GROUP_COLORS );
SONG_GROUP_COLOR .Load( "SongManager", SONG_GROUP_COLOR_NAME, NUM_SONG_GROUP_COLORS );
NUM_COURSE_GROUP_COLORS .Load( "SongManager", "NumCourseGroupColors" );
COURSE_GROUP_COLOR .Load( "SongManager", COURSE_GROUP_COLOR_NAME, NUM_COURSE_GROUP_COLORS );
COURSE_GROUP_COLOR .Load( "SongManager", COURSE_GROUP_COLOR_NAME, NUM_COURSE_GROUP_COLORS );
num_profile_song_group_colors.Load("SongManager", "NumProfileSongGroupColors");
profile_song_group_colors.Load("SongManager", profile_song_group_color_name, num_profile_song_group_colors);
}
+7 -14
View File
@@ -1110,27 +1110,21 @@ void SongID::FromSong( const Song *p )
// Strip off leading "/". 2005/05/21 file layer changes added a leading slash.
if( sDir.Left(1) == "/" )
sDir.erase( sDir.begin() );
m_Cache.Unset();
}
Song *SongID::ToSong() const
{
Song *pRet = nullptr;
if( !m_Cache.Get(&pRet) )
if(!sDir.empty())
{
if(!sDir.empty())
// HACK for backwards compatibility: Re-add the leading "/".
// 2005/05/21 file layer changes added a leading slash.
RString sDir2 = sDir;
if(sDir2.Left(1) != "/")
{
// HACK for backwards compatibility: Re-add the leading "/".
// 2005/05/21 file layer changes added a leading slash.
RString sDir2 = sDir;
if(sDir2.Left(1) != "/")
{
sDir2 = "/" + sDir2;
}
pRet = SONGMAN->GetSongFromDir(sDir2);
sDir2 = "/" + sDir2;
}
m_Cache.Set( pRet );
pRet = SONGMAN->GetSongFromDir(sDir2);
}
return pRet;
}
@@ -1146,7 +1140,6 @@ void SongID::LoadFromNode( const XNode* pNode )
{
ASSERT( pNode->GetName() == "Song" );
pNode->GetAttrValue("Dir", sDir);
m_Cache.Unset();
// HACK for backwards compatibility: /AdditionalSongs has been merged into /Songs
if (sDir.Left(16) == "AdditionalSongs/")
+1 -3
View File
@@ -5,7 +5,6 @@
#include "GameConstantsAndTypes.h"
#include "Difficulty.h"
#include "RageUtil_CachedObject.h"
#include <set>
class Song;
@@ -195,14 +194,13 @@ namespace SongUtil
class SongID
{
RString sDir;
mutable CachedObjectPointer<Song> m_Cache;
public:
/**
* @brief Set up the SongID with default values.
*
* This used to call Unset() to do the same thing. */
SongID(): sDir(""), m_Cache() { m_Cache.Unset(); }
SongID(): sDir("") {}
void Unset() { FromSong(nullptr); }
void FromSong( const Song *p );
Song *ToSong() const;
+1 -4
View File
@@ -8,7 +8,6 @@
#include "RadarValues.h"
#include "Difficulty.h"
#include "RageUtil_AutoPtr.h"
#include "RageUtil_CachedObject.h"
#include "TimingData.h"
class Profile;
@@ -112,7 +111,7 @@ public:
vector<RString> m_sAttackString;
RString GetChartName() const { return parent ? Real()->GetChartName() : this->chartName; }
void SetChartName(const RString name) { this->chartName = name; }
void SetChartName(const RString name) { this->chartName = name; }
void SetFilename( RString fn ) { m_sFilename = fn; }
RString GetFilename() const { return m_sFilename; }
void SetSavedToDisk( bool b ) { DeAutogen(); m_bSavedToDisk = b; }
@@ -196,8 +195,6 @@ public:
/** @brief The Song these Steps are associated with */
Song *m_pSong;
CachedObject<Steps> m_CachedObject;
void SetDisplayBPM(const DisplayBPM type) { this->displayBPMType = type; }
DisplayBPM GetDisplayBPM() const { return this->displayBPMType; }
void SetMinBPM(const float f) { this->specifiedBPMMin = f; }
-6
View File
@@ -262,8 +262,6 @@ void StepsID::FromSteps( const Steps *p )
uHash = 0;
}
}
m_Cache.Unset();
}
/* XXX: Don't allow duplicate edit descriptions, and don't allow edit descriptions
@@ -295,8 +293,6 @@ Steps *StepsID::ToSteps( const Song *p, bool bAllowNull ) const
if( !bAllowNull && pRet == nullptr )
FAIL_M( ssprintf("%i, %i, \"%s\"", st, dc, sDescription.c_str()) );
m_Cache.Set( pRet );
return pRet;
}
@@ -338,8 +334,6 @@ void StepsID::LoadFromNode( const XNode* pNode )
sDescription = "";
uHash = 0;
}
m_Cache.Unset();
}
RString StepsID::ToString() const
+1 -3
View File
@@ -3,7 +3,6 @@
#include "GameConstantsAndTypes.h"
#include "Difficulty.h"
#include "RageUtil_CachedObject.h"
class Steps;
class Song;
@@ -167,7 +166,6 @@ class StepsID
Difficulty dc;
RString sDescription;
unsigned uHash;
mutable CachedObjectPointer<Steps> m_Cache;
public:
/**
@@ -176,7 +174,7 @@ public:
* This used to call Unset(), which set the variables to
* the same thing. */
StepsID(): st(StepsType_Invalid), dc(Difficulty_Invalid),
sDescription(""), uHash(0), m_Cache() {}
sDescription(""), uHash(0) {}
void Unset() { FromSteps(nullptr); }
void FromSteps( const Steps *p );
Steps *ToSteps( const Song *p, bool bAllowNull ) const;
+1 -5
View File
@@ -4,7 +4,6 @@
#include "Attack.h"
#include "RadarValues.h"
#include "Difficulty.h"
#include "RageUtil_CachedObject.h"
class Song;
class Steps;
@@ -73,8 +72,7 @@ public:
m_CourseType(CourseType_Invalid),
m_CourseDifficulty(Difficulty_Invalid),
m_vEntries(), m_iSpecifiedMeter(-1),
m_bRadarValuesCached(false), m_CachedRadarValues(),
m_CachedObject() {}
m_bRadarValuesCached(false), m_CachedRadarValues() {}
void Init()
{
m_StepsType = StepsType_Invalid;
@@ -93,8 +91,6 @@ public:
bool IsSecret() const;
bool ContainsSong( const Song *pSong ) const;
CachedObject<Trail> m_CachedObject;
// Lua
void PushSelf( lua_State *L );
};
+2 -8
View File
@@ -32,7 +32,6 @@ void TrailID::FromTrail( const Trail *p )
st = p->m_StepsType;
cd = p->m_CourseDifficulty;
}
m_Cache.Unset();
}
Trail *TrailID::ToTrail( const Course *p, bool bAllowNull ) const
@@ -40,12 +39,8 @@ Trail *TrailID::ToTrail( const Course *p, bool bAllowNull ) const
ASSERT( p != nullptr );
Trail *pRet = nullptr;
if( !m_Cache.Get(&pRet) )
{
if( st != StepsType_Invalid && cd != Difficulty_Invalid )
pRet = p->GetTrail( st, cd );
m_Cache.Set( pRet );
}
if( st != StepsType_Invalid && cd != Difficulty_Invalid )
pRet = p->GetTrail( st, cd );
if( !bAllowNull && pRet == nullptr )
RageException::Throw( "%i, %i, \"%s\"", st, cd, p->GetDisplayFullTitle().c_str() );
@@ -74,7 +69,6 @@ void TrailID::LoadFromNode( const XNode* pNode )
pNode->GetAttrValue( "CourseDifficulty", sTemp );
cd = StringToDifficulty( sTemp );
m_Cache.Unset();
}
RString TrailID::ToString() const
+1 -4
View File
@@ -3,7 +3,6 @@
#include "GameConstantsAndTypes.h"
#include "Difficulty.h"
#include "RageUtil_CachedObject.h"
class Song;
class Trail;
@@ -30,11 +29,9 @@ class TrailID
{
StepsType st;
CourseDifficulty cd;
mutable CachedObjectPointer<Trail> m_Cache;
public:
TrailID(): st(StepsType_Invalid), cd(Difficulty_Invalid),
m_Cache() { m_Cache.Unset(); }
TrailID(): st(StepsType_Invalid), cd(Difficulty_Invalid) {}
void Unset() { FromTrail(nullptr); }
void FromTrail( const Trail *p );
Trail *ToTrail( const Course *p, bool bAllowNull ) const;