save memory by loading SMData from cache on demand
This commit is contained in:
+11
-7
@@ -262,6 +262,17 @@ bool Song::LoadFromSongDir( CString sDir )
|
|||||||
SaveToCacheFile();
|
SaveToCacheFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for( unsigned i=0; i<m_vpSteps.size(); i++ )
|
||||||
|
{
|
||||||
|
m_vpSteps[i]->SetFile( GetCacheFilePath() );
|
||||||
|
|
||||||
|
/* Compress all Steps. During initial caching, this will remove cached NoteData;
|
||||||
|
* during cached loads, this will just remove cached SMData. */
|
||||||
|
m_vpSteps[i]->Compress();
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the cached banners, if it's not loaded already. */
|
/* Load the cached banners, if it's not loaded already. */
|
||||||
if( m_bHasBanner )
|
if( m_bHasBanner )
|
||||||
BANNERCACHE->LoadBanner( GetBannerPath() );
|
BANNERCACHE->LoadBanner( GetBannerPath() );
|
||||||
@@ -814,13 +825,6 @@ void Song::TidyUpData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Compress all Steps
|
|
||||||
for( i=0; i<m_vpSteps.size(); i++ )
|
|
||||||
{
|
|
||||||
m_vpSteps[i]->Compress();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Song::TranslateTitles()
|
void Song::TranslateTitles()
|
||||||
|
|||||||
+63
-4
@@ -1,5 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* This stores a single note pattern for a song.
|
||||||
|
*
|
||||||
|
* We can have too much data to keep everything decompressed as NoteData, so most
|
||||||
|
* songs are kept in memory compressed as SMData until requested. NoteData is normally
|
||||||
|
* not requested casually during gameplay; we can move through screens, the music
|
||||||
|
* wheel, etc. without touching any NoteData.
|
||||||
|
*
|
||||||
|
* To save more memory, if data is cached on disk, read it from disk on demand. Not
|
||||||
|
* all Steps will have an associated file for this purpose. (Profile edits don't do
|
||||||
|
* this yet.)
|
||||||
|
*
|
||||||
|
* Data can be on disk (always compressed), compressed in memory, and uncompressed in
|
||||||
|
* memory.
|
||||||
|
*/
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "Steps.h"
|
#include "Steps.h"
|
||||||
|
#include "StepsUtil.h"
|
||||||
#include "song.h"
|
#include "song.h"
|
||||||
#include "Steps.h"
|
#include "Steps.h"
|
||||||
#include "IniFile.h"
|
#include "IniFile.h"
|
||||||
@@ -13,6 +29,7 @@
|
|||||||
#include "NoteDataUtil.h"
|
#include "NoteDataUtil.h"
|
||||||
#include "ProfileManager.h"
|
#include "ProfileManager.h"
|
||||||
#include "PrefsManager.h"
|
#include "PrefsManager.h"
|
||||||
|
#include "NotesLoaderSM.h"
|
||||||
|
|
||||||
Steps::Steps()
|
Steps::Steps()
|
||||||
{
|
{
|
||||||
@@ -143,10 +160,9 @@ void Steps::TidyUpData()
|
|||||||
void Steps::Decompress() const
|
void Steps::Decompress() const
|
||||||
{
|
{
|
||||||
if(notes)
|
if(notes)
|
||||||
{
|
|
||||||
return; // already decompressed
|
return; // already decompressed
|
||||||
}
|
|
||||||
else if(parent)
|
if(parent)
|
||||||
{
|
{
|
||||||
// get autogen notes
|
// get autogen notes
|
||||||
NoteData pdata;
|
NoteData pdata;
|
||||||
@@ -164,8 +180,36 @@ void Steps::Decompress() const
|
|||||||
|
|
||||||
NoteDataUtil::FixImpossibleRows( *notes, m_StepsType );
|
NoteDataUtil::FixImpossibleRows( *notes, m_StepsType );
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if(!notes_comp)
|
|
||||||
|
if( !m_sFilename.empty() && notes_comp == NULL )
|
||||||
|
{
|
||||||
|
/* We have data on disk and not in memory. Load it. */
|
||||||
|
Song s;
|
||||||
|
SMLoader ld;
|
||||||
|
if( !ld.LoadFromSMFile( m_sFilename, s, true ) )
|
||||||
|
{
|
||||||
|
LOG->Warn( "Couldn't load \"%s\"", m_sFilename.c_str() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the steps. */
|
||||||
|
StepsID ID;
|
||||||
|
ID.FromSteps( this );
|
||||||
|
|
||||||
|
Steps *pSteps = ID.ToSteps( &s, true );
|
||||||
|
if( pSteps == NULL )
|
||||||
|
{
|
||||||
|
LOG->Warn( "Couldn't find %s in \"%s\"", ID.ToString().c_str(), m_sFilename.c_str() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
notes_comp = new CompressedNoteData;
|
||||||
|
pSteps->GetSMNoteData( notes_comp->notes, notes_comp->attacks );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( notes_comp == NULL )
|
||||||
{
|
{
|
||||||
/* there is no data, do nothing */
|
/* there is no data, do nothing */
|
||||||
}
|
}
|
||||||
@@ -181,6 +225,16 @@ void Steps::Decompress() const
|
|||||||
|
|
||||||
void Steps::Compress() const
|
void Steps::Compress() const
|
||||||
{
|
{
|
||||||
|
if( !m_sFilename.empty() )
|
||||||
|
{
|
||||||
|
/* We have a file on disk; clear all data in memory. */
|
||||||
|
delete notes;
|
||||||
|
notes = NULL;
|
||||||
|
delete notes_comp;
|
||||||
|
notes_comp = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(!notes_comp)
|
if(!notes_comp)
|
||||||
{
|
{
|
||||||
if(!notes) return; /* no data is no data */
|
if(!notes) return; /* no data is no data */
|
||||||
@@ -251,6 +305,11 @@ bool Steps::IsAutogen() const
|
|||||||
return parent != NULL;
|
return parent != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Steps::SetFile( CString fn )
|
||||||
|
{
|
||||||
|
m_sFilename = fn;
|
||||||
|
}
|
||||||
|
|
||||||
void Steps::SetDescription(CString desc)
|
void Steps::SetDescription(CString desc)
|
||||||
{
|
{
|
||||||
DeAutogen();
|
DeAutogen();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
int GetMeter() const { return Real()->m_iMeter; }
|
int GetMeter() const { return Real()->m_iMeter; }
|
||||||
const RadarValues& GetRadarValues() const { return Real()->m_RadarValues; }
|
const RadarValues& GetRadarValues() const { return Real()->m_RadarValues; }
|
||||||
|
|
||||||
|
void SetFile( CString fn );
|
||||||
void SetDescription(CString desc);
|
void SetDescription(CString desc);
|
||||||
void SetDifficulty(Difficulty d);
|
void SetDifficulty(Difficulty d);
|
||||||
void SetLoadedFromProfile( ProfileSlot slot ) { m_LoadedFromProfile = slot; }
|
void SetLoadedFromProfile( ProfileSlot slot ) { m_LoadedFromProfile = slot; }
|
||||||
@@ -70,6 +71,8 @@ protected:
|
|||||||
|
|
||||||
const Steps *Real() const;
|
const Steps *Real() const;
|
||||||
|
|
||||||
|
CString m_sFilename;
|
||||||
|
|
||||||
/* These values are pulled from the autogen source first, if there is one. */
|
/* These values are pulled from the autogen source first, if there is one. */
|
||||||
ProfileSlot m_LoadedFromProfile; // PROFILE_SLOT_INVALID if wasn't loaded from a profile
|
ProfileSlot m_LoadedFromProfile; // PROFILE_SLOT_INVALID if wasn't loaded from a profile
|
||||||
unsigned m_uHash; // only used if m_Difficulty == DIFFICULTY_EDIT
|
unsigned m_uHash; // only used if m_Difficulty == DIFFICULTY_EDIT
|
||||||
|
|||||||
Reference in New Issue
Block a user