Skip to content

Commit

Permalink
Don't store custom names from TitleDatabase in GameFileCache
Browse files Browse the repository at this point in the history
This saves us from having to update the GameFileCache when the
TitleDatabase changes (for instance when the user changes language).
  • Loading branch information
JosJuice committed Jun 4, 2018
1 parent 0f7370a commit 85e94cc
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 94 deletions.
10 changes: 6 additions & 4 deletions Source/Core/Core/TitleDatabase.cpp
Expand Up @@ -19,6 +19,8 @@

namespace Core
{
static const std::string EMPTY_STRING;

static std::string GetLanguageCode(DiscIO::Language language)
{
switch (language)
Expand Down Expand Up @@ -157,16 +159,16 @@ TitleDatabase::TitleDatabase()

TitleDatabase::~TitleDatabase() = default;

std::string TitleDatabase::GetTitleName(const std::string& game_id, TitleType type) const
const std::string& TitleDatabase::GetTitleName(const std::string& game_id, TitleType type) const
{
const auto& map = IsWiiTitle(game_id) ? m_wii_title_map : m_gc_title_map;
const std::string key =
type == TitleType::Channel && game_id.length() == 6 ? game_id.substr(0, 4) : game_id;
const auto iterator = map.find(key);
return iterator != map.end() ? iterator->second : "";
return iterator != map.end() ? iterator->second : EMPTY_STRING;
}

std::string TitleDatabase::GetChannelName(u64 title_id) const
const std::string& TitleDatabase::GetChannelName(u64 title_id) const
{
const std::string id{
{static_cast<char>((title_id >> 24) & 0xff), static_cast<char>((title_id >> 16) & 0xff),
Expand All @@ -176,7 +178,7 @@ std::string TitleDatabase::GetChannelName(u64 title_id) const

std::string TitleDatabase::Describe(const std::string& game_id, TitleType type) const
{
const std::string title_name = GetTitleName(game_id, type);
const std::string& title_name = GetTitleName(game_id, type);
if (title_name.empty())
return game_id;
return StringFromFormat("%s (%s)", title_name.c_str(), game_id.c_str());
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/TitleDatabase.h
Expand Up @@ -26,10 +26,10 @@ class TitleDatabase final

// Get a user friendly title name for a game ID.
// This falls back to returning an empty string if none could be found.
std::string GetTitleName(const std::string& game_id, TitleType = TitleType::Other) const;
const std::string& GetTitleName(const std::string& game_id, TitleType = TitleType::Other) const;

// Same as above, but takes a title ID instead of a game ID, and can only find names of channels.
std::string GetChannelName(u64 title_id) const;
const std::string& GetChannelName(u64 title_id) const;

// Get a description for a game ID (title name if available + game ID).
std::string Describe(const std::string& game_id, TitleType = TitleType::Other) const;
Expand Down
6 changes: 4 additions & 2 deletions Source/Core/DolphinQt2/GameList/GameListModel.cpp
Expand Up @@ -80,7 +80,7 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
case COL_TITLE:
if (role == Qt::DisplayRole || role == Qt::InitialSortOrderRole)
{
QString name = QString::fromStdString(game.GetName());
QString name = QString::fromStdString(game.GetName(m_title_database));
const int disc_nr = game.GetDiscNumber() + 1;
if (disc_nr > 1)
{
Expand Down Expand Up @@ -161,8 +161,10 @@ bool GameListModel::ShouldDisplayGameListItem(int index) const
const UICommon::GameFile& game = *m_games[index];

if (!m_term.isEmpty() &&
!QString::fromStdString(game.GetName()).contains(m_term, Qt::CaseInsensitive))
!QString::fromStdString(game.GetName(m_title_database)).contains(m_term, Qt::CaseInsensitive))
{
return false;
}

const bool show_platform = [&game] {
switch (game.GetPlatform())
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/DolphinQt2/GameList/GameListModel.h
Expand Up @@ -10,6 +10,8 @@
#include <QAbstractTableModel>
#include <QString>

#include "Core/TitleDatabase.h"

#include "DolphinQt2/GameList/GameTracker.h"

#include "UICommon/GameFile.h"
Expand Down Expand Up @@ -63,5 +65,6 @@ class GameListModel final : public QAbstractTableModel

GameTracker m_tracker;
QList<std::shared_ptr<const UICommon::GameFile>> m_games;
Core::TitleDatabase m_title_database;
QString m_term;
};
4 changes: 2 additions & 2 deletions Source/Core/DolphinQt2/GameList/GameTracker.cpp
Expand Up @@ -105,7 +105,7 @@ void GameTracker::StartInternal()
m_initial_games_emitted_event.Wait();

bool cache_updated = m_cache.Update(paths, emit_game_loaded, emit_game_removed);
cache_updated |= m_cache.UpdateAdditionalMetadata(m_title_database, emit_game_updated);
cache_updated |= m_cache.UpdateAdditionalMetadata(emit_game_updated);
if (cache_updated)
m_cache.Save();
}
Expand Down Expand Up @@ -256,7 +256,7 @@ void GameTracker::LoadGame(const QString& path)
if (!DiscIO::ShouldHideFromGameList(converted_path))
{
bool cache_changed = false;
auto game = m_cache.AddOrGet(converted_path, &cache_changed, m_title_database);
auto game = m_cache.AddOrGet(converted_path, &cache_changed);
if (game)
emit GameLoaded(std::move(game));
if (cache_changed)
Expand Down
2 changes: 0 additions & 2 deletions Source/Core/DolphinQt2/GameList/GameTracker.h
Expand Up @@ -14,7 +14,6 @@

#include "Common/Event.h"
#include "Common/WorkQueueThread.h"
#include "Core/TitleDatabase.h"
#include "UICommon/GameFile.h"
#include "UICommon/GameFileCache.h"

Expand Down Expand Up @@ -75,7 +74,6 @@ class GameTracker final : public QFileSystemWatcher
QMap<QString, QSet<QString>> m_tracked_files;
Common::WorkQueueThread<Command> m_load_thread;
UICommon::GameFileCache m_cache;
Core::TitleDatabase m_title_database;
Common::Event m_cache_loaded_event;
Common::Event m_initial_games_emitted_event;
bool m_initial_games_emitted = false;
Expand Down
67 changes: 37 additions & 30 deletions Source/Core/DolphinWX/GameListCtrl.cpp
Expand Up @@ -82,9 +82,18 @@ struct CompressionProgress final

static bool sorted = false;

static int CompareGameListItems(const UICommon::GameFile* iso1, const UICommon::GameFile* iso2,
long sortData = GameListCtrl::COLUMN_TITLE)
static int CompareGameListItems(size_t item1, size_t item2, long sortData,
const GameListCtrl* caller)
{
// return 1 if item1 > item2
// return -1 if item1 < item2
// return 0 for identity
const UICommon::GameFile* iso1 = caller->GetISO(item1);
const UICommon::GameFile* iso2 = caller->GetISO(item2);

if (iso1 == iso2)
return 0;

int t = 1;

if (sortData < 0)
Expand Down Expand Up @@ -136,7 +145,8 @@ static int CompareGameListItems(const UICommon::GameFile* iso1, const UICommon::
if (sortData != GameListCtrl::COLUMN_TITLE)
t = 1;

int name_cmp = strcasecmp(iso1->GetName().c_str(), iso2->GetName().c_str()) * t;
int name_cmp =
strcasecmp(caller->GetShownName(item1).c_str(), caller->GetShownName(item2).c_str()) * t;
if (name_cmp != 0)
return name_cmp;

Expand Down Expand Up @@ -383,28 +393,34 @@ void GameListCtrl::RefreshList()
if (Core::GetState() != Core::State::Uninitialized)
return;

// Use a newly loaded title database (it might have gotten updated)
const Core::TitleDatabase title_database;

m_shown_names.clear();
m_shown_files.clear();
{
std::unique_lock<std::mutex> lk(m_cache_mutex);
m_cache.ForEach([this](const std::shared_ptr<const UICommon::GameFile>& game_file) {
if (ShouldDisplayGameListItem(*game_file))
m_shown_files.push_back(game_file);
});
m_cache.ForEach(
[this, &title_database](const std::shared_ptr<const UICommon::GameFile>& game_file) {
if (ShouldDisplayGameListItem(*game_file))
{
m_shown_names.push_back(game_file->GetName(title_database));
m_shown_files.push_back(game_file);
}
});
}

// Drives are not cached. Not sure if this is required, but better to err on the
// side of caution if cross-platform issues could come into play.
if (SConfig::GetInstance().m_ListDrives)
{
std::unique_lock<std::mutex> lk(m_title_database_mutex);
for (const auto& drive : Common::GetCDDevices())
{
auto file = std::make_shared<UICommon::GameFile>(drive);
if (file->IsValid())
{
if (file->CustomNameChanged(m_title_database))
file->CustomNameCommit();
m_shown_files.push_back(file);
m_shown_names.push_back(file->GetName(title_database));
m_shown_files.push_back(std::move(file));
}
}
}
Expand Down Expand Up @@ -501,7 +517,8 @@ void GameListCtrl::RefreshList()
// Update the column content of the item at index
void GameListCtrl::UpdateItemAtColumn(long index, int column)
{
const auto& iso_file = *GetISO(GetItemData(index));
const size_t item_data = GetItemData(index);
const auto& iso_file = *GetISO(item_data);

switch (column)
{
Expand All @@ -527,7 +544,7 @@ void GameListCtrl::UpdateItemAtColumn(long index, int column)
}
case COLUMN_TITLE:
{
wxString name = StrToWxStr(iso_file.GetName());
wxString name = StrToWxStr(GetShownName(item_data));
int disc_number = iso_file.GetDiscNumber() + 1;

if (disc_number > 1 &&
Expand Down Expand Up @@ -628,12 +645,6 @@ void GameListCtrl::RescanList()
const std::vector<std::string> game_paths = UICommon::FindAllGamePaths(
SConfig::GetInstance().m_ISOFolder, SConfig::GetInstance().m_RecursiveISOFolder);

// Reload the TitleDatabase
{
std::unique_lock<std::mutex> lock(m_title_database_mutex);
m_title_database = {};
}

bool cache_changed = false;

{
Expand All @@ -647,7 +658,7 @@ void GameListCtrl::RescanList()

{
std::unique_lock<std::mutex> lk(m_cache_mutex);
if (m_cache.UpdateAdditionalMetadata(m_title_database))
if (m_cache.UpdateAdditionalMetadata())
{
cache_changed = true;
QueueEvent(new wxCommandEvent(DOLPHIN_EVT_REFRESH_GAMELIST));
Expand Down Expand Up @@ -701,19 +712,15 @@ const UICommon::GameFile* GameListCtrl::GetISO(size_t index) const
return nullptr;
}

const std::string& GameListCtrl::GetShownName(size_t index) const
{
return m_shown_names[index];
}

static GameListCtrl* caller;
static int wxCALLBACK wxListCompare(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
{
// return 1 if item1 > item2
// return -1 if item1 < item2
// return 0 for identity
const UICommon::GameFile* iso1 = caller->GetISO(item1);
const UICommon::GameFile* iso2 = caller->GetISO(item2);

if (iso1 == iso2)
return 0;

return CompareGameListItems(iso1, iso2, sortData);
return CompareGameListItems(item1, item2, sortData, caller);
}

void GameListCtrl::OnColumnClick(wxListEvent& event)
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/DolphinWX/GameListCtrl.h
Expand Up @@ -35,6 +35,7 @@ class GameListCtrl : public wxListCtrl

void BrowseForDirectory();
const UICommon::GameFile* GetISO(size_t index) const;
const std::string& GetShownName(size_t index) const;
const UICommon::GameFile* GetSelectedISO() const;

static bool IsHidingItems();
Expand Down Expand Up @@ -111,13 +112,12 @@ class GameListCtrl : public wxListCtrl
UICommon::GameFileCache m_cache;
// Locks the cache object, not the shared_ptr<GameFile>s obtained from it
std::mutex m_cache_mutex;
Core::TitleDatabase m_title_database;
std::mutex m_title_database_mutex;
std::thread m_scan_thread;
Common::Event m_scan_trigger;
Common::Flag m_scan_exiting;
// UI thread's view into the cache
std::vector<std::shared_ptr<const UICommon::GameFile>> m_shown_files;
std::vector<std::string> m_shown_names;

int m_last_column;
int m_last_sort;
Expand Down
31 changes: 10 additions & 21 deletions Source/Core/UICommon/GameFile.cpp
Expand Up @@ -141,20 +141,6 @@ bool GameFile::IsValid() const
return true;
}

bool GameFile::CustomNameChanged(const Core::TitleDatabase& title_database)
{
const auto type = m_platform == DiscIO::Platform::WiiWAD ?
Core::TitleDatabase::TitleType::Channel :
Core::TitleDatabase::TitleType::Other;
m_pending.custom_name = title_database.GetTitleName(m_game_id, type);
return m_custom_name != m_pending.custom_name;
}

void GameFile::CustomNameCommit()
{
m_custom_name = std::move(m_pending.custom_name);
}

void GameBanner::DoState(PointerWrap& p)
{
p.Do(buffer);
Expand Down Expand Up @@ -191,7 +177,6 @@ void GameFile::DoState(PointerWrap& p)

m_volume_banner.DoState(p);
m_custom_banner.DoState(p);
p.Do(m_custom_name);
}

bool GameFile::IsElfOrDol() const
Expand Down Expand Up @@ -280,11 +265,17 @@ void GameFile::CustomBannerCommit()
m_custom_banner = std::move(m_pending.custom_banner);
}

const std::string& GameFile::GetName(bool long_name) const
const std::string& GameFile::GetName(const Core::TitleDatabase& title_database) const
{
if (!m_custom_name.empty())
return m_custom_name;
const auto type = m_platform == DiscIO::Platform::WiiWAD ?
Core::TitleDatabase::TitleType::Channel :
Core::TitleDatabase::TitleType::Other;
const std::string& custom_name = title_database.GetTitleName(m_game_id, type);
return custom_name.empty() ? GetName() : custom_name;
}

const std::string& GameFile::GetName(bool long_name) const
{
const std::string& name = long_name ? GetLongName() : GetShortName();
if (!name.empty())
return name;
Expand Down Expand Up @@ -323,9 +314,7 @@ std::string GameFile::GetUniqueIdentifier() const
if (GetRevision() != 0)
info.push_back("Revision " + std::to_string(GetRevision()));

std::string name(GetLongName(lang));
if (name.empty())
name = GetName();
const std::string& name = GetName();

int disc_number = GetDiscNumber() + 1;

Expand Down
6 changes: 1 addition & 5 deletions Source/Core/UICommon/GameFile.h
Expand Up @@ -44,6 +44,7 @@ class GameFile final
bool IsValid() const;
const std::string& GetFilePath() const { return m_file_path; }
const std::string& GetFileName() const { return m_file_name; }
const std::string& GetName(const Core::TitleDatabase& title_database) const;
const std::string& GetName(bool long_name = true) const;
const std::string& GetMaker(bool long_maker = true) const;
const std::string& GetShortName(DiscIO::Language l) const { return Lookup(l, m_short_names); }
Expand Down Expand Up @@ -79,8 +80,6 @@ class GameFile final
void WiiBannerCommit();
bool CustomBannerChanged();
void CustomBannerCommit();
bool CustomNameChanged(const Core::TitleDatabase& title_database);
void CustomNameCommit();

private:
static const std::string& Lookup(DiscIO::Language language,
Expand Down Expand Up @@ -121,16 +120,13 @@ class GameFile final

GameBanner m_volume_banner{};
GameBanner m_custom_banner{};
// Overridden name from TitleDatabase
std::string m_custom_name{};

// The following data members allow GameFileCache to construct updated versions
// of GameFiles in a threadsafe way. They should not be handled in DoState.
struct
{
GameBanner volume_banner;
GameBanner custom_banner;
std::string custom_name;
} m_pending{};
};

Expand Down

0 comments on commit 85e94cc

Please sign in to comment.