From 8160b28e8c8b7b94c99d3aeebbe36033717968a4 Mon Sep 17 00:00:00 2001 From: Jamiras Date: Tue, 14 Jul 2026 13:15:06 -0600 Subject: [PATCH 1/3] move TriggerValidation to data/util --- src/devkit/RADevKit.vcxproj | 4 ++-- src/devkit/RADevKit.vcxproj.filters | 12 +++++------ src/devkit/data/models/AchievementModel.cpp | 4 ++-- src/devkit/data/models/LeaderboardModel.cpp | 8 +++---- src/devkit/data/models/TriggerValidation.hh | 21 ------------------- .../{models => util}/TriggerValidation.cpp | 8 +++---- src/devkit/data/util/TriggerValidation.hh | 21 +++++++++++++++++++ .../viewmodels/MemoryBookmarksViewModel.cpp | 1 - .../viewmodels/MemoryWatchListViewModel.cpp | 1 - src/ui/viewmodels/MemoryWatchViewModel.cpp | 1 - .../viewmodels/TriggerConditionViewModel.cpp | 1 - src/ui/viewmodels/TriggerViewModel.cpp | 2 -- tests/devkit/RADevKit.Tests.vcxproj | 2 +- tests/devkit/RADevKit.Tests.vcxproj.filters | 6 +++--- .../TriggerValidation_Tests.cpp | 10 ++++----- 15 files changed, 48 insertions(+), 54 deletions(-) delete mode 100644 src/devkit/data/models/TriggerValidation.hh rename src/devkit/data/{models => util}/TriggerValidation.cpp (98%) create mode 100644 src/devkit/data/util/TriggerValidation.hh rename tests/devkit/data/{models => util}/TriggerValidation_Tests.cpp (98%) diff --git a/src/devkit/RADevKit.vcxproj b/src/devkit/RADevKit.vcxproj index aaea74aa9..0cc079922 100644 --- a/src/devkit/RADevKit.vcxproj +++ b/src/devkit/RADevKit.vcxproj @@ -75,8 +75,8 @@ - + @@ -110,9 +110,9 @@ - + diff --git a/src/devkit/RADevKit.vcxproj.filters b/src/devkit/RADevKit.vcxproj.filters index 6b02e5c63..0629c30a3 100644 --- a/src/devkit/RADevKit.vcxproj.filters +++ b/src/devkit/RADevKit.vcxproj.filters @@ -183,9 +183,6 @@ data\models - - data\models - ui @@ -207,6 +204,9 @@ data\util + + data\util + @@ -275,9 +275,6 @@ data\models - - data\models - ui @@ -293,5 +290,8 @@ data\util + + data\util + \ No newline at end of file diff --git a/src/devkit/data/models/AchievementModel.cpp b/src/devkit/data/models/AchievementModel.cpp index 4a81d89c9..9d7754ca7 100644 --- a/src/devkit/data/models/AchievementModel.cpp +++ b/src/devkit/data/models/AchievementModel.cpp @@ -8,7 +8,7 @@ #include "util/Log.hh" #include "data/models/LocalBadgesModel.hh" -#include "data/models/TriggerValidation.hh" +#include "data/util/TriggerValidation.hh" #include "services/ServiceLocator.hh" @@ -169,7 +169,7 @@ bool AchievementModel::ValidateAsset(std::wstring& sError) return false; } - return TriggerValidation::Validate(sTrigger, sError, AssetType::Achievement); + return ra::data::util::TriggerValidation::TriggerValidation::Validate(sTrigger, sError, AssetType::Achievement); } void AchievementModel::DoFrame() diff --git a/src/devkit/data/models/LeaderboardModel.cpp b/src/devkit/data/models/LeaderboardModel.cpp index 2229fd25d..4b822b52a 100644 --- a/src/devkit/data/models/LeaderboardModel.cpp +++ b/src/devkit/data/models/LeaderboardModel.cpp @@ -2,7 +2,7 @@ #include "context/IRcClient.hh" -#include "data/models/TriggerValidation.hh" +#include "data/util/TriggerValidation.hh" #include "services/ServiceLocator.hh" @@ -133,19 +133,19 @@ bool LeaderboardModel::ValidateAsset(std::wstring& sError) return false; } - if (!TriggerValidation::Validate(sStartTrigger, sError, AssetType::Leaderboard)) + if (!ra::data::util::TriggerValidation::Validate(sStartTrigger, sError, AssetType::Leaderboard)) { sError.insert(0, L"Start: "); return false; } - if (!TriggerValidation::Validate(sCancelTrigger, sError, AssetType::Leaderboard)) + if (!ra::data::util::TriggerValidation::Validate(sCancelTrigger, sError, AssetType::Leaderboard)) { sError.insert(0, L"Cancel: "); return false; } - if (!TriggerValidation::Validate(sSubmitTrigger, sError, AssetType::Leaderboard)) + if (!ra::data::util::TriggerValidation::Validate(sSubmitTrigger, sError, AssetType::Leaderboard)) { sError.insert(0, L"Submit: "); return false; diff --git a/src/devkit/data/models/TriggerValidation.hh b/src/devkit/data/models/TriggerValidation.hh deleted file mode 100644 index 12d9a5488..000000000 --- a/src/devkit/data/models/TriggerValidation.hh +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef RA_DATA_MODELS_TRIGGERVALIDATION_H -#define RA_DATA_MODELS_TRIGGERVALIDATION_H -#pragma once - -#include "data\models\AssetModelBase.hh" - -namespace ra { -namespace data { -namespace models { - -class TriggerValidation -{ -public: - static bool Validate(const std::string& sTrigger, std::wstring& sError, AssetType nType); -}; - -} // namespace models -} // namespace data -} // namespace ra - -#endif RA_DATA_MODELS_TRIGGERVALIDATION_H diff --git a/src/devkit/data/models/TriggerValidation.cpp b/src/devkit/data/util/TriggerValidation.cpp similarity index 98% rename from src/devkit/data/models/TriggerValidation.cpp rename to src/devkit/data/util/TriggerValidation.cpp index 786caabeb..961e722bc 100644 --- a/src/devkit/data/models/TriggerValidation.cpp +++ b/src/devkit/data/util/TriggerValidation.cpp @@ -15,7 +15,7 @@ namespace ra { namespace data { -namespace models { +namespace util { static bool ValidateLeaderboardCondSet(const rc_condset_t* pCondSet, std::wstring& sError) { @@ -195,7 +195,7 @@ static bool ValidateMemoryNotes(const rc_trigger_t* pTrigger, std::wstring& sErr return true; } -bool TriggerValidation::Validate(const std::string& sTrigger, std::wstring& sError, AssetType nType) +bool TriggerValidation::Validate(const std::string& sTrigger, std::wstring& sError, ra::data::models::AssetType nType) { rc_preparse_state_t preparse; rc_init_preparse_state(&preparse); @@ -254,7 +254,7 @@ bool TriggerValidation::Validate(const std::string& sTrigger, std::wstring& sErr if (nResult) { - if (nType == AssetType::Leaderboard) + if (nType == ra::data::models::AssetType::Leaderboard) { if (!ValidateLeaderboardTrigger(&trigger->trigger, sError)) return false; @@ -273,6 +273,6 @@ bool TriggerValidation::Validate(const std::string& sTrigger, std::wstring& sErr } } -} // namespace models +} // namespace util } // namespace data } // namespace ra diff --git a/src/devkit/data/util/TriggerValidation.hh b/src/devkit/data/util/TriggerValidation.hh new file mode 100644 index 000000000..4e12f4bfd --- /dev/null +++ b/src/devkit/data/util/TriggerValidation.hh @@ -0,0 +1,21 @@ +#ifndef RA_DATA_UTIL_TRIGGERVALIDATION_H +#define RA_DATA_UTIL_TRIGGERVALIDATION_H +#pragma once + +#include "data/models/AssetModelBase.hh" + +namespace ra { +namespace data { +namespace util { + +class TriggerValidation +{ +public: + static bool Validate(const std::string& sTrigger, std::wstring& sError, ra::data::models::AssetType nType); +}; + +} // namespace util +} // namespace data +} // namespace ra + +#endif RA_DATA_UTIL_TRIGGERVALIDATION_H diff --git a/src/ui/viewmodels/MemoryBookmarksViewModel.cpp b/src/ui/viewmodels/MemoryBookmarksViewModel.cpp index c1846a59d..0c9ad8141 100644 --- a/src/ui/viewmodels/MemoryBookmarksViewModel.cpp +++ b/src/ui/viewmodels/MemoryBookmarksViewModel.cpp @@ -7,7 +7,6 @@ #include "context\IEmulatorMemoryContext.hh" #include "data\Types.hh" -#include "data\models\TriggerValidation.hh" #include "services\AchievementLogicSerializer.hh" #include "services\FrameEventQueue.hh" diff --git a/src/ui/viewmodels/MemoryWatchListViewModel.cpp b/src/ui/viewmodels/MemoryWatchListViewModel.cpp index 589e66a74..c7566bd19 100644 --- a/src/ui/viewmodels/MemoryWatchListViewModel.cpp +++ b/src/ui/viewmodels/MemoryWatchListViewModel.cpp @@ -6,7 +6,6 @@ #include "data\Types.hh" #include "data\context\EmulatorContext.hh" -#include "data\models\TriggerValidation.hh" #include "services\AchievementLogicSerializer.hh" #include "services\FrameEventQueue.hh" diff --git a/src/ui/viewmodels/MemoryWatchViewModel.cpp b/src/ui/viewmodels/MemoryWatchViewModel.cpp index 54aaf0126..4e5e50611 100644 --- a/src/ui/viewmodels/MemoryWatchViewModel.cpp +++ b/src/ui/viewmodels/MemoryWatchViewModel.cpp @@ -9,7 +9,6 @@ #include "data\Types.hh" #include "data\context\EmulatorContext.hh" -#include "data\models\TriggerValidation.hh" #include "services\AchievementRuntime.hh" #include "services\IConfiguration.hh" diff --git a/src/ui/viewmodels/TriggerConditionViewModel.cpp b/src/ui/viewmodels/TriggerConditionViewModel.cpp index b1a290c3a..aef90beaa 100644 --- a/src/ui/viewmodels/TriggerConditionViewModel.cpp +++ b/src/ui/viewmodels/TriggerConditionViewModel.cpp @@ -4,7 +4,6 @@ #include "util\Strings.hh" #include "data\context\GameContext.hh" -#include "data\models\TriggerValidation.hh" #include "data\util\IndirectNoteResolver.hh" #include "services\AchievementLogicSerializer.hh" diff --git a/src/ui/viewmodels/TriggerViewModel.cpp b/src/ui/viewmodels/TriggerViewModel.cpp index ae4327a15..c6547e6da 100644 --- a/src/ui/viewmodels/TriggerViewModel.cpp +++ b/src/ui/viewmodels/TriggerViewModel.cpp @@ -10,8 +10,6 @@ #include "util\Strings.hh" -#include "data\models\TriggerValidation.hh" - #include "services\AchievementLogicSerializer.hh" #include "services\AchievementRuntime.hh" #include "services\IClipboard.hh" diff --git a/tests/devkit/RADevKit.Tests.vcxproj b/tests/devkit/RADevKit.Tests.vcxproj index 19ab5e24b..1241a8fe4 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj +++ b/tests/devkit/RADevKit.Tests.vcxproj @@ -75,8 +75,8 @@ - + diff --git a/tests/devkit/RADevKit.Tests.vcxproj.filters b/tests/devkit/RADevKit.Tests.vcxproj.filters index 72fcd5d88..4c116381d 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj.filters +++ b/tests/devkit/RADevKit.Tests.vcxproj.filters @@ -64,9 +64,6 @@ data\models - - data\models - data\models @@ -79,6 +76,9 @@ data\util + + data\util + diff --git a/tests/devkit/data/models/TriggerValidation_Tests.cpp b/tests/devkit/data/util/TriggerValidation_Tests.cpp similarity index 98% rename from tests/devkit/data/models/TriggerValidation_Tests.cpp rename to tests/devkit/data/util/TriggerValidation_Tests.cpp index b84654259..070f96329 100644 --- a/tests/devkit/data/models/TriggerValidation_Tests.cpp +++ b/tests/devkit/data/util/TriggerValidation_Tests.cpp @@ -1,5 +1,5 @@ -#include "data/models/TriggerValidation.hh" +#include "data/util/TriggerValidation.hh" #include "tests/devkit/context/mocks/MockConsoleContext.hh" #include "tests/devkit/context/mocks/MockEmulatorMemoryContext.hh" @@ -10,7 +10,7 @@ namespace ra { namespace data { -namespace models { +namespace util { namespace tests { TEST_CLASS(TriggerValidation_Tests) @@ -19,7 +19,7 @@ TEST_CLASS(TriggerValidation_Tests) void AssertValidation(const std::string& sTrigger, const std::wstring& sExpectedError) { std::wstring sError; - const bool bResult = TriggerValidation::Validate(sTrigger, sError, AssetType::Achievement); + const bool bResult = TriggerValidation::Validate(sTrigger, sError, ra::data::models::AssetType::Achievement); Assert::AreEqual(sExpectedError, sError); Assert::AreEqual(bResult, sExpectedError.empty()); } @@ -27,7 +27,7 @@ TEST_CLASS(TriggerValidation_Tests) void AssertLeaderboardValidation(const std::string& sTrigger, const std::wstring& sExpectedError) { std::wstring sError; - const bool bResult = TriggerValidation::Validate(sTrigger, sError, AssetType::Leaderboard); + const bool bResult = TriggerValidation::Validate(sTrigger, sError, ra::data::models::AssetType::Leaderboard); Assert::AreEqual(sExpectedError, sError); Assert::AreEqual(bResult, sExpectedError.empty()); } @@ -239,6 +239,6 @@ TEST_CLASS(TriggerValidation_Tests) }; } // namespace tests -} // namespace models +} // namespace util } // namespace data } // namespace ra From 14e89464b6033aa536c04f94778ef7429ad7b4c6 Mon Sep 17 00:00:00 2001 From: Jamiras Date: Tue, 14 Jul 2026 17:03:48 -0600 Subject: [PATCH 2/3] move GameAssets to devkit --- src/RA_Integration.vcxproj | 2 - src/RA_Integration.vcxproj.filters | 6 - src/data/context/GameContext.cpp | 68 ++----- src/data/context/GameContext.hh | 64 +------ src/devkit/RADevKit.vcxproj | 7 + src/devkit/RADevKit.vcxproj.filters | 21 +++ src/devkit/context/IDevKitContext.hh | 29 +++ src/devkit/context/IGameContext.hh | 20 ++ src/devkit/context/impl/DevKitContext.cpp | 16 ++ src/devkit/context/impl/DevKitContext.hh | 34 ++++ src/devkit/data/models/AchievementModel.cpp | 11 +- .../data/models/AchievementSetModel.cpp | 29 +++ src/devkit/data/models/AchievementSetModel.hh | 105 +++++++++++ src/devkit/data/models/AssetModelBase.hh | 2 +- .../data/models}/GameAssets.cpp | 90 ++++++--- .../data/models}/GameAssets.hh | 85 ++++++--- src/devkit/data/models/LeaderboardModel.cpp | 2 +- src/services/AchievementRuntime.cpp | 22 +-- src/services/AchievementRuntimeExports.cpp | 2 +- src/services/Initialization.cpp | 4 + src/ui/viewmodels/AssetEditorViewModel.cpp | 2 +- src/ui/viewmodels/AssetEditorViewModel.hh | 2 +- src/ui/viewmodels/AssetListViewModel.cpp | 32 ++-- src/ui/viewmodels/AssetListViewModel.hh | 4 +- src/ui/viewmodels/AssetUploadViewModel.cpp | 10 +- .../BrokenAchievementsViewModel.cpp | 4 +- .../OverlayAchievementsPageViewModel.cpp | 4 +- .../OverlayLeaderboardsPageViewModel.cpp | 2 +- src/ui/viewmodels/TriggerViewModel.cpp | 4 +- src/ui/win32/AssetListDialog.cpp | 4 +- tests/RA_Integration.Tests.vcxproj | 2 - tests/RA_Integration.Tests.vcxproj.filters | 6 - tests/data/DataAsserts.hh | 56 ------ tests/data/context/GameContext_Tests.cpp | 174 +++++++++--------- tests/devkit/RADevKit.Tests.vcxproj | 4 + tests/devkit/RADevKit.Tests.vcxproj.filters | 12 ++ .../devkit/context/mocks/MockDevKitContext.hh | 34 ++++ tests/devkit/context/mocks/MockGameContext.hh | 1 + .../data/models/AchievementModel_Tests.cpp | 2 +- .../data/models/AssetModelBase_Tests.cpp | 30 +-- .../data/models}/GameAssets_Tests.cpp | 64 +++---- .../data/models/LeaderboardModel_Tests.cpp | 10 +- .../data/models/LocalBadgesModel_Tests.cpp | 2 +- .../data/models/MemoryNotesModel_Tests.cpp | 2 +- .../data/models/MemoryRegionsModel_Tests.cpp | 2 +- .../data/models/RichPresenceModel_Tests.cpp | 2 +- tests/devkit/services/mocks/MockLogger.hh | 2 +- .../devkit/testutil/AchievementSetAsserts.hh | 44 +++++ tests/devkit/testutil/LeaderboardAsserts.hh | 46 +++++ tests/mocks/MockAchievementRuntime.cpp | 6 +- tests/mocks/MockGameContext.hh | 17 +- tests/services/AchievementRuntime_Tests.cpp | 20 +- .../viewmodels/AssetEditorViewModel_Tests.cpp | 70 +++---- .../viewmodels/AssetListViewModel_Tests.cpp | 17 +- .../viewmodels/AssetUploadViewModel_Tests.cpp | 8 +- .../viewmodels/MemoryNotesViewModel_Tests.cpp | 4 + .../MemoryRegionsViewModel_Tests.cpp | 4 + ...OverlayAchievementsPageViewModel_Tests.cpp | 2 +- .../PointerInspectorViewModel_Tests.cpp | 4 + 59 files changed, 832 insertions(+), 502 deletions(-) create mode 100644 src/devkit/context/IDevKitContext.hh create mode 100644 src/devkit/context/impl/DevKitContext.cpp create mode 100644 src/devkit/context/impl/DevKitContext.hh create mode 100644 src/devkit/data/models/AchievementSetModel.cpp create mode 100644 src/devkit/data/models/AchievementSetModel.hh rename src/{data/context => devkit/data/models}/GameAssets.cpp (88%) rename src/{data/context => devkit/data/models}/GameAssets.hh (70%) create mode 100644 tests/devkit/context/mocks/MockDevKitContext.hh rename tests/{data/context => devkit/data/models}/GameAssets_Tests.cpp (94%) create mode 100644 tests/devkit/testutil/AchievementSetAsserts.hh create mode 100644 tests/devkit/testutil/LeaderboardAsserts.hh diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj index c40ec6363..988ef2470 100644 --- a/src/RA_Integration.vcxproj +++ b/src/RA_Integration.vcxproj @@ -72,7 +72,6 @@ - @@ -206,7 +205,6 @@ - diff --git a/src/RA_Integration.vcxproj.filters b/src/RA_Integration.vcxproj.filters index d17670b83..c55fa2bee 100644 --- a/src/RA_Integration.vcxproj.filters +++ b/src/RA_Integration.vcxproj.filters @@ -312,9 +312,6 @@ Data\Context - - Data\Context - UI\ViewModels @@ -791,9 +788,6 @@ Data\Context - - Data\Context - UI\ViewModels diff --git a/src/data/context/GameContext.cpp b/src/data/context/GameContext.cpp index 1facde644..b7050f69c 100644 --- a/src/data/context/GameContext.cpp +++ b/src/data/context/GameContext.cpp @@ -116,7 +116,7 @@ bool GameContext::BeginLoadGame(unsigned int nGameId, Mode nMode, bool& bWasPaus // reset the GameContext m_nMode = nMode; m_sGameTitle.clear(); - m_vSubsets.clear(); + m_vAssets.ClearAchievementSets(); m_vAssets.ResetLocalId(); m_vAssets.BeginUpdate(); @@ -293,7 +293,7 @@ void GameContext::EndLoadGame(int nResult, bool bWasPaused, bool bShowSoftcoreWa // activate rich presence (or remove if not defined) if (pRichPresence && nResult == RC_OK) { - pRichPresence->SetSubsetID(m_vSubsets.front().AchievementSetID()); + pRichPresence->SetSubsetID(Assets().AchievementSets().GetItemAt(0)->GetID()); // if the server value differs from the local value, the model will appear as Unpublished if (pRichPresence->GetChanges() != ra::data::models::AssetChanges::None) @@ -501,11 +501,6 @@ void GameContext::InitializeFromAchievementRuntime(const std::map lock(m_mLoadMutex); - m_vSubsets.clear(); - // GameID dictates which game is loaded for purposes of local achievement storage and memory notes m_nGameId = GetRealGameId(game_data_response->id); // ActiveGameID dictates which game is running for purposes of rich presence and pings @@ -516,46 +511,11 @@ void GameContext::InitializeSubsets(const rc_api_fetch_game_sets_response_t* gam ra::services::ServiceLocator::GetMutable().BeginSession(nActiveGameId); } - for (uint32_t i = 0; i < game_data_response->num_sets; ++i) - { - const auto* pSet = &game_data_response->sets[i]; - if (pSet->type == RC_ACHIEVEMENT_SET_TYPE_CORE) - { - // core subset should always be first - m_vSubsets.insert(m_vSubsets.begin(), - Subset(pSet->id, GetRealGameId(pSet->game_id), - ra::util::String::Widen(pSet->title), SubsetType::Core)); - } - else - { - SubsetType nType = SubsetType::Bonus; - switch (pSet->type) - { - case RC_ACHIEVEMENT_SET_TYPE_EXCLUSIVE: - nType = SubsetType::Exclusive; - break; - case RC_ACHIEVEMENT_SET_TYPE_SPECIALTY: - nType = SubsetType::Specialty; - break; - default: - nType = SubsetType::Bonus; - break; - } - m_vSubsets.emplace_back(pSet->id, GetRealGameId(pSet->game_id), - ra::util::String::Widen(pSet->title), nType); - } - } + Assets().InitializeSubsets(game_data_response, m_nActiveGameId != m_nGameId); // if subsets were found, migrate any SUBSET-User.txt files into the the GAME-User.txt file - if (m_vSubsets.size() > 1) - { + if (Assets().AchievementSets().Count() > 1) MigrateSubsetUserFiles(); - } - else if (m_nActiveGameId != m_nGameId) - { - m_vSubsets.front().SetTitle(ra::util::String::Printf(L"%s (%s)", - m_vSubsets.front().Title(), game_data_response->title)); - } } void GameContext::MigrateSubsetUserFiles() @@ -563,22 +523,22 @@ void GameContext::MigrateSubsetUserFiles() auto& pLocalStorage = ra::services::ServiceLocator::GetMutable(); std::unique_ptr pGameData; - for (size_t i = 1; i < m_vSubsets.size(); ++i) + for (const auto& pSubset : Assets().AchievementSets()) { - const auto& pSubset = m_vSubsets.at(i); - Expects(pSubset.GameID() != m_nGameId); + if (pSubset.GetBackingGameID() == m_nGameId) + continue; auto pSubsetData = pLocalStorage.ReadText(ra::services::StorageItemType::UserAchievements, - std::to_wstring(pSubset.GameID())); + std::to_wstring(pSubset.GetBackingGameID())); if (pSubsetData) { // replace ID with "0|SUBSETID" so new IDs will be generated - std::string sSubsetReplace = "0|" + std::to_string(pSubset.AchievementSetID()); + std::string sSubsetReplace = "0|" + std::to_string(pSubset.GetID()); if (!pGameData) { pGameData = pLocalStorage.AppendText(ra::services::StorageItemType::UserAchievements, - std::to_wstring(m_nGameId)); + std::to_wstring(m_nGameId)); if (!pGameData) { RA_LOG_ERR("Could not append to %u-User.txt", m_nGameId); @@ -622,17 +582,17 @@ void GameContext::MigrateSubsetUserFiles() // release the file so it can be deleted, then delete it. pSubsetData.reset(); pLocalStorage.Delete(ra::services::StorageItemType::UserAchievements, - std::to_wstring(pSubset.GameID())); + std::to_wstring(pSubset.GetBackingGameID())); } } } uint32_t GameContext::GetGameId(uint32_t nSubsetId) const noexcept { - for (const auto& pSubset : m_vSubsets) + for (const auto& pSubset : Assets().AchievementSets()) { - if (pSubset.ID() == nSubsetId) - return pSubset.GameID(); + if (pSubset.GetID() == nSubsetId) + return pSubset.GetBackingGameID(); } return GameId(); diff --git a/src/data/context/GameContext.hh b/src/data/context/GameContext.hh index 745e270cc..df23fe368 100644 --- a/src/data/context/GameContext.hh +++ b/src/data/context/GameContext.hh @@ -4,12 +4,11 @@ #include "context/IGameContext.hh" +#include "data/models/GameAssets.hh" #include "data/models/LocalBadgesModel.hh" #include "services/ServiceLocator.hh" -#include "GameAssets.hh" - #include #include @@ -56,11 +55,6 @@ public: /// bool IsGameLoading() const noexcept { return m_nLoadCount != 0; } - /// - /// Gets the title of the currently loaded game. - /// - const std::wstring& GameTitle() const noexcept { return m_sGameTitle; } - /// /// Sets the game title. /// @@ -95,20 +89,6 @@ public: } } - /// - /// Determines if the provided game identifier is virtual - /// - /// - /// IDs above 1 billion are incompatible. The 100 millions place indicates how. - /// Mask off the part above 100 million to get the actual game id. - /// - static constexpr bool IsVirtualGameId(uint32_t nGameId) noexcept { return nGameId > 1000000000; } - - /// - /// Gets the real game identifier from a virtual one - /// - static constexpr uint32_t GetRealGameId(uint32_t nGameId) noexcept { return nGameId % 100000000; } - enum HashCompatibility { Compatible = 0, @@ -128,44 +108,11 @@ public: /// /// Gets the assets for the current game. /// - GameAssets& Assets() noexcept { return m_vAssets; } - const GameAssets& Assets() const noexcept { return m_vAssets; } + ra::data::models::GameAssets& Assets() noexcept { return m_vAssets; } + const ra::data::models::GameAssets& Assets() const noexcept { return m_vAssets; } void DoFrame(); - enum SubsetType - { - Core, - Bonus, - Specialty, - Exclusive, - }; - - class Subset - { - public: - Subset(uint32_t nAchievementSetId, uint32_t nGameId, const std::wstring& sTitle, SubsetType nType) : - m_sTitle(sTitle), m_nType(nType), m_nAchievementSetId(nAchievementSetId), m_nGameId(nGameId) - { - } - - const std::wstring& Title() const noexcept { return m_sTitle; } - SubsetType Type() const noexcept { return m_nType; } - uint32_t AchievementSetID() const noexcept { return m_nAchievementSetId; } - uint32_t GameID() const noexcept { return m_nGameId; } - - // Core assets have SubsetId of 0 - uint32_t ID() const noexcept { return (m_nType == SubsetType::Core) ? 0 : m_nAchievementSetId; } - - void SetTitle(const std::wstring& sTitle) { m_sTitle = sTitle; } - - private: - std::wstring m_sTitle; - SubsetType m_nType; - uint32_t m_nAchievementSetId; - uint32_t m_nGameId; - }; - const std::vector& Subsets() const noexcept { return m_vSubsets; } void InitializeSubsets(const rc_api_fetch_game_sets_response_t* game_data_response); uint32_t GetGameId(uint32_t nSubsetId) const noexcept; @@ -207,14 +154,11 @@ protected: void BeginLoad(); void EndLoad(); - std::wstring m_sGameTitle; std::string m_sGameHash; Mode m_nMode{}; - std::vector m_vSubsets; - private: - GameAssets m_vAssets; + ra::data::models::GameAssets m_vAssets; std::atomic m_nLoadCount = 0; int m_nMasteryPopupId = 0; diff --git a/src/devkit/RADevKit.vcxproj b/src/devkit/RADevKit.vcxproj index 0cc079922..9fffc5998 100644 --- a/src/devkit/RADevKit.vcxproj +++ b/src/devkit/RADevKit.vcxproj @@ -57,6 +57,7 @@ + @@ -68,7 +69,9 @@ + + @@ -85,9 +88,11 @@ + + @@ -103,7 +108,9 @@ + + diff --git a/src/devkit/RADevKit.vcxproj.filters b/src/devkit/RADevKit.vcxproj.filters index 0629c30a3..6e4a81699 100644 --- a/src/devkit/RADevKit.vcxproj.filters +++ b/src/devkit/RADevKit.vcxproj.filters @@ -207,6 +207,18 @@ data\util + + context\impl + + + context + + + data\models + + + data\models + @@ -293,5 +305,14 @@ data\util + + context\impl + + + data\models + + + data\models + \ No newline at end of file diff --git a/src/devkit/context/IDevKitContext.hh b/src/devkit/context/IDevKitContext.hh new file mode 100644 index 000000000..2138d48cb --- /dev/null +++ b/src/devkit/context/IDevKitContext.hh @@ -0,0 +1,29 @@ +#ifndef RA_CONTEXT_IDEVKITCONTEXT_HH +#define RA_CONTEXT_IDEVKITCONTEXT_HH +#pragma once + +#include + +namespace ra { +namespace context { + +class IDevKitContext +{ +public: + IDevKitContext() noexcept = default; + virtual ~IDevKitContext() noexcept = default; + IDevKitContext(const IDevKitContext&) noexcept = delete; + IDevKitContext& operator=(const IDevKitContext&) noexcept = delete; + IDevKitContext(IDevKitContext&&) noexcept = delete; + IDevKitContext& operator=(IDevKitContext&&) noexcept = delete; + + /// + /// Gets the version of the devkit library. + /// + virtual const std::string& Version() const noexcept = 0; +}; + +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_USERCONTEXT_HH diff --git a/src/devkit/context/IGameContext.hh b/src/devkit/context/IGameContext.hh index 74e2454a1..8a5315358 100644 --- a/src/devkit/context/IGameContext.hh +++ b/src/devkit/context/IGameContext.hh @@ -33,6 +33,11 @@ public: /// uint32_t GameId() const noexcept { return m_nGameId; } + /// + /// Gets the title of the currently loaded game. + /// + const std::wstring& GameTitle() const noexcept { return m_sGameTitle; } + /// /// Gets the unique identifier of the base game for the currently loaded subset. /// @@ -41,6 +46,20 @@ public: /// uint32_t ActiveGameId() const noexcept { return m_nActiveGameId; } + /// + /// Determines if the provided game identifier is virtual + /// + /// + /// IDs above 1 billion are incompatible. The 100 millions place indicates how. + /// Mask off the part above 100 million to get the actual game id. + /// + static constexpr bool IsVirtualGameId(uint32_t nGameId) noexcept { return nGameId > 1000000000; } + + /// + /// Gets the real game identifier from a virtual one + /// + static constexpr uint32_t GetRealGameId(uint32_t nGameId) noexcept { return nGameId % 100000000; } + class NotifyTarget { public: @@ -85,6 +104,7 @@ public: protected: uint32_t m_nGameId = 0; uint32_t m_nActiveGameId = 0; + std::wstring m_sGameTitle; ra::data::NotifyTargetSet m_vNotifyTargets; }; diff --git a/src/devkit/context/impl/DevKitContext.cpp b/src/devkit/context/impl/DevKitContext.cpp new file mode 100644 index 000000000..c09780be5 --- /dev/null +++ b/src/devkit/context/impl/DevKitContext.cpp @@ -0,0 +1,16 @@ +#include "DevKitContext.hh" + +#include "RA_BuildVer.h" + +namespace ra { +namespace context { +namespace impl { + +DevKitContext::DevKitContext() noexcept + : IDevKitContext(), m_sVersion(RA_INTEGRATION_VERSION) +{ +} + +} // namespace impl +} // namespace context +} // namespace ra diff --git a/src/devkit/context/impl/DevKitContext.hh b/src/devkit/context/impl/DevKitContext.hh new file mode 100644 index 000000000..ea9203041 --- /dev/null +++ b/src/devkit/context/impl/DevKitContext.hh @@ -0,0 +1,34 @@ +#ifndef RA_CONTEXT_IMPL_DEVKITCONTEXT_HH +#define RA_CONTEXT_IMPL_DEVKITCONTEXT_HH +#pragma once + +#include "context/IDevKitContext.hh" + +namespace ra { +namespace context { +namespace impl { + +class DevKitContext : public IDevKitContext +{ +public: + DevKitContext() noexcept; + virtual ~DevKitContext() noexcept = default; + DevKitContext(const DevKitContext&) noexcept = delete; + DevKitContext& operator=(const DevKitContext&) noexcept = delete; + DevKitContext(DevKitContext&&) noexcept = delete; + DevKitContext& operator=(DevKitContext&&) noexcept = delete; + + /// + /// Gets the version of the devkit library. + /// + const std::string& Version() const noexcept override { return m_sVersion; } + +private: + std::string m_sVersion; +}; + +} // namespace impl +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_IMPL_DEVKITCONTEXT_HH diff --git a/src/devkit/data/models/AchievementModel.cpp b/src/devkit/data/models/AchievementModel.cpp index 9d7754ca7..a9cf94847 100644 --- a/src/devkit/data/models/AchievementModel.cpp +++ b/src/devkit/data/models/AchievementModel.cpp @@ -3,15 +3,14 @@ #include "context/IGameContext.hh" #include "context/IRcClient.hh" -#include "data/context/GameAssets.hh" // TODO: this is a reference outside of the devkit code for FirstLocalID - -#include "util/Log.hh" - +#include "data/models/GameAssets.hh" #include "data/models/LocalBadgesModel.hh" + #include "data/util/TriggerValidation.hh" #include "services/ServiceLocator.hh" +#include "util/Log.hh" #include "util/Strings.hh" #include @@ -311,7 +310,7 @@ void AchievementModel::SyncIDToRuntime() const void AchievementModel::SyncTitleToRuntime() { - m_sTitleBuffer = ra::util::String::Narrow(GetName()); + m_sTitleBuffer = ra::util::String::Narrow(GetTitle()); m_pAchievementInfo->public_.title = m_sTitleBuffer.c_str(); } @@ -729,7 +728,7 @@ bool AchievementModel::Deserialize(ra::util::Tokenizer& pTokenizer) // line is valid SetName(ra::util::String::Widen(sTitle)); SetDescription(ra::util::String::Widen(sDescription)); - if (GetID() >= ra::data::context::GameAssets::FirstLocalId || GetAuthor().empty()) + if (GetID() >= ra::data::models::GameAssets::FirstLocalId || GetAuthor().empty()) SetAuthor(ra::util::String::Widen(sAuthor)); SetPoints(nPoints); SetBadge(ra::util::String::Widen(sBadge)); diff --git a/src/devkit/data/models/AchievementSetModel.cpp b/src/devkit/data/models/AchievementSetModel.cpp new file mode 100644 index 000000000..413e86aa9 --- /dev/null +++ b/src/devkit/data/models/AchievementSetModel.cpp @@ -0,0 +1,29 @@ +#include "AchievementSetModel.hh" + +#include "context/IRcClient.hh" + +#include "util/Strings.hh" + +#include + +namespace ra { +namespace data { +namespace models { + +const IntModelProperty AchievementSetModel::TypeProperty("AchievementSetModel", "Type", ra::etoi(AchievementSetType::Core)); +const IntModelProperty AchievementSetModel::IDProperty("AchievementSetModel", "ID", 0); +const IntModelProperty AchievementSetModel::BackingGameIDProperty("AchievementSetModel", "BackingGameID", 0); +const StringModelProperty AchievementSetModel::TitleProperty("AchievementSetModel", "Name", L""); + +void AchievementSetModel::Initialize(uint32_t nId, uint32_t nBackingGameId, const std::wstring& sName, AchievementSetType nType) +{ + SetValue(IDProperty, nId); + SetValue(BackingGameIDProperty, nBackingGameId); + SetValue(TitleProperty, sName); + SetValue(TypeProperty, nType); +} + + +} // namespace models +} // namespace data +} // namespace ra diff --git a/src/devkit/data/models/AchievementSetModel.hh b/src/devkit/data/models/AchievementSetModel.hh new file mode 100644 index 000000000..ba86c54e1 --- /dev/null +++ b/src/devkit/data/models/AchievementSetModel.hh @@ -0,0 +1,105 @@ +#ifndef RA_DATA_MODELS_ACHIEVEMENTSETMODEL_H +#define RA_DATA_MODELS_ACHIEVEMENTSETMODEL_H +#pragma once + +#include "data/DataModelBase.hh" + +#include "util/TypeCasts.hh" + +namespace ra { +namespace data { +namespace models { + +enum AchievementSetType +{ + Core, + Bonus, + Specialty, + Exclusive, +}; + +class AchievementSetModel : public DataModelBase +{ +public: + AchievementSetModel() noexcept = default; + ~AchievementSetModel() = default; + AchievementSetModel(const AchievementSetModel&) noexcept = delete; + AchievementSetModel& operator=(const AchievementSetModel&) noexcept = delete; + AchievementSetModel(AchievementSetModel&&) noexcept = delete; + AchievementSetModel& operator=(AchievementSetModel&&) noexcept = delete; + + /// + /// A unique value for local achievement sets. + /// + static constexpr uint32_t LocalId = 0xFFFFFFFF; + + /// + /// Initializes the achievement set. + /// + /// + /// + /// + /// + void Initialize(uint32_t nId, uint32_t nBackingGameId, const std::wstring& sName, AchievementSetType nType); + + /// + /// The for the achievement set type. + /// + static const IntModelProperty TypeProperty; + + /// + /// Gets the achievement set type. + /// + AchievementSetType GetType() const { return ra::itoe(GetValue(TypeProperty)); } + + /// + /// The for the achievement set id. + /// + static const IntModelProperty IDProperty; + + /// + /// Gets the achievement set id. + /// + uint32_t GetID() const { return ra::to_unsigned(GetValue(IDProperty)); } + + /// + /// Sets the achievement set id. + /// + void SetID(uint32_t nValue) { SetValue(IDProperty, nValue); } + + /// + /// The for the backing game id. + /// + static const IntModelProperty BackingGameIDProperty; + + /// + /// Gets the backing game id. + /// + uint32_t GetBackingGameID() const { return ra::to_unsigned(GetValue(BackingGameIDProperty)); } + + /// + /// Sets the backing game id. + /// + void SetBackingGameID(uint32_t nValue) { SetValue(BackingGameIDProperty, nValue); } + + /// + /// The for the title. + /// + static const StringModelProperty TitleProperty; + + /// + /// Gets the title to display. + /// + const std::wstring& GetTitle() const { return GetValue(TitleProperty); } + + /// + /// Sets the title to display. + /// + void SetTitle(const std::wstring& sValue) { SetValue(TitleProperty, sValue); } +}; + +} // namespace models +} // namespace data +} // namespace ra + +#endif RA_DATA_MODELS_ACHIEVEMENTSETMODEL_H diff --git a/src/devkit/data/models/AssetModelBase.hh b/src/devkit/data/models/AssetModelBase.hh index 017cc2ec1..aa2387712 100644 --- a/src/devkit/data/models/AssetModelBase.hh +++ b/src/devkit/data/models/AssetModelBase.hh @@ -90,7 +90,7 @@ public: /// /// Gets the name to display. /// - const std::wstring& GetName() const { return GetValue(NameProperty); } + const std::wstring& GetTitle() const { return GetValue(NameProperty); } /// /// Sets the name to display. diff --git a/src/data/context/GameAssets.cpp b/src/devkit/data/models/GameAssets.cpp similarity index 88% rename from src/data/context/GameAssets.cpp rename to src/devkit/data/models/GameAssets.cpp index cad3227cf..1c5cb95cc 100644 --- a/src/data/context/GameAssets.cpp +++ b/src/devkit/data/models/GameAssets.cpp @@ -1,21 +1,21 @@ #include "GameAssets.hh" -#include "Exports.hh" -#include "util\Log.hh" +#include "context/IDevKitContext.hh" +#include "context/IGameContext.hh" -#include "GameContext.hh" +#include "data/models/LocalBadgesModel.hh" -#include "data\models\LocalBadgesModel.hh" -#include "data\models\RichPresenceModel.hh" +#include "services/ILocalStorage.hh" +#include "services/ServiceLocator.hh" -#include "services\ILocalStorage.hh" -#include "services\ServiceLocator.hh" +#include "util/Log.hh" +#include "util/Strings.hh" -#include "util\Strings.hh" +#include namespace ra { namespace data { -namespace context { +namespace models { ra::data::models::AssetModelBase* GameAssets::FindAsset(ra::data::models::AssetType nType, uint32_t nId) { @@ -215,16 +215,16 @@ void GameAssets::OnBeforeItemRemoved(ModelBase& pModel) void GameAssets::ReloadAssets(const std::vector& vAssetsToReload) { - const auto& pGameContext = ra::services::ServiceLocator::Get(); - if (pGameContext.Subsets().empty()) // server assets haven't been loaded yet + if (AchievementSets().Count() == 0) // server assets haven't been loaded yet return; - const auto nPrimarySubsetId = pGameContext.Subsets().front().AchievementSetID(); + const auto nPrimarySubsetId = AchievementSets().GetItemAt(0)->GetID(); auto* pRichPresence = dynamic_cast(FindAsset(ra::data::models::AssetType::RichPresence, 0)); if (pRichPresence != nullptr) pRichPresence->ReloadRichPresenceScript(); + auto& pGameContext = ra::services::ServiceLocator::GetMutable(); auto& pLocalStorage = ra::services::ServiceLocator::GetMutable(); auto pData = pLocalStorage.ReadText(ra::services::StorageItemType::UserAchievements, std::to_wstring(pGameContext.ActiveGameId())); if (pData == nullptr) @@ -454,7 +454,7 @@ void GameAssets::ReloadAssets(const std::vector& vAssetsToSave) { - const auto& pGameContext = ra::services::ServiceLocator::Get(); + const auto& pGameContext = ra::services::ServiceLocator::Get(); auto& pLocalStorage = ra::services::ServiceLocator::GetMutable(); auto pData = pLocalStorage.WriteText(ra::services::StorageItemType::UserAchievements, std::to_wstring(pGameContext.ActiveGameId())); if (pData == nullptr) @@ -463,21 +463,19 @@ void GameAssets::SaveAssets(const std::vector return; } -#ifdef RA_UTEST - pData->WriteLine("0.0.0.0"); -#else - pData->WriteLine(_RA_IntegrationVersion()); // version used to create the file -#endif + const auto& pDevKitContext = ra::services::ServiceLocator::Get(); + pData->WriteLine(pDevKitContext.Version()); // version used to create the file uint32_t nPrimarySubsetId = 0; - if (pGameContext.Subsets().empty()) + const auto* pPrimarySubset = AchievementSets().GetItemAt(0); + if (pPrimarySubset == nullptr) { pData->WriteLine(pGameContext.GameTitle()); } else { - nPrimarySubsetId = pGameContext.Subsets().front().AchievementSetID(); - pData->WriteLine(pGameContext.Subsets().front().Title()); + nPrimarySubsetId = pPrimarySubset->GetID(); + pData->WriteLine(pPrimarySubset->GetTitle()); } bool bHasDeleted = false; @@ -587,6 +585,54 @@ void GameAssets::SaveAssets(const std::vector } } -} // namespace context +void GameAssets::InitializeSubsets(const rc_api_fetch_game_sets_response_t* game_data_response, bool bSubsetWithoutBase) +{ + Expects(game_data_response != nullptr); + + m_vAchievementSets.Clear(); + + for (uint32_t i = 0; i < game_data_response->num_sets; ++i) + { + auto vmAchievementSet = std::make_unique(); + const auto* pSet = &game_data_response->sets[i]; + + AchievementSetType nType = AchievementSetType::Bonus; + switch (pSet->type) + { + case RC_ACHIEVEMENT_SET_TYPE_CORE: + nType = AchievementSetType::Core; + break; + case RC_ACHIEVEMENT_SET_TYPE_EXCLUSIVE: + nType = AchievementSetType::Exclusive; + break; + case RC_ACHIEVEMENT_SET_TYPE_SPECIALTY: + nType = AchievementSetType::Specialty; + break; + default: + nType = AchievementSetType::Bonus; + break; + } + + + vmAchievementSet->Initialize(pSet->id, + ra::context::IGameContext::GetRealGameId(pSet->game_id), + ra::util::String::Widen(pSet->title), nType); + + m_vAchievementSets.Append(std::move(vmAchievementSet)); + + // core subset should always be first + if (pSet->type == RC_ACHIEVEMENT_SET_TYPE_CORE) + m_vAchievementSets.MoveItem(m_vAchievementSets.Count() - 1, 0); + } + + if (bSubsetWithoutBase && m_vAchievementSets.Count() == 1) + { + auto* pCoreSet = m_vAchievementSets.GetItemAt(0); + pCoreSet->SetTitle(ra::util::String::Printf(L"%s (%s)", + pCoreSet->GetTitle(), game_data_response->title)); + } +} + +} // namespace models } // namespace data } // namespace ra diff --git a/src/data/context/GameAssets.hh b/src/devkit/data/models/GameAssets.hh similarity index 70% rename from src/data/context/GameAssets.hh rename to src/devkit/data/models/GameAssets.hh index 5c5eabe5b..7c1af502f 100644 --- a/src/data/context/GameAssets.hh +++ b/src/devkit/data/models/GameAssets.hh @@ -1,21 +1,25 @@ -#ifndef RA_DATA_GAMEASSETS_HH -#define RA_DATA_GAMEASSETS_HH +#ifndef RA_DATA_MODELS_GAMEASSETS_HH +#define RA_DATA_MODELS_GAMEASSETS_HH #pragma once -#include "data\DataModelCollection.hh" -#include "data\Types.hh" +#include "data/DataModelCollection.hh" -#include "data\models\AchievementModel.hh" -#include "data\models\MemoryNotesModel.hh" -#include "data\models\LeaderboardModel.hh" -#include "data\models\MemoryRegionsModel.hh" -#include "data\models\RichPresenceModel.hh" +#include "data/models/AchievementModel.hh" +#include "data/models/AchievementSetModel.hh" +#include "data/models/MemoryNotesModel.hh" +#include "data/models/LeaderboardModel.hh" +#include "data/models/MemoryRegionsModel.hh" +#include "data/models/RichPresenceModel.hh" + +#include + +struct rc_api_fetch_game_sets_response_t; namespace ra { namespace data { -namespace context { +namespace models { -class GameAssets : public ra::data::DataModelCollection +class GameAssets : public DataModelCollection { public: GSL_SUPPRESS_F6 GameAssets() = default; @@ -38,7 +42,7 @@ public: /// /// Finds the achievement asset for the specified ID. /// - ra::data::models::AchievementModel* FindAchievement(ra::AchievementID nId) + ra::data::models::AchievementModel* FindAchievement(uint32_t nId) { return dynamic_cast(FindAsset(ra::data::models::AssetType::Achievement, nId)); } @@ -46,7 +50,7 @@ public: /// /// Finds the achievement asset for the specified ID. /// - const ra::data::models::AchievementModel* FindAchievement(ra::AchievementID nId) const + const ra::data::models::AchievementModel* FindAchievement(uint32_t nId) const { return dynamic_cast(FindAsset(ra::data::models::AssetType::Achievement, nId)); } @@ -59,7 +63,7 @@ public: /// /// Finds the leaderboard asset for the specified ID. /// - ra::data::models::LeaderboardModel* FindLeaderboard(ra::LeaderboardID nId) + ra::data::models::LeaderboardModel* FindLeaderboard(uint32_t nId) { return dynamic_cast(FindAsset(ra::data::models::AssetType::Leaderboard, nId)); } @@ -67,7 +71,7 @@ public: /// /// Finds the leaderboard asset for the specified ID. /// - const ra::data::models::LeaderboardModel* FindLeaderboard(ra::AchievementID nId) const + const ra::data::models::LeaderboardModel* FindLeaderboard(uint32_t nId) const { return dynamic_cast(FindAsset(ra::data::models::AssetType::Leaderboard, nId)); } @@ -151,14 +155,50 @@ public: /// List of assets to reload, empty to reload all assets. void ReloadAssets(const std::vector& vAssetsToReload); + /// + /// Gets the achievements sets for the loaded game. + /// + const DataModelCollection& AchievementSets() const noexcept { return m_vAchievementSets; } + + /// + /// Initializes the achievement sets collection. + /// + void InitializeSubsets(const rc_api_fetch_game_sets_response_t* game_data_response, bool bSubsetWithoutBase); + + /// + /// Resets the achievement sets collection. + /// + void ClearAchievementSets() { m_vAchievementSets.Clear(); } + + /// + /// The unique identifier of the first local asset. + /// Anything of this value or higher has not been committed to the server. + /// static constexpr uint32_t FirstLocalId = 111000001; - void ResetLocalId() noexcept { m_nNextLocalId = FirstLocalId; } - static constexpr uint32_t LocalSubsetId = 0xFFFFFFFF; + /// + /// Resets the counter for new local assets. + /// + void ResetLocalId() noexcept { m_nNextLocalId = FirstLocalId; } + /// + /// Returns true if any assets have their PauseOnX attributes set. + /// bool HasPauseOnXAssets() const noexcept; + + /// + /// Gets the achievements where PauseOnReset is set. + /// void GetPauseOnResetAchievements(std::vector& vAchievements) const; + + /// + /// Gets the leaderboards where PauseOnReset is set. + /// void GetPauseOnResetLeaderboards(std::vector& vLeaderboards) const; + + /// + /// Gets the leaderboards where PauseOnTrigger is set. + /// void GetPauseOnTriggerLeaderboards(std::vector& vLeaderboards) const; protected: @@ -171,13 +211,14 @@ protected: uint32_t m_nNextLocalId = FirstLocalId; - std::set m_vPauseOnResetAchievementIds; - std::set m_vPauseOnResetLeaderboardIds; - std::set m_vPauseOnTriggerLeaderboardIds; + DataModelCollection m_vAchievementSets; + std::set m_vPauseOnResetAchievementIds; + std::set m_vPauseOnResetLeaderboardIds; + std::set m_vPauseOnTriggerLeaderboardIds; }; -} // namespace context +} // namespace models } // namespace data } // namespace ra -#endif // !RA_DATA_GAMEASSETS_HH +#endif // !RA_DATA_MODELS_GAMEASSETS_HH diff --git a/src/devkit/data/models/LeaderboardModel.cpp b/src/devkit/data/models/LeaderboardModel.cpp index 4b822b52a..2b4535590 100644 --- a/src/devkit/data/models/LeaderboardModel.cpp +++ b/src/devkit/data/models/LeaderboardModel.cpp @@ -288,7 +288,7 @@ void LeaderboardModel::SyncIDToRuntime() const void LeaderboardModel::SyncTitleToRuntime() { - m_sTitleBuffer = ra::util::String::Narrow(GetName()); + m_sTitleBuffer = ra::util::String::Narrow(GetTitle()); m_pLeaderboardInfo->public_.title = m_sTitleBuffer.c_str(); } diff --git a/src/services/AchievementRuntime.cpp b/src/services/AchievementRuntime.cpp index 754bb9e98..7455d2eb1 100644 --- a/src/services/AchievementRuntime.cpp +++ b/src/services/AchievementRuntime.cpp @@ -623,7 +623,7 @@ class AchievementRuntime::ClientSynchronizer rc_client_subset_info_t& pCoreSubsetWrapper, rc_client_subset_info_t& pLocalSubsetWrapper, const rc_client_subset_info_t* pSubset, uint32_t nSubsetId, - ra::data::context::GameAssets& vAssets) + ra::data::models::GameAssets& vAssets) { std::vector vCoreAchievements; std::vector vLocalAchievements; @@ -671,7 +671,7 @@ class AchievementRuntime::ClientSynchronizer SyncSubset(&pCoreSubsetWrapper, &pSubsetWrapper, vCoreAchievements, vCoreLeaderboards); - pLocalSubsetWrapper.public_.id = ra::data::context::GameAssets::LocalSubsetId; + pLocalSubsetWrapper.public_.id = ra::data::models::AchievementSetModel::LocalId; pLocalSubsetWrapper.public_.title = "Local"; snprintf(pLocalSubsetWrapper.public_.badge_name, sizeof(pLocalSubsetWrapper.public_.badge_name), "%s", pSubset->public_.badge_name); @@ -1234,7 +1234,7 @@ void AchievementRuntime::UnloadGame() /* ---- DoFrame ----- */ -static void PrepareForPauseOnReset(const ra::data::context::GameAssets& pAssets, +static void PrepareForPauseOnReset(const ra::data::models::GameAssets& pAssets, std::vector& vAchievementsWithHits) { std::vector vAchievements; @@ -1251,7 +1251,7 @@ static void PrepareForPauseOnReset(const ra::data::context::GameAssets& pAssets, } } -static void PrepareForPauseOnReset(const ra::data::context::GameAssets& pAssets, +static void PrepareForPauseOnReset(const ra::data::models::GameAssets& pAssets, std::map& mLeaderboardsWithHits) { std::vector vLeaderboards; @@ -1286,7 +1286,7 @@ static void PrepareForPauseOnReset(const ra::data::context::GameAssets& pAssets, } } -static void PrepareForPauseOnTrigger(const ra::data::context::GameAssets& pAssets, +static void PrepareForPauseOnTrigger(const ra::data::models::GameAssets& pAssets, std::map& mActiveLeaderboards) { std::vector vLeaderboards; @@ -1752,9 +1752,9 @@ static void ShowCompletionPopup(uint32_t nGameId, const std::wstring& sTitle, ui static void HandleSubsetCompletedEvent(const rc_client_subset_t& pSubset) { const auto& pGameContext = ra::services::ServiceLocator::Get(); - for (const auto& pGameSubset : pGameContext.Subsets()) + for (const auto& pGameSubset : pGameContext.Assets().AchievementSets()) { - if (pGameSubset.AchievementSetID() == pSubset.id) + if (pGameSubset.GetID() == pSubset.id) { uint32_t nPoints = 0; for (const auto& pAsset : pGameContext.Assets()) @@ -1764,8 +1764,8 @@ static void HandleSubsetCompletedEvent(const rc_client_subset_t& pSubset) nPoints += pAchievement->GetPoints(); } - const auto sTitle = ra::util::String::Printf(L"%s (%s)", pGameSubset.Title(), pGameContext.GameTitle()); - ShowCompletionPopup(pGameSubset.GameID(), sTitle, pSubset.num_achievements, nPoints, pSubset.badge_name); + const auto sTitle = ra::util::String::Printf(L"%s (%s)", pGameSubset.GetTitle(), pGameContext.GameTitle()); + ShowCompletionPopup(pGameSubset.GetBackingGameID(), sTitle, pSubset.num_achievements, nPoints, pSubset.badge_name); break; } } @@ -2060,7 +2060,7 @@ static void HandleServerError(const rc_client_server_error_t& pServerError) if (pAchievement != nullptr) { vmPopup->SetDescription( - ra::util::String::Printf(L"%s (%u)", pAchievement->GetName(), pAchievement->GetPoints())); + ra::util::String::Printf(L"%s (%u)", pAchievement->GetTitle(), pAchievement->GetPoints())); vmPopup->SetImage(ra::ui::ImageType::Badge, ra::util::String::Narrow(pAchievement->GetBadge())); } else @@ -2085,7 +2085,7 @@ static void HandleServerError(const rc_client_server_error_t& pServerError) const auto& pGameContext = ra::services::ServiceLocator::Get(); const auto* pLeaderboard = pGameContext.Assets().FindLeaderboard(nLeaderboardId); std::wstring sLeaderboardName = (pLeaderboard != nullptr) ? - pLeaderboard->GetName() : ra::util::String::Printf(L"Leaderboard %u", nLeaderboardId); + pLeaderboard->GetTitle() : ra::util::String::Printf(L"Leaderboard %u", nLeaderboardId); const auto sErrorMessage = pServerError.error_message ? ra::util::String::Widen(pServerError.error_message) : L"Error submitting leaderboard entry"; diff --git a/src/services/AchievementRuntimeExports.cpp b/src/services/AchievementRuntimeExports.cpp index 1b6aac7a9..2efdebce6 100644 --- a/src/services/AchievementRuntimeExports.cpp +++ b/src/services/AchievementRuntimeExports.cpp @@ -1086,7 +1086,7 @@ const ra::data::models::AchievementModel* CheckForPauseOnTrigger(const rc_client if (vmAchievement->IsPauseOnTrigger()) { auto& pFrameEventQueue = ra::services::ServiceLocator::GetMutable(); - pFrameEventQueue.QueuePauseOnTrigger(vmAchievement->GetName()); + pFrameEventQueue.QueuePauseOnTrigger(vmAchievement->GetTitle()); } } diff --git a/src/services/Initialization.cpp b/src/services/Initialization.cpp index 2f2c0a315..13a7b3951 100644 --- a/src/services/Initialization.cpp +++ b/src/services/Initialization.cpp @@ -4,6 +4,7 @@ #include "context\UserContext.hh" #include "context\impl\ConsoleContext.hh" +#include "context\impl\DevKitContext.hh" #include "context\impl\EmulatorMemoryContext.hh" #include "context\impl\RcClient.hh" @@ -102,6 +103,9 @@ void Initialization::RegisterCoreServices() ra::services::ServiceLocator::Provide(std::move(pFileSystem)); ra::services::ServiceLocator::Provide(std::move(pLogger)); + auto pDevKitContext = std::make_unique(); + ra::services::ServiceLocator::Provide(std::move(pDevKitContext)); + auto pConfiguration = std::make_unique(); ra::services::ServiceLocator::Provide(std::move(pConfiguration)); } diff --git a/src/ui/viewmodels/AssetEditorViewModel.cpp b/src/ui/viewmodels/AssetEditorViewModel.cpp index 62d269d8a..6ee66a52f 100644 --- a/src/ui/viewmodels/AssetEditorViewModel.cpp +++ b/src/ui/viewmodels/AssetEditorViewModel.cpp @@ -178,7 +178,7 @@ void AssetEditorViewModel::LoadAsset(ra::data::models::AssetModelBase* pAsset, b { pAsset->AddNotifyTarget(*this); - SetName(pAsset->GetName()); + SetName(pAsset->GetTitle()); SetDescription(pAsset->GetDescription()); SetState(pAsset->GetState()); SetCategory(pAsset->GetCategory()); diff --git a/src/ui/viewmodels/AssetEditorViewModel.hh b/src/ui/viewmodels/AssetEditorViewModel.hh index 5f4868682..bcc91cc9d 100644 --- a/src/ui/viewmodels/AssetEditorViewModel.hh +++ b/src/ui/viewmodels/AssetEditorViewModel.hh @@ -100,7 +100,7 @@ public: /// /// Gets the name to display. /// - const std::wstring& GetName() const { return GetValue(NameProperty); } + const std::wstring& GetTitle() const { return GetValue(NameProperty); } /// /// Sets the name to display. diff --git a/src/ui/viewmodels/AssetListViewModel.cpp b/src/ui/viewmodels/AssetListViewModel.cpp index 7ad5ece1d..ea552350c 100644 --- a/src/ui/viewmodels/AssetListViewModel.cpp +++ b/src/ui/viewmodels/AssetListViewModel.cpp @@ -130,15 +130,15 @@ void AssetListViewModel::OnActiveGameChanged() m_vSubsets.BeginUpdate(); m_vSubsets.Clear(); - for (const auto& pSubset : pGameContext.Subsets()) - m_vSubsets.Add(pSubset.AchievementSetID(), pSubset.Title()); + for (const auto& pSubset : pGameContext.Assets().AchievementSets()) + m_vSubsets.Add(pSubset.GetID(), pSubset.GetTitle()); m_vSubsets.EndUpdate(); - if (pGameContext.Subsets().empty()) + if (pGameContext.Assets().AchievementSets().Count() == 0) SetSubsetFilter(0); else - SetSubsetFilter(pGameContext.Subsets().front().AchievementSetID()); + SetSubsetFilter(pGameContext.Assets().AchievementSets().GetItemAt(0)->GetID()); m_bInitializingFilter = false; @@ -573,7 +573,7 @@ void AssetListViewModel::AddOrRemoveFilteredItem(gsl::index nAssetIndex) void AssetListViewModel::SyncAsset(AssetSummaryViewModel& vmSummary, const ra::data::models::AssetModelBase& pAsset) { - vmSummary.SetLabel(pAsset.GetName()); + vmSummary.SetLabel(pAsset.GetTitle()); vmSummary.SetType(pAsset.GetType()); vmSummary.SetCategory(pAsset.GetCategory()); vmSummary.SetChanges(pAsset.GetChanges()); @@ -1368,26 +1368,26 @@ void AssetListViewModel::ValidateAchievementForCore(std::wstring& sError, const { const std::wstring sTriggerError = ValidateTriggerLogic(pAchievement.GetTrigger()); if (!sTriggerError.empty()) - sError.append(ra::util::String::Printf(L"\n* %s: %s", pAchievement.GetName(), sTriggerError)); + sError.append(ra::util::String::Printf(L"\n* %s: %s", pAchievement.GetTitle(), sTriggerError)); } void AssetListViewModel::ValidateLeaderboardForCore(std::wstring& sError, const ra::data::models::LeaderboardModel& pLeaderboard) const { std::wstring sTriggerError = ValidateTriggerLogic(pLeaderboard.GetStartTrigger()); if (!sTriggerError.empty()) - sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetName(), L"Start", sTriggerError)); + sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetTitle(), L"Start", sTriggerError)); sTriggerError = ValidateTriggerLogic(pLeaderboard.GetSubmitTrigger()); if (!sTriggerError.empty()) - sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetName(), L"Submit", sTriggerError)); + sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetTitle(), L"Submit", sTriggerError)); sTriggerError = ValidateTriggerLogic(pLeaderboard.GetCancelTrigger()); if (!sTriggerError.empty()) - sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetName(), L"Cancel", sTriggerError)); + sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetTitle(), L"Cancel", sTriggerError)); const std::wstring sValueError = ValidateValueLogic(pLeaderboard.GetValueDefinition()); if (!sValueError.empty()) - sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetName(), L"Value", sValueError)); + sError.append(ra::util::String::Printf(L"\n* %s: %s: %s", pLeaderboard.GetTitle(), L"Value", sValueError)); } @@ -1415,13 +1415,13 @@ bool AssetListViewModel::ValidateAssetsForCore(std::vectorGetStartTrigger().empty()) - sError.append(ra::util::String::Printf(L"\n* %s: No Start condition", pLeaderboard->GetName())); + sError.append(ra::util::String::Printf(L"\n* %s: No Start condition", pLeaderboard->GetTitle())); if (pLeaderboard->GetCancelTrigger().empty()) - sError.append(ra::util::String::Printf(L"\n* %s: No Cancel condition", pLeaderboard->GetName())); + sError.append(ra::util::String::Printf(L"\n* %s: No Cancel condition", pLeaderboard->GetTitle())); if (pLeaderboard->GetSubmitTrigger().empty()) - sError.append(ra::util::String::Printf(L"\n* %s: No Submit condition", pLeaderboard->GetName())); + sError.append(ra::util::String::Printf(L"\n* %s: No Submit condition", pLeaderboard->GetTitle())); if (pLeaderboard->GetValueDefinition().empty()) - sError.append(ra::util::String::Printf(L"\n* %s: No Value definition", pLeaderboard->GetName())); + sError.append(ra::util::String::Printf(L"\n* %s: No Value definition", pLeaderboard->GetTitle())); ValidateLeaderboardForCore(sError, *pLeaderboard); } @@ -1955,7 +1955,7 @@ void AssetListViewModel::CloneSelected() vmAchievement.SetAuthor(pAuthor); vmAchievement.UpdateServerCheckpoint(); - vmAchievement.SetName(pSourceAchievement->GetName() + L" (copy)"); + vmAchievement.SetName(pSourceAchievement->GetTitle() + L" (copy)"); vmAchievement.SetDescription(pSourceAchievement->GetDescription()); vmAchievement.SetBadge(pSourceAchievement->GetBadge()); vmAchievement.SetPoints(pSourceAchievement->GetPoints()); @@ -1977,7 +1977,7 @@ void AssetListViewModel::CloneSelected() vmLeaderboard.SetAuthor(pAuthor); vmLeaderboard.UpdateServerCheckpoint(); - vmLeaderboard.SetName(pSourceLeaderboard->GetName() + L" (copy)"); + vmLeaderboard.SetName(pSourceLeaderboard->GetTitle() + L" (copy)"); vmLeaderboard.SetDescription(pSourceLeaderboard->GetDescription()); vmLeaderboard.SetStartTrigger(pSourceLeaderboard->GetStartTrigger()); vmLeaderboard.SetSubmitTrigger(pSourceLeaderboard->GetSubmitTrigger()); diff --git a/src/ui/viewmodels/AssetListViewModel.hh b/src/ui/viewmodels/AssetListViewModel.hh index f40d259da..b15b3d905 100644 --- a/src/ui/viewmodels/AssetListViewModel.hh +++ b/src/ui/viewmodels/AssetListViewModel.hh @@ -99,8 +99,8 @@ public: /// /// Gets the list of asset subsets. /// - const LookupItemViewModelCollection& Subsets() const noexcept { return m_vSubsets; } - LookupItemViewModelCollection& Subsets() noexcept { return m_vSubsets; } + const LookupItemViewModelCollection& AchievementSets() const noexcept { return m_vSubsets; } + LookupItemViewModelCollection& AchievementSets() noexcept { return m_vSubsets; } /// /// Gets the list of asset states. diff --git a/src/ui/viewmodels/AssetUploadViewModel.cpp b/src/ui/viewmodels/AssetUploadViewModel.cpp index a74cdb0dc..81c6090bc 100644 --- a/src/ui/viewmodels/AssetUploadViewModel.cpp +++ b/src/ui/viewmodels/AssetUploadViewModel.cpp @@ -262,7 +262,7 @@ void AssetUploadViewModel::UploadAchievement(ra::data::models::AchievementModel& ra::api::UpdateAchievement::Request request; request.GameId = pGameContext.GetGameId(pAchievement.GetSubsetID()); - request.Title = pAchievement.GetName(); + request.Title = pAchievement.GetTitle(); request.Description = pAchievement.GetDescription(); request.Trigger = pAchievement.GetTrigger(); request.Points = pAchievement.GetPoints(); @@ -329,7 +329,7 @@ void AssetUploadViewModel::UploadAchievement(ra::data::models::AchievementModel& if (response.ErrorMessage == "Invalid state") { // generic API failure. Try to guess what went wrong - if (pAchievement.GetName().empty()) + if (pAchievement.GetTitle().empty()) pScan.sErrorMessage = "Title is required"; else if (pAchievement.GetDescription().empty()) pScan.sErrorMessage = "Description is required"; @@ -349,7 +349,7 @@ void AssetUploadViewModel::UploadLeaderboard(ra::data::models::LeaderboardModel& ra::api::UpdateLeaderboard::Request request; request.GameId = pGameContext.GetGameId(pLeaderboard.GetSubsetID()); - request.Title = pLeaderboard.GetName(); + request.Title = pLeaderboard.GetTitle(); request.Description = pLeaderboard.GetDescription(); request.StartTrigger = pLeaderboard.GetStartTrigger(); request.SubmitTrigger = pLeaderboard.GetSubmitTrigger(); @@ -393,7 +393,7 @@ void AssetUploadViewModel::UploadLeaderboard(ra::data::models::LeaderboardModel& if (response.ErrorMessage == "Invalid state") { // generic API failure. Try to guess what went wrong - if (pLeaderboard.GetName().empty()) + if (pLeaderboard.GetTitle().empty()) pScan.sErrorMessage = "Title is required"; else if (pLeaderboard.GetDescription().empty()) pScan.sErrorMessage = "Description is required"; @@ -684,7 +684,7 @@ void AssetUploadViewModel::ShowResults() const default: sMessage.append(ra::util::String::Printf(L"\n* %s: %s", - pItem.pAsset->GetName(), + pItem.pAsset->GetTitle(), pItem.sErrorMessage)); break; } diff --git a/src/ui/viewmodels/BrokenAchievementsViewModel.cpp b/src/ui/viewmodels/BrokenAchievementsViewModel.cpp index 90cdb59c7..bbbb109b2 100644 --- a/src/ui/viewmodels/BrokenAchievementsViewModel.cpp +++ b/src/ui/viewmodels/BrokenAchievementsViewModel.cpp @@ -3,7 +3,7 @@ #include "util\Strings.hh" #include "data\context\GameContext.hh" -#include "data\context\GameAssets.hh" +#include "data\models\GameAssets.hh" #include "services\IConfiguration.hh" #include "services\ServiceLocator.hh" @@ -54,7 +54,7 @@ bool BrokenAchievementsViewModel::InitializeAchievements() { auto& vmAchievement = m_vAchievements.Add(); vmAchievement.SetId(pAchievement->GetID()); - vmAchievement.SetLabel(pAchievement->GetName()); + vmAchievement.SetLabel(pAchievement->GetTitle()); vmAchievement.SetDescription(pAchievement->GetDescription()); vmAchievement.SetAchieved(!pAchievement->IsActive()); } diff --git a/src/ui/viewmodels/OverlayAchievementsPageViewModel.cpp b/src/ui/viewmodels/OverlayAchievementsPageViewModel.cpp index 604161db8..c76e99005 100644 --- a/src/ui/viewmodels/OverlayAchievementsPageViewModel.cpp +++ b/src/ui/viewmodels/OverlayAchievementsPageViewModel.cpp @@ -129,7 +129,7 @@ void OverlayAchievementsPageViewModel::Refresh() if (!pSubset->active) continue; - if (pSubset->public_.id == ra::data::context::GameAssets::LocalSubsetId) + if (pSubset->public_.id == ra::data::models::AchievementSetModel::LocalId) { vDeactivatedSubsets.push_back(pSubset); pSubset->active = 0; @@ -381,7 +381,7 @@ void OverlayAchievementsPageViewModel::FetchItemDetail(ItemViewModel& vmItem) vmAchievement.SetCreatedDate(ra::util::String::FormatDateTime(pAchievement->created_time)); vmAchievement.SetModifiedDate(ra::util::String::FormatDateTime(pAchievement->updated_time)); - if (nAchievementID >= ra::data::context::GameAssets::FirstLocalId) + if (nAchievementID >= ra::data::models::GameAssets::FirstLocalId) { vmAchievement.SetWonBy(L"Local Achievement"); return; diff --git a/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp b/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp index 2ad9dc119..1d7fc6880 100644 --- a/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp +++ b/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp @@ -80,7 +80,7 @@ void OverlayLeaderboardsPageViewModel::Refresh() if (!pSubset->active) continue; - if (pSubset->public_.id == ra::data::context::GameAssets::LocalSubsetId) + if (pSubset->public_.id == ra::data::models::AchievementSetModel::LocalId) { vDeactivatedSubsets.push_back(pSubset); pSubset->active = 0; diff --git a/src/ui/viewmodels/TriggerViewModel.cpp b/src/ui/viewmodels/TriggerViewModel.cpp index c6547e6da..286ed6ce8 100644 --- a/src/ui/viewmodels/TriggerViewModel.cpp +++ b/src/ui/viewmodels/TriggerViewModel.cpp @@ -961,9 +961,9 @@ void TriggerViewModel::Summarize() TriggerSummaryViewModel vmSummary; if (m_vGroups.Count() == 1) - vmSummary.SetWindowTitle(L"Trigger Summary - " + pAssetEditor.GetAsset()->GetName()); + vmSummary.SetWindowTitle(L"Trigger Summary - " + pAssetEditor.GetAsset()->GetTitle()); else - vmSummary.SetWindowTitle(pGroup->GetLabel() + L" Summary - " + pAssetEditor.GetAsset()->GetName()); + vmSummary.SetWindowTitle(pGroup->GetLabel() + L" Summary - " + pAssetEditor.GetAsset()->GetTitle()); vmSummary.InitializeFrom(*pCondSet); vmSummary.AddHeaders(); diff --git a/src/ui/win32/AssetListDialog.cpp b/src/ui/win32/AssetListDialog.cpp index 8d0f05583..b9f16a323 100644 --- a/src/ui/win32/AssetListDialog.cpp +++ b/src/ui/win32/AssetListDialog.cpp @@ -63,7 +63,7 @@ class IdColumnBinding : public ra::ui::win32::bindings::GridNumberColumnBinding { const auto nId = vmItems.GetItemValue(nIndex, *m_pBoundProperty); - if (nId >= ra::data::context::GameAssets::FirstLocalId) + if (nId >= ra::data::models::GameAssets::FirstLocalId) return L"0"; const auto nType = vmItems.GetItemValue(nIndex, ra::data::models::AssetModelBase::TypeProperty); @@ -190,7 +190,7 @@ AssetListDialog::AssetListDialog(AssetListViewModel& vmAssetList) { m_bindWindow.SetInitialPosition(RelativePosition::Near, RelativePosition::After, "Achievements"); - m_bindSubsets.BindItems(vmAssetList.Subsets(), ra::ui::viewmodels::LookupItemViewModel::IdProperty, + m_bindSubsets.BindItems(vmAssetList.AchievementSets(), ra::ui::viewmodels::LookupItemViewModel::IdProperty, ra::ui::viewmodels::LookupItemViewModel::LabelProperty); m_bindSubsets.BindSelectedItem(AssetListViewModel::SubsetFilterProperty); diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj index 0206547f4..fbfda826f 100644 --- a/tests/RA_Integration.Tests.vcxproj +++ b/tests/RA_Integration.Tests.vcxproj @@ -74,7 +74,6 @@ - @@ -149,7 +148,6 @@ - diff --git a/tests/RA_Integration.Tests.vcxproj.filters b/tests/RA_Integration.Tests.vcxproj.filters index 999a73fa0..2b1e921dc 100644 --- a/tests/RA_Integration.Tests.vcxproj.filters +++ b/tests/RA_Integration.Tests.vcxproj.filters @@ -309,12 +309,6 @@ Tests\UI\ViewModels - - Code - - - Tests\Data\Context - Code diff --git a/tests/data/DataAsserts.hh b/tests/data/DataAsserts.hh index 5286005c8..094715c12 100644 --- a/tests/data/DataAsserts.hh +++ b/tests/data/DataAsserts.hh @@ -27,62 +27,6 @@ std::wstring ToString(const ra::data::cont } } -template<> -std::wstring ToString(const ra::data::context::GameContext::SubsetType& nSubsetType) -{ - switch (nSubsetType) - { - case ra::data::context::GameContext::SubsetType::Core: - return L"Core"; - case ra::data::context::GameContext::SubsetType::Bonus: - return L"Bonus"; - case ra::data::context::GameContext::SubsetType::Specialty: - return L"Specialty"; - case ra::data::context::GameContext::SubsetType::Exclusive: - return L"Exclusive"; - default: - return std::to_wstring(static_cast(nSubsetType)); - } -} - -template<> -std::wstring ToString(const ra::data::models::LeaderboardModel::LeaderboardParts& nParts) -{ - switch (nParts) - { - case ra::data::models::LeaderboardModel::LeaderboardParts::None: - return L"None"; - case ra::data::models::LeaderboardModel::LeaderboardParts::Start: - return L"Start"; - case ra::data::models::LeaderboardModel::LeaderboardParts::Submit: - return L"Submit"; - case ra::data::models::LeaderboardModel::LeaderboardParts::Cancel: - return L"Cancel"; - case ra::data::models::LeaderboardModel::LeaderboardParts::Value: - return L"Value"; - default: - return std::to_wstring(static_cast(nParts)); - } -} - -template<> -std::wstring ToString(const ra::data::models::AchievementType& nAchievementType) -{ - switch (nAchievementType) - { - case ra::data::models::AchievementType::None: - return L"None"; - case ra::data::models::AchievementType::Missable: - return L"Missable"; - case ra::data::models::AchievementType::Progression: - return L"Progression"; - case ra::data::models::AchievementType::Win: - return L"Win"; - default: - return std::to_wstring(static_cast(nAchievementType)); - } -} - #pragma warning(pop) } // namespace CppUnitTestFramework diff --git a/tests/data/context/GameContext_Tests.cpp b/tests/data/context/GameContext_Tests.cpp index 85aa775d3..5f7dc2f78 100644 --- a/tests/data/context/GameContext_Tests.cpp +++ b/tests/data/context/GameContext_Tests.cpp @@ -16,6 +16,7 @@ #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockDevKitContext.hh" #include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\context\mocks\MockUserContext.hh" @@ -23,6 +24,7 @@ #include "tests\devkit\services\mocks\MockLocalStorage.hh" #include "tests\devkit\services\mocks\MockMessageDispatcher.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" +#include "tests\devkit\testutil\AchievementSetAsserts.hh" #include "tests\devkit\testutil\AssetAsserts.hh" #include "tests\devkit\ui\mocks\MockImageRepository.hh" #include "tests\mocks\MockAchievementRuntime.hh" @@ -68,6 +70,7 @@ TEST_CLASS(GameContext_Tests) ra::api::mocks::MockServer mockServer; ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + ra::context::mocks::MockDevKitContext mockDevKitContext; ra::context::mocks::MockRcClient mockRcClient; ra::context::mocks::MockUserContext mockUser; ra::services::mocks::MockClock mockClock; @@ -693,7 +696,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch1); Ensures(vmAch1 != nullptr); Assert::AreEqual(5U, vmAch1->GetID()); - Assert::AreEqual(std::wstring(L"Ach1"), vmAch1->GetName()); + Assert::AreEqual(std::wstring(L"Ach1"), vmAch1->GetTitle()); Assert::AreEqual(std::wstring(L"Desc1"), vmAch1->GetDescription()); Assert::AreEqual(std::wstring(L"Auth1"), vmAch1->GetAuthor()); Assert::AreEqual(ra::data::models::AssetCategory::Core, vmAch1->GetCategory()); @@ -706,7 +709,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch2); Ensures(vmAch2 != nullptr); Assert::AreEqual(7U, vmAch2->GetID()); - Assert::AreEqual(std::wstring(L"Ach2"), vmAch2->GetName()); + Assert::AreEqual(std::wstring(L"Ach2"), vmAch2->GetTitle()); Assert::AreEqual(std::wstring(L"Desc2"), vmAch2->GetDescription()); Assert::AreEqual(std::wstring(L"Auth2"), vmAch2->GetAuthor()); Assert::AreEqual(ra::data::models::AssetCategory::Unofficial, vmAch2->GetCategory()); @@ -741,7 +744,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch1); Ensures(vmAch1 != nullptr); Assert::AreEqual(5U, vmAch1->GetID()); - Assert::AreEqual(std::wstring(L"Ach1"), vmAch1->GetName()); + Assert::AreEqual(std::wstring(L"Ach1"), vmAch1->GetTitle()); Assert::AreEqual(std::wstring(L"Desc1"), vmAch1->GetDescription()); Assert::AreEqual(std::wstring(L"Auth1"), vmAch1->GetAuthor()); Assert::AreEqual(ra::data::models::AssetCategory::Unofficial, vmAch1->GetCategory()); @@ -754,7 +757,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch2); Ensures(vmAch2 != nullptr); Assert::AreEqual(7U, vmAch2->GetID()); - Assert::AreEqual(std::wstring(L"Ach2"), vmAch2->GetName()); + Assert::AreEqual(std::wstring(L"Ach2"), vmAch2->GetTitle()); Assert::AreEqual(std::wstring(L"Desc2"), vmAch2->GetDescription()); Assert::AreEqual(ra::data::models::AssetCategory::Unofficial, vmAch2->GetCategory()); Assert::AreEqual(15, vmAch2->GetPoints()); @@ -792,7 +795,7 @@ TEST_CLASS(GameContext_Tests) auto* pAch = game.Assets().FindAchievement(5U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach1"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach1"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc1"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth1"), pAch->GetAuthor()); Assert::AreEqual(std::wstring(L"12345"), pAch->GetBadge()); @@ -804,7 +807,7 @@ TEST_CLASS(GameContext_Tests) pAch = game.Assets().FindAchievement(7U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach2b"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach2b"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc2b"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth2"), pAch->GetAuthor()); // author not merged Assert::AreEqual(std::wstring(L"54321"), pAch->GetBadge()); @@ -819,7 +822,7 @@ TEST_CLASS(GameContext_Tests) pAch = game.Assets().FindAchievement(9U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach3b"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach3b"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc3b"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth3"), pAch->GetAuthor()); // author not merged Assert::AreEqual(std::wstring(L"54321"), pAch->GetBadge()); @@ -831,10 +834,10 @@ TEST_CLASS(GameContext_Tests) Assert::AreEqual(2U, pTrigger->requirement->conditions->operand2.value.num); // runtime trigger updated // no server achievement, assign FirstLocalId - pAch = game.Assets().FindAchievement(GameAssets::FirstLocalId); + pAch = game.Assets().FindAchievement(ra::data::models::GameAssets::FirstLocalId); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach3"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach3"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc3"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth3"), pAch->GetAuthor()); Assert::AreEqual(std::wstring(L"00555"), pAch->GetBadge()); @@ -843,10 +846,10 @@ TEST_CLASS(GameContext_Tests) Assert::AreEqual(std::string("1=1"), pAch->GetTrigger()); // no server achievement, assign next local id - pAch = game.Assets().FindAchievement(GameAssets::FirstLocalId + 1); + pAch = game.Assets().FindAchievement(ra::data::models::GameAssets::FirstLocalId + 1); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach4"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach4"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc4"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth4"), pAch->GetAuthor()); Assert::AreEqual(std::wstring(L"00556"), pAch->GetBadge()); @@ -878,7 +881,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch); Ensures(vmAch != nullptr); Assert::AreEqual(7U, vmAch->GetID()); - Assert::AreEqual(std::wstring(L"Ach2b"), vmAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach2b"), vmAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc2b"), vmAch->GetDescription()); Assert::AreEqual(ra::data::models::AssetCategory::Local, vmAch->GetCategory()); Assert::AreEqual(25, vmAch->GetPoints()); @@ -892,7 +895,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch); Ensures(vmAch != nullptr); Assert::AreEqual(999000001U, vmAch->GetID()); // non-vms get first id and first id + 1 - Assert::AreEqual(std::wstring(L"Ach3"), vmAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach3"), vmAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc3"), vmAch->GetDescription()); Assert::AreEqual(ra::data::models::AssetCategory::Local, vmAch->GetCategory()); Assert::AreEqual(20, vmAch->GetPoints()); @@ -906,7 +909,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch); Ensures(vmAch != nullptr); Assert::AreEqual(999000003U, vmAch->GetID()); // non-vms get first id and first id + 1 - Assert::AreEqual(std::wstring(L"Ach4"), vmAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach4"), vmAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc4"), vmAch->GetDescription()); Assert::AreEqual(ra::data::models::AssetCategory::Local, vmAch->GetCategory()); Assert::AreEqual(10, vmAch->GetPoints()); @@ -966,14 +969,14 @@ TEST_CLASS(GameContext_Tests) "111000002:\"R:1=1\":Ach6:Desc6::::Auth6:10:1234511111:1234500000:::556\n"); game.LoadGame(1U, "0123456789abcdeffedcba987654321"); - Assert::AreEqual({2U}, game.Subsets().size()); + Assert::AreEqual({2U}, game.Assets().AchievementSets().Count()); Assert::AreEqual(2U, game.GetGameId(3U)); // local achievement data for 5 should be merged with server achievement data auto* pAch = game.Assets().FindAchievement(5U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach1b"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach1b"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc1b"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth1"), pAch->GetAuthor()); // author not merged Assert::AreEqual(std::wstring(L"54321"), pAch->GetBadge()); @@ -985,7 +988,7 @@ TEST_CLASS(GameContext_Tests) pAch = game.Assets().FindAchievement(7U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach2b"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach2b"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc2b"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth2"), pAch->GetAuthor()); // author not merged Assert::AreEqual(std::wstring(L"54321"), pAch->GetBadge()); @@ -997,7 +1000,7 @@ TEST_CLASS(GameContext_Tests) pAch = game.Assets().FindAchievement(111000002U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach3"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach3"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc3"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth3"), pAch->GetAuthor()); Assert::AreEqual(std::wstring(L"00555"), pAch->GetBadge()); @@ -1009,7 +1012,7 @@ TEST_CLASS(GameContext_Tests) pAch = game.Assets().FindAchievement(111000003U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach4"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach4"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc4"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth4"), pAch->GetAuthor()); Assert::AreEqual(std::wstring(L"00556"), pAch->GetBadge()); @@ -1021,7 +1024,7 @@ TEST_CLASS(GameContext_Tests) pAch = game.Assets().FindAchievement(111000004U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach5"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach5"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc5"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth5"), pAch->GetAuthor()); Assert::AreEqual(std::wstring(L"00555"), pAch->GetBadge()); @@ -1033,7 +1036,7 @@ TEST_CLASS(GameContext_Tests) pAch = game.Assets().FindAchievement(111000005U); Assert::IsNotNull(pAch); Ensures(pAch != nullptr); - Assert::AreEqual(std::wstring(L"Ach6"), pAch->GetName()); + Assert::AreEqual(std::wstring(L"Ach6"), pAch->GetTitle()); Assert::AreEqual(std::wstring(L"Desc6"), pAch->GetDescription()); Assert::AreEqual(std::wstring(L"Auth6"), pAch->GetAuthor()); Assert::AreEqual(std::wstring(L"00556"), pAch->GetBadge()); @@ -1070,13 +1073,13 @@ TEST_CLASS(GameContext_Tests) const auto* pLb1 = game.Assets().FindLeaderboard(7U); Assert::IsNotNull(pLb1); Ensures(pLb1 != nullptr); - Assert::AreEqual(std::wstring(L"LB1"), pLb1->GetName()); + Assert::AreEqual(std::wstring(L"LB1"), pLb1->GetTitle()); Assert::AreEqual(std::wstring(L"Desc1"), pLb1->GetDescription()); const auto* pLb2 = game.Assets().FindLeaderboard(8U); Assert::IsNotNull(pLb2); Ensures(pLb2 != nullptr); - Assert::AreEqual(std::wstring(L"LB2"), pLb2->GetName()); + Assert::AreEqual(std::wstring(L"LB2"), pLb2->GetTitle()); Assert::AreEqual(std::wstring(L"Desc2"), pLb2->GetDescription()); } @@ -1116,7 +1119,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch1); Ensures(vmAch1 != nullptr); Assert::AreEqual(9U, vmAch1->GetID()); - Assert::AreEqual(std::wstring(L"Ach9"), vmAch1->GetName()); + Assert::AreEqual(std::wstring(L"Ach9"), vmAch1->GetTitle()); Assert::AreEqual(std::wstring(L"Desc9"), vmAch1->GetDescription()); Assert::AreEqual(ra::data::models::AssetCategory::Core, vmAch1->GetCategory()); Assert::AreEqual(9, vmAch1->GetPoints()); @@ -1128,7 +1131,7 @@ TEST_CLASS(GameContext_Tests) Assert::IsNotNull(vmAch2); Ensures(vmAch2 != nullptr); Assert::AreEqual(11U, vmAch2->GetID()); - Assert::AreEqual(std::wstring(L"Ach11"), vmAch2->GetName()); + Assert::AreEqual(std::wstring(L"Ach11"), vmAch2->GetTitle()); Assert::AreEqual(std::wstring(L"Desc11"), vmAch2->GetDescription()); Assert::AreEqual(ra::data::models::AssetCategory::Unofficial, vmAch2->GetCategory()); Assert::AreEqual(11, vmAch2->GetPoints()); @@ -1598,14 +1601,13 @@ TEST_CLASS(GameContext_Tests) Assert::AreEqual(2222U, game.GameId()); Assert::AreEqual(2222U, game.ActiveGameId()); - Assert::AreEqual({1}, game.Subsets().size()); + Assert::AreEqual({1}, game.Assets().AchievementSets().Count()); - const auto& pSubset = game.Subsets().front(); - Assert::AreEqual(0U, pSubset.ID()); - Assert::AreEqual(11111U, pSubset.AchievementSetID()); - Assert::AreEqual(2222U, pSubset.GameID()); - Assert::AreEqual(GameContext::SubsetType::Core, pSubset.Type()); - Assert::AreEqual(std::wstring(L"Game Title"), pSubset.Title()); + const auto& pSubset = *game.Assets().AchievementSets().GetItemAt(0); + Assert::AreEqual(11111U, pSubset.GetID()); + Assert::AreEqual(2222U, pSubset.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Core, pSubset.GetType()); + Assert::AreEqual(std::wstring(L"Game Title"), pSubset.GetTitle()); } TEST_METHOD(TestInitializeSubsetsCoreWithBonus) @@ -1641,28 +1643,25 @@ TEST_CLASS(GameContext_Tests) Assert::AreEqual(2222U, game.GameId()); Assert::AreEqual(2222U, game.ActiveGameId()); - Assert::AreEqual({3}, game.Subsets().size()); - - const auto& pSubset = game.Subsets().at(0); - Assert::AreEqual(0U, pSubset.ID()); - Assert::AreEqual(11111U, pSubset.AchievementSetID()); - Assert::AreEqual(2222U, pSubset.GameID()); - Assert::AreEqual(GameContext::SubsetType::Core, pSubset.Type()); - Assert::AreEqual(std::wstring(L"Game Title"), pSubset.Title()); - - const auto& pSubset2 = game.Subsets().at(1); - Assert::AreEqual(4444U, pSubset2.ID()); - Assert::AreEqual(4444U, pSubset2.AchievementSetID()); - Assert::AreEqual(3333U, pSubset2.GameID()); - Assert::AreEqual(GameContext::SubsetType::Bonus, pSubset2.Type()); - Assert::AreEqual(std::wstring(L"Bonus"), pSubset2.Title()); - - const auto& pSubset3 = game.Subsets().at(2); - Assert::AreEqual(6666U, pSubset3.ID()); - Assert::AreEqual(6666U, pSubset3.AchievementSetID()); - Assert::AreEqual(5555U, pSubset3.GameID()); - Assert::AreEqual(GameContext::SubsetType::Bonus, pSubset3.Type()); - Assert::AreEqual(std::wstring(L"Perfect Play"), pSubset3.Title()); + Assert::AreEqual({3}, game.Assets().AchievementSets().Count()); + + const auto& pSubset = *game.Assets().AchievementSets().GetItemAt(0); + Assert::AreEqual(11111U, pSubset.GetID()); + Assert::AreEqual(2222U, pSubset.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Core, pSubset.GetType()); + Assert::AreEqual(std::wstring(L"Game Title"), pSubset.GetTitle()); + + const auto& pSubset2 = *game.Assets().AchievementSets().GetItemAt(1); + Assert::AreEqual(4444U, pSubset2.GetID()); + Assert::AreEqual(3333U, pSubset2.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Bonus, pSubset2.GetType()); + Assert::AreEqual(std::wstring(L"Bonus"), pSubset2.GetTitle()); + + const auto& pSubset3 = *game.Assets().AchievementSets().GetItemAt(2); + Assert::AreEqual(6666U, pSubset3.GetID()); + Assert::AreEqual(5555U, pSubset3.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Bonus, pSubset3.GetType()); + Assert::AreEqual(std::wstring(L"Perfect Play"), pSubset3.GetTitle()); } TEST_METHOD(TestInitializeSubsetsExclusive) @@ -1690,14 +1689,13 @@ TEST_CLASS(GameContext_Tests) Assert::AreEqual(3333U, game.GameId()); Assert::AreEqual(2222U, game.ActiveGameId()); - Assert::AreEqual({1}, game.Subsets().size()); + Assert::AreEqual({1}, game.Assets().AchievementSets().Count()); - const auto& pSubset = game.Subsets().at(0); - Assert::AreEqual(1111U, pSubset.ID()); - Assert::AreEqual(1111U, pSubset.AchievementSetID()); - Assert::AreEqual(2222U, pSubset.GameID()); - Assert::AreEqual(GameContext::SubsetType::Exclusive, pSubset.Type()); - Assert::AreEqual(std::wstring(L"Subset Title (Game Title)"), pSubset.Title()); + const auto& pSubset = *game.Assets().AchievementSets().GetItemAt(0); + Assert::AreEqual(1111U, pSubset.GetID()); + Assert::AreEqual(2222U, pSubset.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Exclusive, pSubset.GetType()); + Assert::AreEqual(std::wstring(L"Subset Title (Game Title)"), pSubset.GetTitle()); } TEST_METHOD(TestInitializeSubsetsSpecialtyWithBonus) @@ -1734,28 +1732,25 @@ TEST_CLASS(GameContext_Tests) Assert::AreEqual(2222U, game.GameId()); Assert::AreEqual(5555U, game.ActiveGameId()); - Assert::AreEqual({3}, game.Subsets().size()); - - const auto& pSubset = game.Subsets().at(0); - Assert::AreEqual(0U, pSubset.ID()); - Assert::AreEqual(6666U, pSubset.AchievementSetID()); - Assert::AreEqual(2222U, pSubset.GameID()); - Assert::AreEqual(GameContext::SubsetType::Core, pSubset.Type()); - Assert::AreEqual(std::wstring(L"Game Title"), pSubset.Title()); - - const auto& pSubset2 = game.Subsets().at(1); - Assert::AreEqual(7777U, pSubset2.ID()); - Assert::AreEqual(7777U, pSubset2.AchievementSetID()); - Assert::AreEqual(5555U, pSubset2.GameID()); - Assert::AreEqual(GameContext::SubsetType::Specialty, pSubset2.Type()); - Assert::AreEqual(std::wstring(L"Perfect Play"), pSubset2.Title()); - - const auto& pSubset3 = game.Subsets().at(2); - Assert::AreEqual(4444U, pSubset3.ID()); - Assert::AreEqual(4444U, pSubset3.AchievementSetID()); - Assert::AreEqual(3333U, pSubset3.GameID()); - Assert::AreEqual(GameContext::SubsetType::Bonus, pSubset3.Type()); - Assert::AreEqual(std::wstring(L"Bonus"), pSubset3.Title()); + Assert::AreEqual({3}, game.Assets().AchievementSets().Count()); + + const auto& pSubset = *game.Assets().AchievementSets().GetItemAt(0); + Assert::AreEqual(6666U, pSubset.GetID()); + Assert::AreEqual(2222U, pSubset.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Core, pSubset.GetType()); + Assert::AreEqual(std::wstring(L"Game Title"), pSubset.GetTitle()); + + const auto& pSubset2 = *game.Assets().AchievementSets().GetItemAt(1); + Assert::AreEqual(7777U, pSubset2.GetID()); + Assert::AreEqual(5555U, pSubset2.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Specialty, pSubset2.GetType()); + Assert::AreEqual(std::wstring(L"Perfect Play"), pSubset2.GetTitle()); + + const auto& pSubset3 = *game.Assets().AchievementSets().GetItemAt(2); + Assert::AreEqual(4444U, pSubset3.GetID()); + Assert::AreEqual(3333U, pSubset3.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Bonus, pSubset3.GetType()); + Assert::AreEqual(std::wstring(L"Bonus"), pSubset3.GetTitle()); } TEST_METHOD(TestInitializeSubsetsVirtual) @@ -1781,14 +1776,13 @@ TEST_CLASS(GameContext_Tests) Assert::AreEqual(2222U, game.GameId()); Assert::AreEqual(2222U, game.ActiveGameId()); - Assert::AreEqual({1}, game.Subsets().size()); + Assert::AreEqual({1}, game.Assets().AchievementSets().Count()); - const auto& pSubset = game.Subsets().front(); - Assert::AreEqual(0U, pSubset.ID()); - Assert::AreEqual(11111U, pSubset.AchievementSetID()); - Assert::AreEqual(2222U, pSubset.GameID()); - Assert::AreEqual(GameContext::SubsetType::Core, pSubset.Type()); - Assert::AreEqual(std::wstring(L"Unsupported Game Version"), pSubset.Title()); + const auto& pSubset = *game.Assets().AchievementSets().GetItemAt(0); + Assert::AreEqual(11111U, pSubset.GetID()); + Assert::AreEqual(2222U, pSubset.GetBackingGameID()); + Assert::AreEqual(ra::data::models::AchievementSetType::Core, pSubset.GetType()); + Assert::AreEqual(std::wstring(L"Unsupported Game Version"), pSubset.GetTitle()); } }; diff --git a/tests/devkit/RADevKit.Tests.vcxproj b/tests/devkit/RADevKit.Tests.vcxproj index 1241a8fe4..1a092a6fd 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj +++ b/tests/devkit/RADevKit.Tests.vcxproj @@ -71,6 +71,7 @@ + @@ -79,6 +80,7 @@ + @@ -92,6 +94,7 @@ + @@ -104,6 +107,7 @@ + diff --git a/tests/devkit/RADevKit.Tests.vcxproj.filters b/tests/devkit/RADevKit.Tests.vcxproj.filters index 4c116381d..36af019d1 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj.filters +++ b/tests/devkit/RADevKit.Tests.vcxproj.filters @@ -79,6 +79,9 @@ data\util + + data\models + @@ -185,5 +188,14 @@ testutil + + testutil + + + testutil + + + context\mocks + \ No newline at end of file diff --git a/tests/devkit/context/mocks/MockDevKitContext.hh b/tests/devkit/context/mocks/MockDevKitContext.hh new file mode 100644 index 000000000..ae9368620 --- /dev/null +++ b/tests/devkit/context/mocks/MockDevKitContext.hh @@ -0,0 +1,34 @@ +#ifndef RA_CONTEXT_MOCK_DEVKITCONTEXT_HH +#define RA_CONTEXT_MOCK_DEVKITCONTEXT_HH +#pragma once + +#include "context/IDevKitContext.hh" + +#include "services/ServiceLocator.hh" + +namespace ra { +namespace context { +namespace mocks { + +class MockDevKitContext : public IDevKitContext +{ +public: + GSL_SUPPRESS_F6 MockDevKitContext() noexcept + : m_Override(this) + { + } + + const std::string& Version() const noexcept { return m_sVersion; } + void SetVersion(const std::string& sValue) { m_sVersion = sValue; } + +private: + std::string m_sVersion = "0.0.0.0"; + + ra::services::ServiceLocator::ServiceOverride m_Override; +}; + +} // namespace mocks +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_MOCK_DEVKITCONTEXT_HH diff --git a/tests/devkit/context/mocks/MockGameContext.hh b/tests/devkit/context/mocks/MockGameContext.hh index 855b8fb39..b24030985 100644 --- a/tests/devkit/context/mocks/MockGameContext.hh +++ b/tests/devkit/context/mocks/MockGameContext.hh @@ -23,6 +23,7 @@ public: void SetGameId(uint32_t nId) noexcept { m_nGameId = m_nActiveGameId = nId; } void SetActiveGameId(uint32_t nId) noexcept { m_nActiveGameId = nId; } + void SetGameTitle(const std::wstring& sTitle) noexcept { m_sGameTitle = sTitle; } ra::data::models::MemoryNotesModel& MemoryNotes() noexcept override { return m_oMemoryNotes; } const ra::data::models::MemoryNotesModel& MemoryNotes() const noexcept override { return m_oMemoryNotes; } diff --git a/tests/devkit/data/models/AchievementModel_Tests.cpp b/tests/devkit/data/models/AchievementModel_Tests.cpp index 29eacdd9f..97b3e7f7a 100644 --- a/tests/devkit/data/models/AchievementModel_Tests.cpp +++ b/tests/devkit/data/models/AchievementModel_Tests.cpp @@ -51,7 +51,7 @@ TEST_CLASS(AchievementModel_Tests) Assert::AreEqual(AssetType::Achievement, achievement.GetType()); Assert::AreEqual(0U, achievement.GetID()); - Assert::AreEqual(std::wstring(L""), achievement.GetName()); + Assert::AreEqual(std::wstring(L""), achievement.GetTitle()); Assert::AreEqual(std::wstring(L""), achievement.GetDescription()); Assert::AreEqual(AssetCategory::Core, achievement.GetCategory()); Assert::AreEqual(AssetState::Inactive, achievement.GetState()); diff --git a/tests/devkit/data/models/AssetModelBase_Tests.cpp b/tests/devkit/data/models/AssetModelBase_Tests.cpp index 6be5d887e..865207653 100644 --- a/tests/devkit/data/models/AssetModelBase_Tests.cpp +++ b/tests/devkit/data/models/AssetModelBase_Tests.cpp @@ -37,7 +37,7 @@ TEST_CLASS(AssetModelBase_Tests) void Serialize(ra::services::TextWriter& pWriter) const override { - WriteQuoted(pWriter, GetName()); + WriteQuoted(pWriter, GetTitle()); WritePossiblyQuoted(pWriter, GetString()); WriteNumber(pWriter, GetInt()); WriteQuoted(pWriter, Utf8QuotedString); @@ -115,7 +115,7 @@ TEST_CLASS(AssetModelBase_Tests) Assert::AreEqual(AssetType::Achievement, asset.GetType()); Assert::AreEqual(0U, asset.GetID()); - Assert::AreEqual(std::wstring(L""), asset.GetName()); + Assert::AreEqual(std::wstring(L""), asset.GetTitle()); Assert::AreEqual(std::wstring(L""), asset.GetDescription()); Assert::AreEqual(AssetCategory::Core, asset.GetCategory()); Assert::AreEqual(AssetState::Inactive, asset.GetState()); @@ -215,7 +215,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsTrue(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(L"Name"), asset.GetName()); + Assert::AreEqual(std::wstring(L"Name"), asset.GetTitle()); Assert::AreEqual(std::wstring(L"String"), asset.GetString()); Assert::AreEqual(99U, asset.GetInt()); Assert::AreEqual(std::string("UTF-8-Quoted"), asset.Utf8QuotedString); @@ -231,7 +231,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsTrue(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(L"Mission: Impossible"), asset.GetName()); + Assert::AreEqual(std::wstring(L"Mission: Impossible"), asset.GetTitle()); Assert::AreEqual(std::wstring(L"Mission: Impossible"), asset.GetString()); Assert::AreEqual(0U, asset.GetInt()); Assert::AreEqual(std::string("Mission: Impossible"), asset.Utf8QuotedString); @@ -247,7 +247,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsTrue(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(L"A \"Test\" B"), asset.GetName()); + Assert::AreEqual(std::wstring(L"A \"Test\" B"), asset.GetTitle()); Assert::AreEqual(std::wstring(L"A \"Test\" B"), asset.GetString()); Assert::AreEqual(0U, asset.GetInt()); Assert::AreEqual(std::string("A \"Test\" B"), asset.Utf8QuotedString); @@ -263,7 +263,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsTrue(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(L"A\\B"), asset.GetName()); + Assert::AreEqual(std::wstring(L"A\\B"), asset.GetTitle()); Assert::AreEqual(std::wstring(L"A\\B"), asset.GetString()); Assert::AreEqual(0U, asset.GetInt()); Assert::AreEqual(std::string("A\\B"), asset.Utf8QuotedString); @@ -279,7 +279,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsFalse(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(L"A"), asset.GetName()); + Assert::AreEqual(std::wstring(L"A"), asset.GetTitle()); Assert::AreEqual(std::wstring(L"B"), asset.GetString()); Assert::AreEqual(0U, asset.GetInt()); Assert::AreEqual(std::string(), asset.Utf8QuotedString); @@ -295,7 +295,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsFalse(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(L"A"), asset.GetName()); + Assert::AreEqual(std::wstring(L"A"), asset.GetTitle()); Assert::AreEqual(std::wstring(L"B"), asset.GetString()); Assert::AreEqual(5U, asset.GetInt()); Assert::AreEqual(std::string("D"), asset.Utf8QuotedString); @@ -311,7 +311,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsFalse(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(), asset.GetName()); + Assert::AreEqual(std::wstring(), asset.GetTitle()); Assert::AreEqual(std::wstring(), asset.GetString()); Assert::AreEqual(0U, asset.GetInt()); Assert::AreEqual(std::string(), asset.Utf8QuotedString); @@ -327,7 +327,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon Assert::IsFalse(asset.Deserialize(pTokenizer)); - Assert::AreEqual(std::wstring(L"A"), asset.GetName()); + Assert::AreEqual(std::wstring(L"A"), asset.GetTitle()); Assert::AreEqual(std::wstring(), asset.GetString()); Assert::AreEqual(0U, asset.GetInt()); Assert::AreEqual(std::string(), asset.Utf8QuotedString); @@ -349,11 +349,11 @@ TEST_CLASS(AssetModelBase_Tests) asset.UpdateLocalCheckpoint(); Assert::AreEqual(AssetChanges::Unpublished, asset.GetChanges()); - Assert::AreEqual(std::wstring(L"LocalName"), asset.GetName()); + Assert::AreEqual(std::wstring(L"LocalName"), asset.GetTitle()); asset.UpdateServerCheckpoint(); Assert::AreEqual(AssetChanges::None, asset.GetChanges()); - Assert::AreEqual(std::wstring(L"LocalName"), asset.GetName()); + Assert::AreEqual(std::wstring(L"LocalName"), asset.GetTitle()); } TEST_METHOD(TestRestoreCheckpoint) @@ -372,14 +372,14 @@ TEST_CLASS(AssetModelBase_Tests) asset.RestoreLocalCheckpoint(); Assert::AreEqual(AssetChanges::Unpublished, asset.GetChanges()); - Assert::AreEqual(std::wstring(L"LocalName"), asset.GetName()); + Assert::AreEqual(std::wstring(L"LocalName"), asset.GetTitle()); asset.SetName(L"ModifiedName"); Assert::AreEqual(AssetChanges::Modified, asset.GetChanges()); asset.RestoreServerCheckpoint(); Assert::AreEqual(AssetChanges::None, asset.GetChanges()); - Assert::AreEqual(std::wstring(L"ServerName"), asset.GetName()); + Assert::AreEqual(std::wstring(L"ServerName"), asset.GetTitle()); } TEST_METHOD(TestUpdateDefinitionCheckpoint) @@ -470,7 +470,7 @@ TEST_CLASS(AssetModelBase_Tests) pTokenizer.Advance(); // skip leading colon asset.ResetLocalCheckpoint(pTokenizer); - Assert::AreEqual(std::wstring(L"Name"), asset.GetName()); + Assert::AreEqual(std::wstring(L"Name"), asset.GetTitle()); Assert::AreEqual(AssetChanges::Unpublished, asset.GetChanges()); } diff --git a/tests/data/context/GameAssets_Tests.cpp b/tests/devkit/data/models/GameAssets_Tests.cpp similarity index 94% rename from tests/data/context/GameAssets_Tests.cpp rename to tests/devkit/data/models/GameAssets_Tests.cpp index 1fab59896..f2be3c4a0 100644 --- a/tests/data/context/GameAssets_Tests.cpp +++ b/tests/devkit/data/models/GameAssets_Tests.cpp @@ -1,18 +1,16 @@ -#include "CppUnitTest.h" +#include "data/models/GameAssets.hh" -#include "data\context\GameAssets.hh" +#include "context/mocks/MockDevKitContext.hh" +#include "context/mocks/MockEmulatorMemoryContext.hh" +#include "context/mocks/MockGameContext.hh" +#include "context/mocks/MockRcClient.hh" -#include "data\models\AchievementModel.hh" -#include "data\models\LocalBadgesModel.hh" +#include "services/mocks/MockLocalStorage.hh" +#include "services/mocks/MockLogger.hh" -#include "tests\RA_UnitTestHelpers.h" -#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" -#include "tests\devkit\context\mocks\MockRcClient.hh" -#include "tests\devkit\services\mocks\MockLocalStorage.hh" -#include "tests\devkit\testutil\AssetAsserts.hh" -#include "tests\devkit\testutil\ValueAsserts.hh" -#include "tests\mocks\MockAchievementRuntime.hh" -#include "tests\mocks\MockGameContext.hh" +#include "testutil/AssetAsserts.hh" +#include "testutil/CppUnitTest.hh" +#include "testutil/ValueAsserts.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -22,7 +20,7 @@ using ra::data::models::AssetType; namespace ra { namespace data { -namespace context { +namespace models { namespace tests { TEST_CLASS(GameAssets_Tests) @@ -31,16 +29,21 @@ TEST_CLASS(GameAssets_Tests) class GameAssetsHarness : public GameAssets { public: + ra::context::mocks::MockDevKitContext mockDevKitContext; ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + ra::context::mocks::MockGameContext mockGameContext; ra::context::mocks::MockRcClient mockRcClient; - ra::data::context::mocks::MockGameContext mockGameContext; - ra::services::mocks::MockAchievementRuntime mockRuntime; ra::services::mocks::MockLocalStorage mockLocalStorage; + ra::services::mocks::MockLogger mockLogger; GameAssetsHarness() noexcept { - GSL_SUPPRESS_F6 mockGameContext.SetGameTitle(L"GameName"); - GSL_SUPPRESS_F6 mockRuntime.MockGame(); + mockGameContext.SetGameTitle(L"Game Title"); + mockGameContext.SetGameId(2U); + + auto vmAchievementSet = std::make_unique(); + vmAchievementSet->Initialize(2U, 3U, L"Game Title", ra::data::models::AchievementSetType::Core); + m_vAchievementSets.Append(std::move(vmAchievementSet)); } void SaveAllAssets() @@ -156,19 +159,6 @@ TEST_CLASS(GameAssets_Tests) return mockLocalStorage.GetStoredData(ra::services::StorageItemType::UserAchievements, std::to_wstring(mockGameContext.GameId())); } - void AddLocalBadgesModel() - { - auto pLocalBadges = std::make_unique(); - pLocalBadges->CreateServerCheckpoint(); - pLocalBadges->CreateLocalCheckpoint(); - mockGameContext.Assets().Append(std::move(pLocalBadges)); - } - - ra::data::models::LocalBadgesModel& GetLocalBadgesModel() - { - return *(dynamic_cast(mockGameContext.Assets().FindAsset(ra::data::models::AssetType::LocalBadges, 0))); - } - void AddRichPresenceModel() { auto pRichPresence = std::make_unique(); @@ -244,11 +234,10 @@ TEST_CLASS(GameAssets_Tests) { GameAssetsHarness gameAssets; gameAssets.mockGameContext.SetGameId(22); - gameAssets.AddLocalBadgesModel(); gameAssets.AddNewAchievement(10, L"Temp", L"Temp", L"local\\22-ABCDE.png", "1=1"); // gameAssets is not the same instance as mockGameContext.Assets, so manually update the badge reference count - auto& pLocalBadges = gameAssets.GetLocalBadgesModel(); + auto& pLocalBadges = gameAssets.mockGameContext.LocalBadges(); pLocalBadges.AddReference(L"local\\22-ABCDE.png", false); // simulate the pre-commit of the achievement by converting the reference from uncommitted to committed @@ -453,7 +442,6 @@ TEST_CLASS(GameAssets_Tests) { GameAssetsHarness gameAssets; gameAssets.mockGameContext.SetGameId(22); - gameAssets.AddLocalBadgesModel(); gameAssets.MockUserFileContents( "111000001:\"0xH2345=0\":Test2:::::User:0:0:0:::local\\22-A.png\n"); @@ -464,7 +452,7 @@ TEST_CLASS(GameAssets_Tests) Ensures(pAsset != nullptr); Assert::AreEqual(std::wstring(L"local\\22-A.png"), pAsset->GetBadge()); - const auto& pLocalBadges = gameAssets.GetLocalBadgesModel(); + const auto& pLocalBadges = gameAssets.mockGameContext.LocalBadges(); Assert::AreEqual(1, pLocalBadges.GetReferenceCount(L"local\\22-A.png", true)); } @@ -485,7 +473,7 @@ TEST_CLASS(GameAssets_Tests) Ensures(pAsset != nullptr); Assert::AreEqual(std::string("0xH1234=0"), pAsset->GetTrigger()); Assert::AreEqual(AssetCategory::Local, pAsset->GetCategory()); - Assert::AreEqual(0U, pAsset->GetSubsetID()); + Assert::AreEqual(2U, pAsset->GetSubsetID()); Assert::AreEqual(AssetChanges::Unpublished, pAsset->GetChanges()); const auto* pAsset2 = gameAssets.FindAchievement({111000002U}); @@ -619,7 +607,7 @@ TEST_CLASS(GameAssets_Tests) const auto* pAsset2 = gameAssets.FindAchievement({ 1U }); Assert::IsNotNull(pAsset2); Ensures(pAsset2 != nullptr); - Assert::AreEqual(std::wstring(L"Server"), pAsset2->GetName()); + Assert::AreEqual(std::wstring(L"Server"), pAsset2->GetTitle()); Assert::AreEqual(AssetCategory::Core, pAsset2->GetCategory()); Assert::AreEqual(AssetChanges::None, pAsset2->GetChanges()); } @@ -646,7 +634,7 @@ TEST_CLASS(GameAssets_Tests) const auto* pAsset2 = gameAssets.FindAchievement({ 1U }); Assert::IsNotNull(pAsset2); Ensures(pAsset2 != nullptr); - Assert::AreEqual(std::wstring(L"Server"), pAsset2->GetName()); + Assert::AreEqual(std::wstring(L"Server"), pAsset2->GetTitle()); Assert::AreEqual(AssetCategory::Core, pAsset2->GetCategory()); Assert::AreEqual(AssetChanges::None, pAsset2->GetChanges()); } @@ -812,6 +800,6 @@ TEST_CLASS(GameAssets_Tests) }; } // namespace tests -} // namespace context +} // namespace models } // namespace data } // namespace ra diff --git a/tests/devkit/data/models/LeaderboardModel_Tests.cpp b/tests/devkit/data/models/LeaderboardModel_Tests.cpp index 1a34288c2..3a41f130c 100644 --- a/tests/devkit/data/models/LeaderboardModel_Tests.cpp +++ b/tests/devkit/data/models/LeaderboardModel_Tests.cpp @@ -42,7 +42,7 @@ TEST_CLASS(LeaderboardModel_Tests) Assert::AreEqual(AssetType::Leaderboard, leaderboard.GetType()); Assert::AreEqual(0U, leaderboard.GetID()); - Assert::AreEqual(std::wstring(L""), leaderboard.GetName()); + Assert::AreEqual(std::wstring(L""), leaderboard.GetTitle()); Assert::AreEqual(std::wstring(L""), leaderboard.GetDescription()); Assert::AreEqual(AssetCategory::Core, leaderboard.GetCategory()); Assert::AreEqual(AssetState::Inactive, leaderboard.GetState()); @@ -68,7 +68,7 @@ TEST_CLASS(LeaderboardModel_Tests) Assert::AreEqual(std::string("0xH1234=3"), leaderboard.GetSubmitTrigger()); Assert::AreEqual(std::string("0xH1234"), leaderboard.GetValueDefinition()); Assert::AreEqual(Value::Format::Frames, leaderboard.GetValueFormat()); - Assert::AreEqual(std::wstring(L"Title"), leaderboard.GetName()); + Assert::AreEqual(std::wstring(L"Title"), leaderboard.GetTitle()); Assert::AreEqual(std::wstring(L"Desc"), leaderboard.GetDescription()); Assert::IsFalse(leaderboard.IsLowerBetter()); } @@ -88,7 +88,7 @@ TEST_CLASS(LeaderboardModel_Tests) Assert::AreEqual(std::string("0xH1234>3"), leaderboard.GetSubmitTrigger()); Assert::AreEqual(std::string("M:0xH1234"), leaderboard.GetValueDefinition()); Assert::AreEqual(Value::Format::Centiseconds, leaderboard.GetValueFormat()); - Assert::AreEqual(std::wstring(L"My Title"), leaderboard.GetName()); + Assert::AreEqual(std::wstring(L"My Title"), leaderboard.GetTitle()); Assert::AreEqual(std::wstring(L"My Desc"), leaderboard.GetDescription()); Assert::IsTrue(leaderboard.IsLowerBetter()); } @@ -108,7 +108,7 @@ TEST_CLASS(LeaderboardModel_Tests) Assert::AreEqual(std::string("0xH1234=3"), leaderboard.GetSubmitTrigger()); Assert::AreEqual(std::string("0xH1234"), leaderboard.GetValueDefinition()); Assert::AreEqual(Value::Format::Frames, leaderboard.GetValueFormat()); - Assert::AreEqual(std::wstring(L"Title"), leaderboard.GetName()); + Assert::AreEqual(std::wstring(L"Title"), leaderboard.GetTitle()); Assert::AreEqual(std::wstring(L"Desc"), leaderboard.GetDescription()); Assert::IsFalse(leaderboard.IsLowerBetter()); } @@ -128,7 +128,7 @@ TEST_CLASS(LeaderboardModel_Tests) Assert::AreEqual(std::string(), leaderboard.GetSubmitTrigger()); Assert::AreEqual(std::string(), leaderboard.GetValueDefinition()); Assert::AreEqual(Value::Format::Value, leaderboard.GetValueFormat()); - Assert::AreEqual(std::wstring(), leaderboard.GetName()); + Assert::AreEqual(std::wstring(), leaderboard.GetTitle()); Assert::AreEqual(std::wstring(), leaderboard.GetDescription()); Assert::IsFalse(leaderboard.IsLowerBetter()); } diff --git a/tests/devkit/data/models/LocalBadgesModel_Tests.cpp b/tests/devkit/data/models/LocalBadgesModel_Tests.cpp index 9e4f6a789..4aeca85df 100644 --- a/tests/devkit/data/models/LocalBadgesModel_Tests.cpp +++ b/tests/devkit/data/models/LocalBadgesModel_Tests.cpp @@ -34,7 +34,7 @@ TEST_CLASS(LocalBadgesModel_Tests) Assert::AreEqual(AssetType::LocalBadges, badges.GetType()); Assert::AreEqual(0U, badges.GetID()); - Assert::AreEqual(std::wstring(L"Local Badges"), badges.GetName()); + Assert::AreEqual(std::wstring(L"Local Badges"), badges.GetTitle()); Assert::AreEqual(std::wstring(L""), badges.GetDescription()); Assert::AreEqual(AssetCategory::Local, badges.GetCategory()); Assert::AreEqual(AssetState::Inactive, badges.GetState()); diff --git a/tests/devkit/data/models/MemoryNotesModel_Tests.cpp b/tests/devkit/data/models/MemoryNotesModel_Tests.cpp index 349d07f2d..3fc2c1b59 100644 --- a/tests/devkit/data/models/MemoryNotesModel_Tests.cpp +++ b/tests/devkit/data/models/MemoryNotesModel_Tests.cpp @@ -194,7 +194,7 @@ TEST_CLASS(MemoryNotesModel_Tests) Assert::AreEqual(AssetType::MemoryNotes, notes.GetType()); Assert::AreEqual(0U, notes.GetID()); - Assert::AreEqual(std::wstring(L"Memory Notes"), notes.GetName()); + Assert::AreEqual(std::wstring(L"Memory Notes"), notes.GetTitle()); Assert::AreEqual(std::wstring(L""), notes.GetDescription()); Assert::AreEqual(AssetCategory::Core, notes.GetCategory()); Assert::AreEqual(AssetState::Inactive, notes.GetState()); diff --git a/tests/devkit/data/models/MemoryRegionsModel_Tests.cpp b/tests/devkit/data/models/MemoryRegionsModel_Tests.cpp index 5a2d13f6f..9348545cc 100644 --- a/tests/devkit/data/models/MemoryRegionsModel_Tests.cpp +++ b/tests/devkit/data/models/MemoryRegionsModel_Tests.cpp @@ -51,7 +51,7 @@ TEST_CLASS(MemoryRegionsModel_Tests) Assert::AreEqual(AssetType::MemoryRegions, regions.GetType()); Assert::AreEqual(0U, regions.GetID()); - Assert::AreEqual(std::wstring(L"Memory Regions"), regions.GetName()); + Assert::AreEqual(std::wstring(L"Memory Regions"), regions.GetTitle()); Assert::AreEqual(std::wstring(L""), regions.GetDescription()); Assert::AreEqual(AssetCategory::Core, regions.GetCategory()); Assert::AreEqual(AssetState::Inactive, regions.GetState()); diff --git a/tests/devkit/data/models/RichPresenceModel_Tests.cpp b/tests/devkit/data/models/RichPresenceModel_Tests.cpp index 40195d5cc..68825b7e7 100644 --- a/tests/devkit/data/models/RichPresenceModel_Tests.cpp +++ b/tests/devkit/data/models/RichPresenceModel_Tests.cpp @@ -39,7 +39,7 @@ TEST_CLASS(RichPresenceModel_Tests) Assert::AreEqual(AssetType::RichPresence, richPresence.GetType()); Assert::AreEqual(0U, richPresence.GetID()); - Assert::AreEqual(std::wstring(L"Rich Presence"), richPresence.GetName()); + Assert::AreEqual(std::wstring(L"Rich Presence"), richPresence.GetTitle()); Assert::AreEqual(std::wstring(L""), richPresence.GetDescription()); Assert::AreEqual(AssetCategory::Core, richPresence.GetCategory()); Assert::AreEqual(AssetState::Inactive, richPresence.GetState()); diff --git a/tests/devkit/services/mocks/MockLogger.hh b/tests/devkit/services/mocks/MockLogger.hh index bd11834aa..94f028d1f 100644 --- a/tests/devkit/services/mocks/MockLogger.hh +++ b/tests/devkit/services/mocks/MockLogger.hh @@ -5,7 +5,7 @@ #include "services/ILogger.hh" #include "services/ServiceLocator.hh" -#include "testutil/CppUnitTest.hh" +#include "tests/devkit/testutil/CppUnitTest.hh" namespace ra { namespace services { diff --git a/tests/devkit/testutil/AchievementSetAsserts.hh b/tests/devkit/testutil/AchievementSetAsserts.hh new file mode 100644 index 000000000..894e73634 --- /dev/null +++ b/tests/devkit/testutil/AchievementSetAsserts.hh @@ -0,0 +1,44 @@ +#ifndef RA_ACHIEVEMENTSET_ASSERTS_H +#define RA_ACHIEVEMENTSET_ASSERTS_H +#pragma once + +#include "CppUnitTest.hh" + +#include "data/models/AchievementSetModel.hh" + +#include "util/TypeCasts.hh" + +namespace Microsoft { +namespace VisualStudio { +namespace CppUnitTestFramework { + +// converters for asserting enum values + +#pragma warning(push) +#pragma warning(disable : 4505) // unreferenced inline functions, they are referenced. Must be a bug. + +template<> +std::wstring ToString(const ra::data::models::AchievementSetType& t) +{ + switch (t) + { + case ra::data::models::AchievementSetType::Core: + return L"Core"; + case ra::data::models::AchievementSetType::Bonus: + return L"Bonus"; + case ra::data::models::AchievementSetType::Specialty: + return L"Specialty"; + case ra::data::models::AchievementSetType::Exclusive: + return L"Exclusive"; + default: + return std::to_wstring(static_cast(t)); + } +} + +#pragma warning(pop) + +} // namespace CppUnitTestFramework +} // namespace VisualStudio +} // namespace Microsoft + +#endif /* !RA_ACHIEVEMENTSET_ASSERTS_H */ diff --git a/tests/devkit/testutil/LeaderboardAsserts.hh b/tests/devkit/testutil/LeaderboardAsserts.hh new file mode 100644 index 000000000..b501c0c48 --- /dev/null +++ b/tests/devkit/testutil/LeaderboardAsserts.hh @@ -0,0 +1,46 @@ +#ifndef RA_LEADERBOARD_ASSERTS_H +#define RA_LEADERBOARD_ASSERTS_H +#pragma once + +#include "CppUnitTest.hh" + +#include "data/models/LeaderboardModel.hh" + +#include "util/TypeCasts.hh" + +namespace Microsoft { +namespace VisualStudio { +namespace CppUnitTestFramework { + +// converters for asserting enum values + +#pragma warning(push) +#pragma warning(disable : 4505) // unreferenced inline functions, they are referenced. Must be a bug. + +template<> +std::wstring ToString(const ra::data::models::LeaderboardModel::LeaderboardParts& t) +{ + switch (t) + { + case ra::data::models::LeaderboardModel::LeaderboardParts::None: + return L"None"; + case ra::data::models::LeaderboardModel::LeaderboardParts::Start: + return L"Start"; + case ra::data::models::LeaderboardModel::LeaderboardParts::Submit: + return L"Submit"; + case ra::data::models::LeaderboardModel::LeaderboardParts::Cancel: + return L"Cancel"; + case ra::data::models::LeaderboardModel::LeaderboardParts::Value: + return L"Value"; + default: + return std::to_wstring(static_cast(t)); + } +} + +#pragma warning(pop) + +} // namespace CppUnitTestFramework +} // namespace VisualStudio +} // namespace Microsoft + +#endif /* !RA_LEADERBOARD_ASSERTS_H */ diff --git a/tests/mocks/MockAchievementRuntime.cpp b/tests/mocks/MockAchievementRuntime.cpp index f965a1d15..ea46d07de 100644 --- a/tests/mocks/MockAchievementRuntime.cpp +++ b/tests/mocks/MockAchievementRuntime.cpp @@ -7,7 +7,7 @@ #include "CppUnitTest.h" #include "util\Strings.hh" -#include "data\context\GameAssets.hh" +#include "data\models\GameAssets.hh" #include #include @@ -46,7 +46,7 @@ void MockAchievementRuntime::MockGame() auto* mockGameContext = dynamic_cast( &ra::services::ServiceLocator::GetMutable()); if (mockGameContext != nullptr) - mockGameContext->MockSubset(0, game->public_.title, ra::data::context::GameContext::SubsetType::Core); + mockGameContext->MockSubset(game->public_.id, game->public_.title, ra::data::models::AchievementSetType::Core); } } @@ -82,7 +82,7 @@ static rc_client_subset_info_t* GetCoreSubset(rc_client_game_info_t* game) static rc_client_subset_info_t* GetLocalSubset(rc_client_game_info_t* game) { Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsNotNull(game, L"MockGame must be called first"); - return GetSubset(game, ra::data::context::GameAssets::LocalSubsetId, "Local"); + return GetSubset(game, ra::data::models::AchievementSetModel::LocalId, "Local"); } static rc_client_achievement_info_t* AddAchievement(rc_client_game_info_t* game, diff --git a/tests/mocks/MockGameContext.hh b/tests/mocks/MockGameContext.hh index 9ce11bfae..7a080d014 100644 --- a/tests/mocks/MockGameContext.hh +++ b/tests/mocks/MockGameContext.hh @@ -38,10 +38,12 @@ public: { m_nGameId = m_nActiveGameId = nGameId; - if (!m_vSubsets.empty()) + // MockRuntime may have populated an AchievementSet. Update it too + auto* pPrimarySet = const_cast(Assets().AchievementSets().GetItemAt(0)); + if (pPrimarySet) { - const auto& pSubset = m_vSubsets.front(); - m_vSubsets.front() = Subset(nGameId, nGameId, pSubset.Title(), pSubset.Type()); + pPrimarySet->SetID(nGameId); + pPrimarySet->SetBackingGameID(nGameId); } } void SetActiveGameId(unsigned int nGameId) noexcept { m_nActiveGameId = nGameId; } @@ -149,14 +151,17 @@ public: GSL_SUPPRESS_C128 void InitializeFromAchievementRuntime(); - void MockSubset(uint32_t nSubsetId, const std::string& sName, SubsetType nType = SubsetType::Bonus) + void MockSubset(uint32_t nSubsetId, const std::string& sName, ra::data::models::AchievementSetType nType = ra::data::models::AchievementSetType::Bonus) { MockSubset(nSubsetId, nSubsetId, sName, nType); } - void MockSubset(uint32_t nGameId, uint32_t nAchievementSetId, const std::string& sName, SubsetType nType = SubsetType::Bonus) + void MockSubset(uint32_t nGameId, uint32_t nAchievementSetId, const std::string& sName, ra::data::models::AchievementSetType nType = ra::data::models::AchievementSetType::Bonus) { - m_vSubsets.emplace_back(nAchievementSetId, nGameId, ra::util::String::Widen(sName), nType); + auto& vAchievementSets = const_cast&>(Assets().AchievementSets()); + auto vmAchievementSet = std::make_unique(); + vmAchievementSet->Initialize(nAchievementSetId, nGameId, ra::util::String::Widen(sName), nType); + vAchievementSets.Append(std::move(vmAchievementSet)); } private: diff --git a/tests/services/AchievementRuntime_Tests.cpp b/tests/services/AchievementRuntime_Tests.cpp index 0a8c9ceba..c36b668fb 100644 --- a/tests/services/AchievementRuntime_Tests.cpp +++ b/tests/services/AchievementRuntime_Tests.cpp @@ -232,7 +232,7 @@ class AchievementRuntimeHarness : public AchievementRuntime { if (&pSubset->achievements[i] == pAchievement) { - if (pSubset->public_.id == ra::data::context::GameAssets::LocalSubsetId) + if (pSubset->public_.id == ra::data::models::AchievementSetModel::LocalId) nCategory = ra::data::models::AssetCategory::Local; vmAchievement->SetSubsetID(pSubset->public_.id); @@ -315,7 +315,7 @@ class AchievementRuntimeHarness : public AchievementRuntime { if (&pSubset->leaderboards[i] == pLeaderboard) { - if (pSubset->public_.id == ra::data::context::GameAssets::LocalSubsetId) + if (pSubset->public_.id == ra::data::models::AchievementSetModel::LocalId) nCategory = ra::data::models::AssetCategory::Local; break; } @@ -445,7 +445,7 @@ class AchievementRuntimeHarness : public AchievementRuntime static rc_client_subset_info_t* GetLocalSubset(rc_client_game_info_t* game) noexcept { - return GetSubset(game, ra::data::context::GameAssets::LocalSubsetId, "Local"); + return GetSubset(game, ra::data::models::AchievementSetModel::LocalId, "Local"); } static rc_client_achievement_info_t* AddAchievement(rc_client_game_info_t* game, rc_client_subset_info_t* subset, @@ -549,7 +549,7 @@ TEST_CLASS(AchievementRuntime_Tests) vmAchievement->SetDescription(L"Do something cool"); vmAchievement->SetPoints(25); vmAchievement->SetTrigger("0xH0000=1"); - vmAchievement->SetID(ra::data::context::GameAssets::FirstLocalId); + vmAchievement->SetID(ra::data::models::GameAssets::FirstLocalId); vmAchievement->SetBadge(L"local\\ABCDEF0123456789.png"); vmAchievement->CreateLocalCheckpoint(); vmAchievement->SetState(ra::data::models::AssetState::Active); @@ -570,7 +570,7 @@ TEST_CLASS(AchievementRuntime_Tests) pSubset = pSubset->next; Expects(pSubset != nullptr); Assert::AreEqual("Local", pSubset->public_.title); - Assert::AreEqual(ra::data::context::GameAssets::LocalSubsetId, pSubset->public_.id); + Assert::AreEqual(ra::data::models::AchievementSetModel::LocalId, pSubset->public_.id); Assert::AreEqual("012345", pSubset->public_.badge_name); Assert::AreEqual(1U, pSubset->public_.num_achievements); Assert::IsTrue(pSubset->active); @@ -580,7 +580,7 @@ TEST_CLASS(AchievementRuntime_Tests) Assert::AreEqual("Achievement Name", pAchievement->public_.title); Assert::AreEqual("Do something cool", pAchievement->public_.description); Assert::AreEqual(25U, pAchievement->public_.points); - Assert::AreEqual(ra::data::context::GameAssets::FirstLocalId, pAchievement->public_.id); + Assert::AreEqual(ra::data::models::GameAssets::FirstLocalId, pAchievement->public_.id); Assert::AreEqual("L69db9c", pAchievement->public_.badge_name); // FirstLocalId as hex Assert::AreEqual("file://RACache/Badges/local/ABCDEF0123456789.png", pAchievement->public_.badge_url); Assert::AreEqual("file://RACache/Badges/local/ABCDEF0123456789.png", pAchievement->public_.badge_locked_url); @@ -588,7 +588,7 @@ TEST_CLASS(AchievementRuntime_Tests) const auto* pOldTrigger = pAchievement->trigger; // directly modifying the achievement trigger should rebuild the underlying trigger - runtime.mockGameContext.Assets().FindAchievement(ra::data::context::GameAssets::FirstLocalId) + runtime.mockGameContext.Assets().FindAchievement(ra::data::models::GameAssets::FirstLocalId) ->SetTrigger("0xH0000=2"); Assert::IsNotNull(pAchievement->trigger); const auto* pNewTrigger = pAchievement->trigger; @@ -605,7 +605,7 @@ TEST_CLASS(AchievementRuntime_Tests) vmAchievement2->SetDescription(L"Do something cool"); vmAchievement2->SetPoints(25); vmAchievement2->SetTrigger("0xH0000=2"); - vmAchievement2->SetID(ra::data::context::GameAssets::FirstLocalId); + vmAchievement2->SetID(ra::data::models::GameAssets::FirstLocalId); vmAchievement2->CreateLocalCheckpoint(); vmAchievement2->SetState(ra::data::models::AssetState::Active); vmAchievement2->SetSubsetID(1U); @@ -629,7 +629,7 @@ TEST_CLASS(AchievementRuntime_Tests) vmAchievement3->SetDescription(L"Do something cool"); vmAchievement3->SetPoints(25); vmAchievement3->SetTrigger("0xH0000=1"); - vmAchievement3->SetID(ra::data::context::GameAssets::FirstLocalId); + vmAchievement3->SetID(ra::data::models::GameAssets::FirstLocalId); vmAchievement3->CreateLocalCheckpoint(); vmAchievement3->SetState(ra::data::models::AssetState::Active); vmAchievement3->SetSubsetID(1U); @@ -678,7 +678,7 @@ TEST_CLASS(AchievementRuntime_Tests) Assert::IsNotNull(pSubset->next); // there will be an inactive local subset const auto* pOriginalTrigger = pSubset->achievements->trigger; - Assert::AreEqual(std::wstring(L"Achievement Name"), vmAchievement.GetName()); + Assert::AreEqual(std::wstring(L"Achievement Name"), vmAchievement.GetTitle()); Assert::AreEqual(std::wstring(L"Do something cool"), vmAchievement.GetDescription()); Assert::AreEqual(25, vmAchievement.GetPoints()); Assert::AreEqual(12345U, vmAchievement.GetID()); diff --git a/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp b/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp index ff0d4fc20..7b3e7b07d 100644 --- a/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp @@ -17,7 +17,9 @@ #include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" +#include "tests\devkit\testutil\AchievementAsserts.hh" #include "tests\devkit\testutil\AssetAsserts.hh" +#include "tests\devkit\testutil\LeaderboardAsserts.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\devkit\testutil\ValueAsserts.hh" #include "tests\devkit\ui\mocks\MockImageRepository.hh" @@ -127,7 +129,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Achievement Editor"), editor.GetWindowTitle()); Assert::AreEqual(0U, editor.GetID()); - Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetName()); + Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Open an achievement from the Achievements List"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Core, editor.GetCategory()); Assert::AreEqual(AssetState::Inactive, editor.GetState()); @@ -216,7 +218,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Achievement Editor"), editor.GetWindowTitle()); Assert::AreEqual(1234U, editor.GetID()); - Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetName()); + Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Do something cool"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Unofficial, editor.GetCategory()); Assert::AreEqual(AssetState::Active, editor.GetState()); @@ -237,7 +239,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Achievement Editor"), editor.GetWindowTitle()); Assert::AreEqual(0U, editor.GetID()); - Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetName()); + Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Open an achievement from the Achievements List"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Core, editor.GetCategory()); Assert::AreEqual(AssetState::Inactive, editor.GetState()); @@ -321,7 +323,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) bMessageSeen = false; Assert::AreEqual(1234U, editor.GetID()); - Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetName()); + Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Do something modified"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Unofficial, editor.GetCategory()); Assert::AreEqual(AssetState::Active, editor.GetState()); @@ -337,7 +339,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) bMessageSeen = false; Assert::AreEqual(1234U, editor.GetID()); - Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetName()); + Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Do something modified"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Unofficial, editor.GetCategory()); Assert::AreEqual(AssetState::Active, editor.GetState()); @@ -359,7 +361,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::IsTrue(bMessageSeen); Assert::AreEqual(2345U, editor.GetID()); - Assert::AreEqual(std::wstring(L"Test Achievement 2"), editor.GetName()); + Assert::AreEqual(std::wstring(L"Test Achievement 2"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Do something else"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Unofficial, editor.GetCategory()); Assert::AreEqual(AssetState::Waiting, editor.GetState()); @@ -441,7 +443,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Achievement Editor"), editor.GetWindowTitle()); Assert::AreEqual(1234U, editor.GetID()); - Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetName()); + Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Do something cool"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Unofficial, editor.GetCategory()); Assert::AreEqual(AssetState::Active, editor.GetState()); @@ -457,7 +459,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Achievement Editor"), editor.GetWindowTitle()); Assert::AreEqual(0U, editor.GetID()); - Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetName()); + Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Open an achievement from the Achievements List"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Core, editor.GetCategory()); Assert::AreEqual(AssetState::Inactive, editor.GetState()); @@ -699,7 +701,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Leaderboard Editor"), editor.GetWindowTitle()); Assert::AreEqual(1234U, editor.GetID()); - Assert::AreEqual(std::wstring(L"Test Leaderboard"), editor.GetName()); + Assert::AreEqual(std::wstring(L"Test Leaderboard"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Do something cool"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Unofficial, editor.GetCategory()); Assert::AreEqual(AssetState::Active, editor.GetState()); @@ -720,7 +722,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Achievement Editor"), editor.GetWindowTitle()); Assert::AreEqual(0U, editor.GetID()); - Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetName()); + Assert::AreEqual(std::wstring(L"[No Achievement Loaded]"), editor.GetTitle()); Assert::AreEqual(std::wstring(L"Open an achievement from the Achievements List"), editor.GetDescription()); Assert::AreEqual(AssetCategory::Core, editor.GetCategory()); Assert::AreEqual(AssetState::Inactive, editor.GetState()); @@ -764,7 +766,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) Assert::AreEqual(std::wstring(L"Leaderboard Editor"), editor.GetWindowTitle()); Assert::AreEqual(0U, editor.GetID()); - Assert::AreEqual(std::wstring(L""), editor.GetName()); + Assert::AreEqual(std::wstring(L""), editor.GetTitle()); Assert::AreEqual(std::wstring(L""), editor.GetDescription()); Assert::AreEqual(AssetCategory::Local, editor.GetCategory()); Assert::AreEqual(AssetState::Inactive, editor.GetState()); @@ -880,20 +882,20 @@ TEST_CLASS(AssetEditorViewModel_Tests) achievement.CreateLocalCheckpoint(); editor.LoadAsset(&achievement); - Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetName()); - Assert::AreEqual(std::wstring(L"Test Achievement"), achievement.GetName()); + Assert::AreEqual(std::wstring(L"Test Achievement"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"Test Achievement"), achievement.GetTitle()); editor.SetName(L"New Name"); - Assert::AreEqual(std::wstring(L"New Name"), editor.GetName()); - Assert::AreEqual(std::wstring(L"New Name"), achievement.GetName()); + Assert::AreEqual(std::wstring(L"New Name"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name"), achievement.GetTitle()); editor.SetName(L"New Name 2"); - Assert::AreEqual(std::wstring(L"New Name 2"), editor.GetName()); - Assert::AreEqual(std::wstring(L"New Name 2"), achievement.GetName()); + Assert::AreEqual(std::wstring(L"New Name 2"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name 2"), achievement.GetTitle()); achievement.SetName(L"New Name 3"); - Assert::AreEqual(std::wstring(L"New Name 3"), editor.GetName()); - Assert::AreEqual(std::wstring(L"New Name 3"), achievement.GetName()); + Assert::AreEqual(std::wstring(L"New Name 3"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name 3"), achievement.GetTitle()); } TEST_METHOD(TestSyncDescription) @@ -1319,29 +1321,29 @@ TEST_CLASS(AssetEditorViewModel_Tests) achievement2.CreateLocalCheckpoint(); editor.LoadAsset(&achievement1); - Assert::AreEqual(std::wstring(L"Achievement1"), editor.GetName()); - Assert::AreEqual(std::wstring(L"Achievement1"), achievement1.GetName()); - Assert::AreEqual(std::wstring(L"Achievement2"), achievement2.GetName()); + Assert::AreEqual(std::wstring(L"Achievement1"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"Achievement1"), achievement1.GetTitle()); + Assert::AreEqual(std::wstring(L"Achievement2"), achievement2.GetTitle()); editor.SetName(L"New Name"); - Assert::AreEqual(std::wstring(L"New Name"), editor.GetName()); - Assert::AreEqual(std::wstring(L"New Name"), achievement1.GetName()); - Assert::AreEqual(std::wstring(L"Achievement2"), achievement2.GetName()); + Assert::AreEqual(std::wstring(L"New Name"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name"), achievement1.GetTitle()); + Assert::AreEqual(std::wstring(L"Achievement2"), achievement2.GetTitle()); editor.LoadAsset(&achievement2); - Assert::AreEqual(std::wstring(L"Achievement2"), editor.GetName()); - Assert::AreEqual(std::wstring(L"New Name"), achievement1.GetName()); - Assert::AreEqual(std::wstring(L"Achievement2"), achievement2.GetName()); + Assert::AreEqual(std::wstring(L"Achievement2"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name"), achievement1.GetTitle()); + Assert::AreEqual(std::wstring(L"Achievement2"), achievement2.GetTitle()); editor.SetName(L"New Name 2"); - Assert::AreEqual(std::wstring(L"New Name 2"), editor.GetName()); - Assert::AreEqual(std::wstring(L"New Name"), achievement1.GetName()); - Assert::AreEqual(std::wstring(L"New Name 2"), achievement2.GetName()); + Assert::AreEqual(std::wstring(L"New Name 2"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name"), achievement1.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name 2"), achievement2.GetTitle()); achievement1.SetName(L"New Name 3"); - Assert::AreEqual(std::wstring(L"New Name 2"), editor.GetName()); - Assert::AreEqual(std::wstring(L"New Name 3"), achievement1.GetName()); - Assert::AreEqual(std::wstring(L"New Name 2"), achievement2.GetName()); + Assert::AreEqual(std::wstring(L"New Name 2"), editor.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name 3"), achievement1.GetTitle()); + Assert::AreEqual(std::wstring(L"New Name 2"), achievement2.GetTitle()); } TEST_METHOD(TestUpdateActiveTrigger) diff --git a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp index e4a45f1ec..c183d83f5 100644 --- a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp +++ b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp @@ -14,13 +14,16 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockDevKitContext.hh" #include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\context\mocks\MockUserContext.hh" #include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\services\mocks\MockLocalStorage.hh" +#include "tests\devkit\services\mocks\MockLogger.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" +#include "tests\devkit\testutil\AchievementAsserts.hh" #include "tests\devkit\testutil\AssetAsserts.hh" #include "tests\devkit\testutil\ValueAsserts.hh" #include "tests\devkit\ui\mocks\MockImageRepository.hh" @@ -164,6 +167,7 @@ TEST_CLASS(AssetListViewModel_Tests) class AssetListViewModelHarness : public AssetListViewModel { public: + ra::context::mocks::MockDevKitContext mockDevKitContext; ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::context::mocks::MockUserContext mockUserContext; @@ -172,6 +176,7 @@ TEST_CLASS(AssetListViewModel_Tests) ra::services::mocks::MockConfiguration mockConfiguration; ra::services::mocks::MockThreadPool mockThreadPool; ra::services::mocks::MockLocalStorage mockLocalStorage; + ra::services::mocks::MockLogger mockLogger; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::ui::mocks::MockDesktop mockDesktop; @@ -593,7 +598,7 @@ TEST_CLASS(AssetListViewModel_Tests) { const auto pIter = m_mValidationErrors.find(pAchievement.GetID()); if (pIter != m_mValidationErrors.end()) - sError.append(ra::util::String::Printf(L"\n* %s: %s", pAchievement.GetName(), pIter->second)); + sError.append(ra::util::String::Printf(L"\n* %s: %s", pAchievement.GetTitle(), pIter->second)); } } @@ -1277,11 +1282,11 @@ TEST_CLASS(AssetListViewModel_Tests) vmAssetList.mockRuntime.SyncAssets(); vmAssetList.mockGameContext.NotifyActiveGameChanged(); - Assert::AreEqual({2U}, vmAssetList.Subsets().Count()); - Assert::AreEqual({22U}, vmAssetList.Subsets().GetItemAt(0)->GetId()); - Assert::AreEqual(std::wstring(L"Game Title"), vmAssetList.Subsets().GetItemAt(0)->GetLabel()); - Assert::AreEqual({555U}, vmAssetList.Subsets().GetItemAt(1)->GetId()); - Assert::AreEqual(std::wstring(L"Bonus"), vmAssetList.Subsets().GetItemAt(1)->GetLabel()); + Assert::AreEqual({2U}, vmAssetList.AchievementSets().Count()); + Assert::AreEqual({22U}, vmAssetList.AchievementSets().GetItemAt(0)->GetId()); + Assert::AreEqual(std::wstring(L"Game Title"), vmAssetList.AchievementSets().GetItemAt(0)->GetLabel()); + Assert::AreEqual({555U}, vmAssetList.AchievementSets().GetItemAt(1)->GetId()); + Assert::AreEqual(std::wstring(L"Bonus"), vmAssetList.AchievementSets().GetItemAt(1)->GetLabel()); Assert::AreEqual({2U}, vmAssetList.FilteredAssets().Count()); Assert::AreEqual({1U}, vmAssetList.FilteredAssets().GetItemAt(0)->GetId()); diff --git a/tests/ui/viewmodels/AssetUploadViewModel_Tests.cpp b/tests/ui/viewmodels/AssetUploadViewModel_Tests.cpp index 55af48fa7..965923012 100644 --- a/tests/ui/viewmodels/AssetUploadViewModel_Tests.cpp +++ b/tests/ui/viewmodels/AssetUploadViewModel_Tests.cpp @@ -3,8 +3,8 @@ #include "ui\viewmodels\AssetUploadViewModel.hh" #include "ui\viewmodels\MessageBoxViewModel.hh" -#include "data\context\GameAssets.hh" #include "data\models\AchievementModel.hh" +#include "data\models\GameAssets.hh" #include "data\models\LeaderboardModel.hh" #include "tests\ui\UIAsserts.hh" @@ -97,7 +97,7 @@ TEST_CLASS(AssetUploadViewModel_Tests) auto vmAchievement = std::make_unique(); if (nCategory == AssetCategory::Local) { - vmAchievement->SetID(gsl::narrow_cast(m_pAssets.Count()) + ra::data::context::GameAssets::FirstLocalId); + vmAchievement->SetID(gsl::narrow_cast(m_pAssets.Count()) + ra::data::models::GameAssets::FirstLocalId); vmAchievement->CreateServerCheckpoint(); } else @@ -129,7 +129,7 @@ TEST_CLASS(AssetUploadViewModel_Tests) auto vmLeaderboard = std::make_unique(); if (nCategory == AssetCategory::Local) { - vmLeaderboard->SetID(gsl::narrow_cast(m_pAssets.Count()) + ra::data::context::GameAssets::FirstLocalId); + vmLeaderboard->SetID(gsl::narrow_cast(m_pAssets.Count()) + ra::data::models::GameAssets::FirstLocalId); vmLeaderboard->CreateServerCheckpoint(); } else @@ -250,7 +250,7 @@ TEST_CLASS(AssetUploadViewModel_Tests) void Rest() const noexcept override {} private: - ra::data::context::GameAssets m_pAssets; + ra::data::models::GameAssets m_pAssets; }; public: diff --git a/tests/ui/viewmodels/MemoryNotesViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryNotesViewModel_Tests.cpp index 4bc6607e2..4b6c744b4 100644 --- a/tests/ui/viewmodels/MemoryNotesViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryNotesViewModel_Tests.cpp @@ -7,10 +7,12 @@ #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockDevKitContext.hh" #include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\context\mocks\MockUserContext.hh" #include "tests\devkit\services\mocks\MockLocalStorage.hh" +#include "tests\devkit\services\mocks\MockLogger.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockConfiguration.hh" @@ -34,12 +36,14 @@ TEST_CLASS(MemoryNotesViewModel_Tests) public: ra::api::mocks::MockServer mockServer; ra::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockDevKitContext mockDevKitContext; ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::context::mocks::MockUserContext mockUserContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::services::mocks::MockConfiguration mockConfiguration; ra::services::mocks::MockLocalStorage mockLocalStorage; + ra::services::mocks::MockLogger mockLogger; ra::services::mocks::MockThreadPool mockThreadPool; ra::ui::mocks::MockDesktop mockDesktop; ra::ui::viewmodels::mocks::MockWindowManager mockWindowManager; diff --git a/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp index 8902baaa9..2a82bae85 100644 --- a/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp @@ -4,8 +4,10 @@ #include "ui\viewmodels\MemoryRegionsViewModel.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockDevKitContext.hh" #include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\services\mocks\MockLocalStorage.hh" +#include "tests\devkit\services\mocks\MockLogger.hh" #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" #include "tests\mocks\MockConfiguration.hh" @@ -28,11 +30,13 @@ TEST_CLASS(MemoryRegionsViewModel_Tests) { public: ra::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockDevKitContext mockDevKitContext; ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::services::mocks::MockConfiguration mockConfiguration; ra::services::mocks::MockLocalStorage mockLocalStorage; + ra::services::mocks::MockLogger mockLogger; ra::ui::mocks::MockDesktop mockDesktop; ra::ui::viewmodels::mocks::MockWindowManager mockWindowManager; diff --git a/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp b/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp index 44144de3b..f7948cf72 100644 --- a/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp +++ b/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp @@ -774,7 +774,7 @@ TEST_CLASS(OverlayAchievementsPageViewModel_Tests) OverlayAchievementsPageViewModelHarness achievementsPage; achievementsPage.mockWindowManager.AssetList.SetCategoryFilter(AssetListViewModel::CategoryFilter::Local); achievementsPage.mockAchievementRuntime.MockGame(); - const auto* pAch1 = achievementsPage.mockAchievementRuntime.MockAchievement(ra::data::context::GameAssets::FirstLocalId); + const auto* pAch1 = achievementsPage.mockAchievementRuntime.MockAchievement(ra::data::models::GameAssets::FirstLocalId); achievementsPage.mockServer.ExpectUncalled(); diff --git a/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp b/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp index 8f69594f9..4292eb4fe 100644 --- a/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp @@ -6,9 +6,11 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockDevKitContext.hh" #include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockUserContext.hh" #include "tests\devkit\services\mocks\MockLocalStorage.hh" +#include "tests\devkit\services\mocks\MockLogger.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockClipboard.hh" @@ -32,11 +34,13 @@ TEST_CLASS(PointerInspectorViewModel_Tests) { public: ra::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockDevKitContext mockDevKitContext; ra::context::mocks::MockEmulatorMemoryContext mockEmulatorContext; ra::context::mocks::MockUserContext mockUserContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::services::mocks::MockClipboard mockClipboard; ra::services::mocks::MockLocalStorage mockLocalStorage; + ra::services::mocks::MockLogger mockLogger; std::array memory{}; From daf41355105a2344d9a822333ca4c342fc6707b9 Mon Sep 17 00:00:00 2001 From: Jamiras Date: Fri, 17 Jul 2026 09:04:51 -0600 Subject: [PATCH 3/3] address analysis warning --- tests/devkit/context/mocks/MockDevKitContext.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/devkit/context/mocks/MockDevKitContext.hh b/tests/devkit/context/mocks/MockDevKitContext.hh index ae9368620..591b3f286 100644 --- a/tests/devkit/context/mocks/MockDevKitContext.hh +++ b/tests/devkit/context/mocks/MockDevKitContext.hh @@ -18,7 +18,7 @@ public: { } - const std::string& Version() const noexcept { return m_sVersion; } + const std::string& Version() const noexcept override { return m_sVersion; } void SetVersion(const std::string& sValue) { m_sVersion = sValue; } private: