keep the whole LocalProfile in memory, not just the EditableData
This commit is contained in:
@@ -40,21 +40,21 @@ static Preference<CString> g_sMemoryCardProfileImportSubdirs( "MemoryCardProfile
|
|||||||
|
|
||||||
static CString LocalProfileIdToDir( const CString &sProfileID ) { return USER_PROFILES_DIR + sProfileID + "/"; }
|
static CString LocalProfileIdToDir( const CString &sProfileID ) { return USER_PROFILES_DIR + sProfileID + "/"; }
|
||||||
|
|
||||||
static map<CString,Profile> g_mapLocalProfileIdToEditableData;
|
static map<CString,Profile*> g_mapLocalProfileDirToProfile;
|
||||||
|
|
||||||
|
|
||||||
ProfileManager::ProfileManager()
|
ProfileManager::ProfileManager()
|
||||||
{
|
{
|
||||||
m_pMachineProfile = new Profile;
|
m_pMachineProfile = new Profile;
|
||||||
FOREACH_PlayerNumber(pn)
|
FOREACH_PlayerNumber(pn)
|
||||||
m_pProfile[pn] = new Profile;
|
m_pMemoryCardProfile[pn] = new Profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileManager::~ProfileManager()
|
ProfileManager::~ProfileManager()
|
||||||
{
|
{
|
||||||
SAFE_DELETE( m_pMachineProfile );
|
SAFE_DELETE( m_pMachineProfile );
|
||||||
FOREACH_PlayerNumber(pn)
|
FOREACH_PlayerNumber(pn)
|
||||||
SAFE_DELETE( m_pProfile[pn] );
|
SAFE_DELETE( m_pMemoryCardProfile[pn] );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileManager::Init()
|
void ProfileManager::Init()
|
||||||
@@ -68,7 +68,7 @@ void ProfileManager::Init()
|
|||||||
|
|
||||||
LoadMachineProfile();
|
LoadMachineProfile();
|
||||||
|
|
||||||
RefreshLocalProfilesEditableData();
|
RefreshLocalProfilesFromDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ProfileManager::LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsMemCard )
|
int ProfileManager::LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsMemCard )
|
||||||
@@ -84,7 +84,7 @@ int ProfileManager::LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsM
|
|||||||
m_bLastLoadWasFromLastGood[pn] = false;
|
m_bLastLoadWasFromLastGood[pn] = false;
|
||||||
|
|
||||||
// Try to load the original, non-backup data.
|
// Try to load the original, non-backup data.
|
||||||
Profile::LoadResult lr = m_pProfile[pn]->LoadAllFromDir( m_sProfileDir[pn], PREFSMAN->m_bSignProfileData );
|
Profile::LoadResult lr = GetProfile(pn)->LoadAllFromDir( m_sProfileDir[pn], PREFSMAN->m_bSignProfileData );
|
||||||
|
|
||||||
CString sBackupDir = m_sProfileDir[pn] + LAST_GOOD_DIR;
|
CString sBackupDir = m_sProfileDir[pn] + LAST_GOOD_DIR;
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ int ProfileManager::LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsM
|
|||||||
//
|
//
|
||||||
if( lr == Profile::failed_tampered )
|
if( lr == Profile::failed_tampered )
|
||||||
{
|
{
|
||||||
lr = m_pProfile[pn]->LoadAllFromDir( sBackupDir, PREFSMAN->m_bSignProfileData );
|
lr = GetProfile(pn)->LoadAllFromDir( sBackupDir, PREFSMAN->m_bSignProfileData );
|
||||||
m_bLastLoadWasFromLastGood[pn] = lr == Profile::success;
|
m_bLastLoadWasFromLastGood[pn] = lr == Profile::success;
|
||||||
|
|
||||||
/* If the LastGood profile doesn't exist at all, and the actual profile was failed_tampered,
|
/* If the LastGood profile doesn't exist at all, and the actual profile was failed_tampered,
|
||||||
@@ -257,7 +257,7 @@ bool ProfileManager::SaveProfile( PlayerNumber pn ) const
|
|||||||
if( m_sProfileDir[pn].empty() )
|
if( m_sProfileDir[pn].empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool b = m_pProfile[pn]->SaveAllToDir( m_sProfileDir[pn], PREFSMAN->m_bSignProfileData );
|
bool b = GetProfile(pn)->SaveAllToDir( m_sProfileDir[pn], PREFSMAN->m_bSignProfileData );
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@@ -269,7 +269,7 @@ void ProfileManager::UnloadProfile( PlayerNumber pn )
|
|||||||
m_bWasLoadedFromMemoryCard[pn] = false;
|
m_bWasLoadedFromMemoryCard[pn] = false;
|
||||||
m_bLastLoadWasTamperedOrCorrupt[pn] = false;
|
m_bLastLoadWasTamperedOrCorrupt[pn] = false;
|
||||||
m_bLastLoadWasFromLastGood[pn] = false;
|
m_bLastLoadWasFromLastGood[pn] = false;
|
||||||
m_pProfile[pn]->InitAll();
|
m_pMemoryCardProfile[pn]->InitAll();
|
||||||
SONGMAN->FreeAllLoadedFromProfile( (ProfileSlot) pn );
|
SONGMAN->FreeAllLoadedFromProfile( (ProfileSlot) pn );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,34 +277,41 @@ const Profile* ProfileManager::GetProfile( PlayerNumber pn ) const
|
|||||||
{
|
{
|
||||||
ASSERT( pn >= 0 && pn < NUM_PLAYERS );
|
ASSERT( pn >= 0 && pn < NUM_PLAYERS );
|
||||||
|
|
||||||
return m_pProfile[pn];
|
if( m_sProfileDir[pn].empty() || ProfileWasLoadedFromMemoryCard(pn) )
|
||||||
|
return m_pMemoryCardProfile[pn];
|
||||||
|
else
|
||||||
|
return g_mapLocalProfileDirToProfile[ m_sProfileDir[pn] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
CString ProfileManager::GetPlayerName( PlayerNumber pn ) const
|
CString ProfileManager::GetPlayerName( PlayerNumber pn ) const
|
||||||
{
|
{
|
||||||
const Profile *prof = GetProfile( pn );
|
const Profile *prof = GetProfile( pn );
|
||||||
return prof ? prof->GetDisplayNameOrHighScoreName() : CString("");
|
return prof ? prof->GetDisplayNameOrHighScoreName() : CString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ProfileManager::RefreshLocalProfilesEditableData()
|
void ProfileManager::RefreshLocalProfilesFromDisk()
|
||||||
{
|
{
|
||||||
g_mapLocalProfileIdToEditableData.clear();
|
FOREACHM( CString, Profile*, g_mapLocalProfileDirToProfile, iter )
|
||||||
|
SAFE_DELETE( iter->second );
|
||||||
|
g_mapLocalProfileDirToProfile.clear();
|
||||||
|
|
||||||
vector<CString> vsProfileID;
|
vector<CString> vsProfileID;
|
||||||
GetDirListing( USER_PROFILES_DIR "*", vsProfileID, true, false );
|
GetDirListing( USER_PROFILES_DIR "*", vsProfileID, true, false );
|
||||||
FOREACH_CONST( CString, vsProfileID, s )
|
FOREACH_CONST( CString, vsProfileID, s )
|
||||||
{
|
{
|
||||||
Profile &pro = g_mapLocalProfileIdToEditableData[*s];
|
Profile *&pProfile = g_mapLocalProfileDirToProfile[*s];
|
||||||
|
pProfile = new Profile;
|
||||||
CString sProfileDir = LocalProfileIdToDir( *s );
|
CString sProfileDir = LocalProfileIdToDir( *s );
|
||||||
LOG->Trace(" '%s'", pro.GetDisplayNameOrHighScoreName().c_str());
|
LOG->Trace(" '%s'", pProfile->GetDisplayNameOrHighScoreName().c_str());
|
||||||
pro.LoadEditableDataFromDir( sProfileDir );
|
pProfile->LoadAllFromDir( sProfileDir, PREFSMAN->m_bSignProfileData );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Profile &ProfileManager::GetLocalProfileEditableData( const CString &sProfileID )
|
Profile &ProfileManager::GetLocalProfile( const CString &sProfileID )
|
||||||
{
|
{
|
||||||
map<CString,Profile>::iterator iter = g_mapLocalProfileIdToEditableData.find( sProfileID );
|
map<CString,Profile*>::iterator iter = g_mapLocalProfileDirToProfile.find( sProfileID );
|
||||||
if( iter == g_mapLocalProfileIdToEditableData.end() )
|
if( iter == g_mapLocalProfileDirToProfile.end() )
|
||||||
{
|
{
|
||||||
LOG->Warn( "ProfileID '%s' doesn't exist", sProfileID.c_str() );
|
LOG->Warn( "ProfileID '%s' doesn't exist", sProfileID.c_str() );
|
||||||
static Profile s_pro;
|
static Profile s_pro;
|
||||||
@@ -312,7 +319,7 @@ Profile &ProfileManager::GetLocalProfileEditableData( const CString &sProfileID
|
|||||||
return s_pro;
|
return s_pro;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter->second;
|
return *iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProfileManager::CreateLocalProfile( CString sName )
|
bool ProfileManager::CreateLocalProfile( CString sName )
|
||||||
@@ -336,7 +343,7 @@ bool ProfileManager::CreateLocalProfile( CString sName )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool bResult = Profile::CreateNewProfile( sProfileDir, sName );
|
bool bResult = Profile::CreateNewProfile( sProfileDir, sName );
|
||||||
RefreshLocalProfilesEditableData();
|
RefreshLocalProfilesFromDisk();
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +361,7 @@ bool ProfileManager::RenameLocalProfile( CString sProfileID, CString sNewName )
|
|||||||
pro.m_sDisplayName = sNewName;
|
pro.m_sDisplayName = sNewName;
|
||||||
|
|
||||||
bool bResult = pro.SaveAllToDir( sProfileDir, PREFSMAN->m_bSignProfileData );
|
bool bResult = pro.SaveAllToDir( sProfileDir, PREFSMAN->m_bSignProfileData );
|
||||||
RefreshLocalProfilesEditableData();
|
RefreshLocalProfilesFromDisk();
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +393,7 @@ bool ProfileManager::DeleteLocalProfile( CString sProfileID )
|
|||||||
// remove profile dir
|
// remove profile dir
|
||||||
bool bResult = FILEMAN->Remove( sProfileDir );
|
bool bResult = FILEMAN->Remove( sProfileDir );
|
||||||
|
|
||||||
RefreshLocalProfilesEditableData();
|
RefreshLocalProfilesFromDisk();
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,17 +425,17 @@ void ProfileManager::LoadMachineProfile()
|
|||||||
|
|
||||||
bool ProfileManager::ProfileWasLoadedFromMemoryCard( PlayerNumber pn ) const
|
bool ProfileManager::ProfileWasLoadedFromMemoryCard( PlayerNumber pn ) const
|
||||||
{
|
{
|
||||||
return GetProfile(pn) && m_bWasLoadedFromMemoryCard[pn];
|
return !m_sProfileDir[pn].empty() && m_bWasLoadedFromMemoryCard[pn];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProfileManager::LastLoadWasTamperedOrCorrupt( PlayerNumber pn ) const
|
bool ProfileManager::LastLoadWasTamperedOrCorrupt( PlayerNumber pn ) const
|
||||||
{
|
{
|
||||||
return GetProfile(pn) && m_bLastLoadWasTamperedOrCorrupt[pn];
|
return !m_sProfileDir[pn].empty() && m_bLastLoadWasTamperedOrCorrupt[pn];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProfileManager::LastLoadWasFromLastGood( PlayerNumber pn ) const
|
bool ProfileManager::LastLoadWasFromLastGood( PlayerNumber pn ) const
|
||||||
{
|
{
|
||||||
return GetProfile(pn) && m_bLastLoadWasFromLastGood[pn];
|
return !m_sProfileDir[pn].empty() && m_bLastLoadWasFromLastGood[pn];
|
||||||
}
|
}
|
||||||
|
|
||||||
CString ProfileManager::GetProfileDir( ProfileSlot slot ) const
|
CString ProfileManager::GetProfileDir( ProfileSlot slot ) const
|
||||||
@@ -468,7 +475,7 @@ const Profile* ProfileManager::GetProfile( ProfileSlot slot ) const
|
|||||||
if( m_sProfileDir[slot].empty() )
|
if( m_sProfileDir[slot].empty() )
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
return m_pProfile[slot];
|
return GetProfile( (PlayerNumber)slot );
|
||||||
case PROFILE_SLOT_MACHINE:
|
case PROFILE_SLOT_MACHINE:
|
||||||
return m_pMachineProfile;
|
return m_pMachineProfile;
|
||||||
default:
|
default:
|
||||||
@@ -673,15 +680,40 @@ CString ProfileManager::GetNewLocalProfileDefaultName() const
|
|||||||
void ProfileManager::GetLocalProfileIDs( vector<CString> &vsProfileIDsOut ) const
|
void ProfileManager::GetLocalProfileIDs( vector<CString> &vsProfileIDsOut ) const
|
||||||
{
|
{
|
||||||
vsProfileIDsOut.clear();
|
vsProfileIDsOut.clear();
|
||||||
FOREACHM_CONST( CString, Profile, g_mapLocalProfileIdToEditableData, iter )
|
FOREACHM_CONST( CString, Profile*, g_mapLocalProfileDirToProfile, iter )
|
||||||
vsProfileIDsOut.push_back( iter->first );
|
vsProfileIDsOut.push_back( iter->first );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileManager::GetLocalProfileDisplayNames( vector<CString> &vsProfileDisplayNamesOut ) const
|
void ProfileManager::GetLocalProfileDisplayNames( vector<CString> &vsProfileDisplayNamesOut ) const
|
||||||
{
|
{
|
||||||
vsProfileDisplayNamesOut.clear();
|
vsProfileDisplayNamesOut.clear();
|
||||||
FOREACHM_CONST( CString, Profile, g_mapLocalProfileIdToEditableData, iter )
|
FOREACHM_CONST( CString, Profile*, g_mapLocalProfileDirToProfile, iter )
|
||||||
vsProfileDisplayNamesOut.push_back( iter->second.m_sDisplayName );
|
vsProfileDisplayNamesOut.push_back( iter->second->m_sDisplayName );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProfileManager::ValidateLocalProfileName( const CString &sAnswer, CString &sErrorOut )
|
||||||
|
{
|
||||||
|
CString sCurrentProfileOldName = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sLastSelectedProfileID ).m_sDisplayName;
|
||||||
|
vector<CString> vsProfileNames;
|
||||||
|
PROFILEMAN->GetLocalProfileDisplayNames( vsProfileNames );
|
||||||
|
bool bAlreadyAProfileWithThisName = find( vsProfileNames.begin(), vsProfileNames.end(), sAnswer ) != vsProfileNames.end();
|
||||||
|
|
||||||
|
if( sAnswer == "" )
|
||||||
|
{
|
||||||
|
sErrorOut = "Profile name cannot be blank.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if( sAnswer == sCurrentProfileOldName )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if( bAlreadyAProfileWithThisName )
|
||||||
|
{
|
||||||
|
sErrorOut = "There is already another profile with this name. Please choose a different name.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -697,7 +729,7 @@ public:
|
|||||||
static int GetProfile( T* p, lua_State *L ) { PlayerNumber pn = (PlayerNumber)IArg(1); Profile* pP = p->GetProfile(pn); ASSERT(pP); pP->PushSelf(L); return 1; }
|
static int GetProfile( T* p, lua_State *L ) { PlayerNumber pn = (PlayerNumber)IArg(1); Profile* pP = p->GetProfile(pn); ASSERT(pP); pP->PushSelf(L); return 1; }
|
||||||
static int GetMachineProfile( T* p, lua_State *L ) { p->GetMachineProfile()->PushSelf(L); return 1; }
|
static int GetMachineProfile( T* p, lua_State *L ) { p->GetMachineProfile()->PushSelf(L); return 1; }
|
||||||
static int SaveMachineProfile( T* p, lua_State *L ) { p->SaveMachineProfile(); return 1; }
|
static int SaveMachineProfile( T* p, lua_State *L ) { p->SaveMachineProfile(); return 1; }
|
||||||
static int GetLocalProfileEditableData( T* p, lua_State *L ) { Profile &pro = p->GetLocalProfileEditableData(SArg(1)); pro.PushSelf(L); return 1; }
|
static int GetLocalProfile( T* p, lua_State *L ) { Profile &pro = p->GetLocalProfile(SArg(1)); pro.PushSelf(L); return 1; }
|
||||||
|
|
||||||
static void Register(lua_State *L)
|
static void Register(lua_State *L)
|
||||||
{
|
{
|
||||||
@@ -705,7 +737,7 @@ public:
|
|||||||
ADD_METHOD( GetProfile )
|
ADD_METHOD( GetProfile )
|
||||||
ADD_METHOD( GetMachineProfile )
|
ADD_METHOD( GetMachineProfile )
|
||||||
ADD_METHOD( SaveMachineProfile )
|
ADD_METHOD( SaveMachineProfile )
|
||||||
ADD_METHOD( GetLocalProfileEditableData )
|
ADD_METHOD( GetLocalProfile )
|
||||||
Luna<T>::Register( L );
|
Luna<T>::Register( L );
|
||||||
|
|
||||||
// Add global singleton if constructed already. If it's not constructed yet,
|
// Add global singleton if constructed already. If it's not constructed yet,
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ public:
|
|||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// local profiles
|
// local profiles
|
||||||
void RefreshLocalProfilesEditableData();
|
void RefreshLocalProfilesFromDisk();
|
||||||
Profile &GetLocalProfileEditableData( const CString &sProfileID );
|
Profile &GetLocalProfile( const CString &sProfileID );
|
||||||
|
|
||||||
bool CreateLocalProfile( CString sName );
|
bool CreateLocalProfile( CString sName );
|
||||||
bool RenameLocalProfile( CString sProfileID, CString sNewName );
|
bool RenameLocalProfile( CString sProfileID, CString sNewName );
|
||||||
@@ -102,6 +102,10 @@ public:
|
|||||||
// Lua
|
// Lua
|
||||||
void PushSelf( lua_State *L );
|
void PushSelf( lua_State *L );
|
||||||
|
|
||||||
|
|
||||||
|
static bool ValidateLocalProfileName( const CString &sAnswer, CString &sErrorOut );
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// returns Profile::LoadResult, but we don't want to depend on Profile
|
// returns Profile::LoadResult, but we don't want to depend on Profile
|
||||||
int LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsMemCard );
|
int LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsMemCard );
|
||||||
@@ -118,9 +122,7 @@ private:
|
|||||||
bool m_bLastLoadWasTamperedOrCorrupt[NUM_PLAYERS]; // true if Stats.xml was present, but failed to load (probably because of a signature failure)
|
bool m_bLastLoadWasTamperedOrCorrupt[NUM_PLAYERS]; // true if Stats.xml was present, but failed to load (probably because of a signature failure)
|
||||||
bool m_bLastLoadWasFromLastGood[NUM_PLAYERS]; // if true, then m_bLastLoadWasTamperedOrCorrupt is also true
|
bool m_bLastLoadWasFromLastGood[NUM_PLAYERS]; // if true, then m_bLastLoadWasTamperedOrCorrupt is also true
|
||||||
|
|
||||||
// actual loaded profile data
|
Profile *m_pMemoryCardProfile[NUM_PLAYERS]; // holds Profile for the currently inserted card
|
||||||
Profile *m_pProfile[NUM_PLAYERS];
|
|
||||||
|
|
||||||
Profile *m_pMachineProfile;
|
Profile *m_pMachineProfile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user