Permalink
Browse files

Merge pull request #7058 from JosJuice/move-titledatabase-usage

Don't store custom names from TitleDatabase in GameFileCache
  • Loading branch information...
leoetlino committed Jun 4, 2018
2 parents 8074192 + 85e94cc commit 8e0ea92ec35a0473e79ef012b9f98b7a38d3ef33
@@ -19,6 +19,8 @@
namespace Core
{
static const std::string EMPTY_STRING;
static std::string GetLanguageCode(DiscIO::Language language)
{
switch (language)
@@ -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),
@@ -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());
@@ -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;
@@ -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)
{
@@ -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())
@@ -10,6 +10,8 @@
#include <QAbstractTableModel>
#include <QString>
#include "Core/TitleDatabase.h"
#include "DolphinQt2/GameList/GameTracker.h"
#include "UICommon/GameFile.h"
@@ -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;
};
@@ -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();
}
@@ -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)
@@ -14,7 +14,6 @@
#include "Common/Event.h"
#include "Common/WorkQueueThread.h"
#include "Core/TitleDatabase.h"
#include "UICommon/GameFile.h"
#include "UICommon/GameFileCache.h"
@@ -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;
@@ -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)
@@ -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;
@@ -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));
}
}
}
@@ -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)
{
@@ -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 &&
@@ -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;
{
@@ -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));
@@ -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)
@@ -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();
@@ -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;
@@ -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);
@@ -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
@@ -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;
@@ -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;
@@ -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); }
@@ -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,
@@ -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{};
};
Oops, something went wrong.

0 comments on commit 8e0ea92

Please sign in to comment.