diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj
index e409f6c9..4745629e 100644
--- a/src/RA_Integration.vcxproj
+++ b/src/RA_Integration.vcxproj
@@ -80,8 +80,6 @@
-
-
Create
@@ -213,8 +211,6 @@
-
-
diff --git a/src/RA_Integration.vcxproj.filters b/src/RA_Integration.vcxproj.filters
index aeeb4943..42217004 100644
--- a/src/RA_Integration.vcxproj.filters
+++ b/src/RA_Integration.vcxproj.filters
@@ -46,9 +46,6 @@
{d29ae560-83b6-496b-b1ba-bc0b0c5978af}
-
- {c9c038f9-c4bb-436c-8416-12f91df44904}
-
{e978c08c-fedb-4ead-af63-0420b26291bb}
@@ -315,9 +312,6 @@
Data\Context
-
- Data\Models
-
Data\Context
@@ -333,9 +327,6 @@
UI\ViewModels
-
- Data\Models
-
UI\ViewModels
@@ -806,9 +797,6 @@
Data\Context
-
- Data\Models
-
Data\Context
@@ -830,9 +818,6 @@
UI\ViewModels
-
- Data\Models
-
UI\ViewModels
diff --git a/src/data/context/GameContext.hh b/src/data/context/GameContext.hh
index 4ecf4050..745e270c 100644
--- a/src/data/context/GameContext.hh
+++ b/src/data/context/GameContext.hh
@@ -4,6 +4,8 @@
#include "context/IGameContext.hh"
+#include "data/models/LocalBadgesModel.hh"
+
#include "services/ServiceLocator.hh"
#include "GameAssets.hh"
@@ -178,6 +180,17 @@ public:
return pNotes ? *pNotes : m_oDefaultNotes;
}
+ ra::data::models::LocalBadgesModel& LocalBadges() override
+ {
+ auto* pLocalBadges = dynamic_cast(m_vAssets.FindAsset(ra::data::models::AssetType::LocalBadges, 0));
+ return pLocalBadges ? *pLocalBadges : m_oDefaultLocalBadges;
+ }
+ const ra::data::models::LocalBadgesModel& LocalBadges() const override
+ {
+ auto* pLocalBadges = dynamic_cast(m_vAssets.FindAsset(ra::data::models::AssetType::LocalBadges, 0));
+ return pLocalBadges ? *pLocalBadges : m_oDefaultLocalBadges;
+ }
+
private:
void FinishLoadGame(int nResult, const char* sErrorMessage, bool bWasPaused);
void MigrateSubsetUserFiles();
@@ -211,6 +224,7 @@ private:
// use the mock helper to register as both GameContext and IGameContext
ra::services::ServiceLocator::ServiceOverride m_IGameContextOverride;
ra::data::models::MemoryNotesModel m_oDefaultNotes;
+ ra::data::models::LocalBadgesModel m_oDefaultLocalBadges;
};
} // namespace context
diff --git a/src/devkit/RADevKit.vcxproj b/src/devkit/RADevKit.vcxproj
index 9aa7102e..b72d6a91 100644
--- a/src/devkit/RADevKit.vcxproj
+++ b/src/devkit/RADevKit.vcxproj
@@ -67,7 +67,9 @@
+
+
@@ -99,7 +101,9 @@
+
+
diff --git a/src/devkit/RADevKit.vcxproj.filters b/src/devkit/RADevKit.vcxproj.filters
index 485f77cf..05637bdb 100644
--- a/src/devkit/RADevKit.vcxproj.filters
+++ b/src/devkit/RADevKit.vcxproj.filters
@@ -195,6 +195,12 @@
data\models
+
+ data\models
+
+
+ data\models
+
@@ -272,5 +278,11 @@
data\models
+
+ data\models
+
+
+ data\models
+
\ No newline at end of file
diff --git a/src/devkit/context/IGameContext.hh b/src/devkit/context/IGameContext.hh
index ac8043bb..74e2454a 100644
--- a/src/devkit/context/IGameContext.hh
+++ b/src/devkit/context/IGameContext.hh
@@ -12,6 +12,7 @@ namespace ra {
namespace data {
namespace models {
class MemoryNotesModel;
+ class LocalBadgesModel;
} // namespace models
} // namespace data
@@ -71,6 +72,16 @@ public:
///
virtual const ra::data::models::MemoryNotesModel& MemoryNotes() const noexcept(false) = 0;
+ ///
+ /// Gets the s for the currently loaded game.
+ ///
+ virtual ra::data::models::LocalBadgesModel& LocalBadges() noexcept(false) = 0;
+
+ ///
+ /// Gets the s for the currently loaded game.
+ ///
+ virtual const ra::data::models::LocalBadgesModel& LocalBadges() const noexcept(false) = 0;
+
protected:
uint32_t m_nGameId = 0;
uint32_t m_nActiveGameId = 0;
diff --git a/src/data/models/AchievementModel.cpp b/src/devkit/data/models/AchievementModel.cpp
similarity index 94%
rename from src/data/models/AchievementModel.cpp
rename to src/devkit/data/models/AchievementModel.cpp
index 21a99fd2..4a81d89c 100644
--- a/src/data/models/AchievementModel.cpp
+++ b/src/devkit/data/models/AchievementModel.cpp
@@ -1,20 +1,21 @@
#include "AchievementModel.hh"
-#include "context\IRcClient.hh"
+#include "context/IGameContext.hh"
+#include "context/IRcClient.hh"
-#include "util\Log.hh"
+#include "data/context/GameAssets.hh" // TODO: this is a reference outside of the devkit code for FirstLocalID
-#include "data\context\GameContext.hh"
+#include "util/Log.hh"
-#include "data\models\LocalBadgesModel.hh"
-#include "data\models\TriggerValidation.hh"
+#include "data/models/LocalBadgesModel.hh"
+#include "data/models/TriggerValidation.hh"
-#include "services\ServiceLocator.hh"
+#include "services/ServiceLocator.hh"
-#include "util\Strings.hh"
+#include "util/Strings.hh"
-#include
-#include
+#include
+#include
namespace ra {
namespace data {
@@ -109,24 +110,16 @@ void AchievementModel::OnValueChanged(const StringModelProperty::ChangeArgs& arg
{
if (ra::util::String::StartsWith(args.tOldValue, L"local\\"))
{
- auto& pGameContext = ra::services::ServiceLocator::GetMutable();
- auto* pLocalBadges = dynamic_cast(pGameContext.Assets().FindAsset(ra::data::models::AssetType::LocalBadges, 0));
- if (pLocalBadges)
- {
- const bool bCommitted = (GetLocalValue(BadgeProperty) == args.tOldValue);
- pLocalBadges->RemoveReference(args.tOldValue, bCommitted);
- }
+ const bool bCommitted = (GetLocalValue(BadgeProperty) == args.tOldValue);
+ auto& pGameContext = ra::services::ServiceLocator::GetMutable();
+ pGameContext.LocalBadges().RemoveReference(args.tOldValue, bCommitted);
}
if (ra::util::String::StartsWith(args.tNewValue, L"local\\"))
{
- auto& pGameContext = ra::services::ServiceLocator::GetMutable();
- auto* pLocalBadges = dynamic_cast(pGameContext.Assets().FindAsset(ra::data::models::AssetType::LocalBadges, 0));
- if (pLocalBadges)
- {
- const bool bCommitted = (GetLocalValue(BadgeProperty) == args.tNewValue);
- pLocalBadges->AddReference(args.tNewValue, bCommitted);
- }
+ const bool bCommitted = (GetLocalValue(BadgeProperty) == args.tNewValue);
+ auto& pGameContext = ra::services::ServiceLocator::GetMutable();
+ pGameContext.LocalBadges().AddReference(args.tNewValue, bCommitted);
}
if (m_pAchievementInfo)
@@ -143,10 +136,8 @@ void AchievementModel::CommitTransaction()
const auto& pBadgeName = GetBadge();
if (*pPreviousBadgeName != pBadgeName)
{
- auto& pGameContext = ra::services::ServiceLocator::GetMutable();
- auto* pLocalBadges = dynamic_cast(pGameContext.Assets().FindAsset(ra::data::models::AssetType::LocalBadges, 0));
- if (pLocalBadges)
- pLocalBadges->Commit(*pPreviousBadgeName, pBadgeName);
+ auto& pGameContext = ra::services::ServiceLocator::GetMutable();
+ pGameContext.LocalBadges().Commit(*pPreviousBadgeName, pBadgeName);
}
}
diff --git a/src/data/models/AchievementModel.hh b/src/devkit/data/models/AchievementModel.hh
similarity index 98%
rename from src/data/models/AchievementModel.hh
rename to src/devkit/data/models/AchievementModel.hh
index d24e1854..ac0cfd80 100644
--- a/src/data/models/AchievementModel.hh
+++ b/src/devkit/data/models/AchievementModel.hh
@@ -1,5 +1,5 @@
-#ifndef RA_DATA_ACHIEVEMENT_MODEL_H
-#define RA_DATA_ACHIEVEMENT_MODEL_H
+#ifndef RA_DATA_MODELS_ACHIEVEMENTMODEL_H
+#define RA_DATA_MODELS_ACHIEVEMENTMODEL_H
#pragma once
#include "data/models/AssetModelBase.hh"
@@ -237,4 +237,4 @@ private:
} // namespace data
} // namespace ra
-#endif RA_DATA_ACHIEVEMENT_MODEL_H
+#endif RA_DATA_MODELS_ACHIEVEMENTMODEL_H
diff --git a/src/data/models/LeaderboardModel.cpp b/src/devkit/data/models/LeaderboardModel.cpp
similarity index 98%
rename from src/data/models/LeaderboardModel.cpp
rename to src/devkit/data/models/LeaderboardModel.cpp
index d5abd913..2229fd25 100644
--- a/src/data/models/LeaderboardModel.cpp
+++ b/src/devkit/data/models/LeaderboardModel.cpp
@@ -1,15 +1,15 @@
#include "LeaderboardModel.hh"
-#include "context\IRcClient.hh"
+#include "context/IRcClient.hh"
-#include "data\models\TriggerValidation.hh"
+#include "data/models/TriggerValidation.hh"
-#include "services\ServiceLocator.hh"
+#include "services/ServiceLocator.hh"
-#include "util\Strings.hh"
+#include "util/Strings.hh"
-#include
-#include
+#include
+#include
namespace ra {
namespace data {
diff --git a/src/data/models/LeaderboardModel.hh b/src/devkit/data/models/LeaderboardModel.hh
similarity index 98%
rename from src/data/models/LeaderboardModel.hh
rename to src/devkit/data/models/LeaderboardModel.hh
index c57bf604..4773d53d 100644
--- a/src/data/models/LeaderboardModel.hh
+++ b/src/devkit/data/models/LeaderboardModel.hh
@@ -1,5 +1,5 @@
-#ifndef RA_DATA_LEADERBOARD_MODEL_H
-#define RA_DATA_LEADERBOARD_MODEL_H
+#ifndef RA_DATA_MODELS_LEADERBOARDMODEL_H
+#define RA_DATA_MODELS_LEADERBOARDMODEL_H
#pragma once
#include "data/models/AssetModelBase.hh"
@@ -260,4 +260,4 @@ private:
} // namespace data
} // namespace ra
-#endif RA_DATA_LEADERBOARD_MODEL_H
+#endif RA_DATA_MODELS_LEADERBOARDMODEL_H
diff --git a/src/ui/win32/bindings/ImageBinding.hh b/src/ui/win32/bindings/ImageBinding.hh
index f67367bc..58c9ea5a 100644
--- a/src/ui/win32/bindings/ImageBinding.hh
+++ b/src/ui/win32/bindings/ImageBinding.hh
@@ -19,8 +19,11 @@ public:
~ImageBinding() noexcept
{
- GSL_SUPPRESS_F6 auto& pImageRepository = ra::services::ServiceLocator::GetMutable();
- pImageRepository.RemoveNotifyTarget(*this);
+ if (ra::services::ServiceLocator::Exists())
+ {
+ GSL_SUPPRESS_F6 auto& pImageRepository = ra::services::ServiceLocator::GetMutable();
+ pImageRepository.RemoveNotifyTarget(*this);
+ }
}
ImageBinding(const ImageBinding&) noexcept = delete;
diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj
index f261656a..0206547f 100644
--- a/tests/RA_Integration.Tests.vcxproj
+++ b/tests/RA_Integration.Tests.vcxproj
@@ -82,8 +82,6 @@
-
-
Create
@@ -144,7 +142,6 @@
-
@@ -155,8 +152,6 @@
-
-
diff --git a/tests/RA_Integration.Tests.vcxproj.filters b/tests/RA_Integration.Tests.vcxproj.filters
index e3c0fb90..999a73fa 100644
--- a/tests/RA_Integration.Tests.vcxproj.filters
+++ b/tests/RA_Integration.Tests.vcxproj.filters
@@ -31,9 +31,6 @@
{da241f86-5f80-4b36-b3d8-f8a0ecc1a4ee}
-
- {a0f14c97-e5dd-4827-9864-ca54f0c9177e}
-
@@ -309,12 +306,6 @@
Tests\Data\Context
-
- Code
-
-
- Tests\Data\Models
-
Tests\UI\ViewModels
@@ -339,12 +330,6 @@
Code
-
- Code
-
-
- Tests\Data\Models
-
Code
@@ -512,9 +497,6 @@
Tests\UI\ViewModels
-
- Code
-
Code
diff --git a/tests/devkit/RADevKit.Tests.vcxproj b/tests/devkit/RADevKit.Tests.vcxproj
index 6f62eb63..27e21359 100644
--- a/tests/devkit/RADevKit.Tests.vcxproj
+++ b/tests/devkit/RADevKit.Tests.vcxproj
@@ -70,6 +70,8 @@
+
+
@@ -88,6 +90,7 @@
+
diff --git a/tests/devkit/RADevKit.Tests.vcxproj.filters b/tests/devkit/RADevKit.Tests.vcxproj.filters
index ff15a7f0..eccf4c02 100644
--- a/tests/devkit/RADevKit.Tests.vcxproj.filters
+++ b/tests/devkit/RADevKit.Tests.vcxproj.filters
@@ -70,6 +70,12 @@
data\models
+
+ data\models
+
+
+ data\models
+
@@ -170,5 +176,8 @@
ui\mocks
+
+ testutil
+
\ No newline at end of file
diff --git a/tests/devkit/context/mocks/MockGameContext.hh b/tests/devkit/context/mocks/MockGameContext.hh
index 6af100b5..855b8fb3 100644
--- a/tests/devkit/context/mocks/MockGameContext.hh
+++ b/tests/devkit/context/mocks/MockGameContext.hh
@@ -4,6 +4,7 @@
#include "context/IGameContext.hh"
+#include "data/models/LocalBadgesModel.hh"
#include "data/models/MemoryNotesModel.hh"
#include "services/ServiceLocator.hh"
@@ -26,6 +27,9 @@ public:
ra::data::models::MemoryNotesModel& MemoryNotes() noexcept override { return m_oMemoryNotes; }
const ra::data::models::MemoryNotesModel& MemoryNotes() const noexcept override { return m_oMemoryNotes; }
+ ra::data::models::LocalBadgesModel& LocalBadges() noexcept override { return m_oLocalBadges; }
+ const ra::data::models::LocalBadgesModel& LocalBadges() const noexcept override { return m_oLocalBadges; }
+
bool SetNote(ra::data::ByteAddress nAddress, const std::wstring& sNote)
{
if (m_oMemoryNotes.NoteCount() == 0)
@@ -88,6 +92,7 @@ private:
};
MockMemoryNotesModel m_oMemoryNotes;
+ ra::data::models::LocalBadgesModel m_oLocalBadges;
ra::services::ServiceLocator::ServiceOverride m_Override;
};
diff --git a/tests/devkit/context/mocks/MockRcClient.cpp b/tests/devkit/context/mocks/MockRcClient.cpp
index 2b83d0cb..648ff9ee 100644
--- a/tests/devkit/context/mocks/MockRcClient.cpp
+++ b/tests/devkit/context/mocks/MockRcClient.cpp
@@ -186,6 +186,7 @@ void MockRcClient::MockGame(uint32_t nGameId, const char* title, uint32_t nConso
pGame->public_.id = nGameId;
pGame->public_.console_id = nConsoleId;
pGame->public_.title = title;
+ pGame->public_.badge_name = "55443";
auto* pClient = GetClient();
rc_client_unload_game(pClient);
@@ -194,6 +195,147 @@ void MockRcClient::MockGame(uint32_t nGameId, const char* title, uint32_t nConso
pClient->state.frames_processed = pClient->state.frames_at_last_ping = 0;
}
+static rc_client_subset_info_t* GetSubset(rc_client_game_info_t* game, uint32_t subset_id, const char* name)
+{
+ rc_client_subset_info_t* subset = game->subsets;
+ gsl::not_null next = gsl::make_not_null(&game->subsets);
+ for (; subset; subset = subset->next)
+ {
+ if (subset->public_.id == subset_id)
+ return subset;
+
+ next = gsl::make_not_null(&subset->next);
+ }
+
+ subset = static_cast(rc_buffer_alloc(&game->buffer, sizeof(rc_client_subset_info_t)));
+ memset(subset, 0, sizeof(*subset));
+ subset->public_.id = subset_id;
+ strcpy_s(subset->public_.badge_name, sizeof(subset->public_.badge_name), game->public_.badge_name);
+ subset->public_.title = name;
+ subset->active = 1;
+
+ *next = subset;
+
+ return subset;
+}
+
+static rc_client_subset_info_t* GetCoreSubset(rc_client_game_info_t* game)
+{
+ Assert::IsNotNull(game, L"MockGame must be called first");
+ return GetSubset(game, game->public_.id, game->public_.title);
+}
+
+static rc_client_achievement_info_t* AddAchievement(rc_client_game_info_t* game,
+ rc_client_subset_info_t* subset, uint32_t nId, const char* sTitle)
+{
+ Expects(subset != nullptr);
+ if (subset->public_.num_achievements % 8 == 0)
+ {
+ const uint32_t new_count = subset->public_.num_achievements + 8;
+ rc_client_achievement_info_t* new_achievements = static_cast(rc_buffer_alloc(
+ &game->buffer, sizeof(rc_client_achievement_info_t) * new_count));
+
+ if (subset->public_.num_achievements > 0)
+ {
+ memcpy(new_achievements, subset->achievements,
+ sizeof(rc_client_achievement_info_t) * subset->public_.num_achievements);
+ }
+
+ subset->achievements = new_achievements;
+ }
+
+ rc_client_achievement_info_t* achievement = &subset->achievements[subset->public_.num_achievements++];
+ memset(achievement, 0, sizeof(*achievement));
+ achievement->public_.id = nId;
+
+ if (sTitle)
+ {
+ achievement->public_.title = rc_buffer_strcpy(&game->buffer, sTitle);
+ }
+ else
+ {
+ const std::string sGeneratedTitle = ra::util::String::Printf("Achievement %u", nId);
+ achievement->public_.title = rc_buffer_strcpy(&game->buffer, sGeneratedTitle.c_str());
+ }
+
+ const std::string sGeneratedDescripton = ra::util::String::Printf("Description %u", nId);
+ achievement->public_.description = rc_buffer_strcpy(&game->buffer, sGeneratedDescripton.c_str());
+
+ achievement->public_.category = RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE;
+ achievement->public_.state = RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE;
+ achievement->public_.points = 5;
+ achievement->author = "Author";
+
+ return achievement;
+}
+
+rc_client_achievement_info_t* MockRcClient::MockAchievement(uint32_t nId, const char* sTitle)
+{
+ rc_client_game_info_t* game = GetClient()->game;
+ rc_client_achievement_info_t* achievement = AddAchievement(game, GetCoreSubset(game), nId, sTitle);
+
+ achievement->trigger = static_cast(rc_buffer_alloc(&game->buffer, sizeof(rc_trigger_t)));
+ memset(achievement->trigger, 0, sizeof(*achievement->trigger));
+ achievement->trigger->state = RC_TRIGGER_STATE_ACTIVE;
+
+ return achievement;
+}
+
+static rc_client_leaderboard_info_t* AddLeaderboard(const rc_client_t* client, rc_client_game_info_t* game,
+ rc_client_subset_info_t* subset, uint32_t nId, const char* sTitle)
+{
+ Expects(subset != nullptr);
+ if (subset->public_.num_leaderboards % 8 == 0)
+ {
+ const uint32_t new_count = subset->public_.num_leaderboards + 8;
+ rc_client_leaderboard_info_t* new_leaderboards = static_cast(rc_buffer_alloc(
+ &game->buffer, sizeof(rc_client_leaderboard_info_t) * new_count));
+
+ if (subset->public_.num_leaderboards > 0)
+ {
+ memcpy(new_leaderboards, subset->leaderboards,
+ sizeof(rc_client_leaderboard_info_t) * subset->public_.num_leaderboards);
+ }
+
+ subset->leaderboards = new_leaderboards;
+ }
+
+ rc_client_leaderboard_info_t* leaderboard = &subset->leaderboards[subset->public_.num_leaderboards++];
+ memset(leaderboard, 0, sizeof(*leaderboard));
+ leaderboard->public_.id = nId;
+
+ if (sTitle)
+ {
+ leaderboard->public_.title = rc_buffer_strcpy(&game->buffer, sTitle);
+ }
+ else
+ {
+ const std::string sGeneratedTitle = ra::util::String::Printf("Leaderboard %u", nId);
+ leaderboard->public_.title = rc_buffer_strcpy(&game->buffer, sGeneratedTitle.c_str());
+ }
+
+ const std::string sGeneratedDescripton = ra::util::String::Printf("Description %u", nId);
+ leaderboard->public_.description = rc_buffer_strcpy(&game->buffer, sGeneratedDescripton.c_str());
+
+ leaderboard->public_.state = static_cast(rc_client_get_hardcore_enabled(client) ?
+ RC_CLIENT_LEADERBOARD_STATE_ACTIVE : RC_CLIENT_LEADERBOARD_STATE_INACTIVE);
+
+ return leaderboard;
+}
+
+rc_client_leaderboard_info_t* MockRcClient::MockLeaderboard(uint32_t nId, const char* sTitle)
+{
+ rc_client_game_info_t* game = GetClient()->game;
+ rc_client_leaderboard_info_t* leaderboard = AddLeaderboard(GetClient(), game, GetCoreSubset(game), nId, sTitle);
+
+ leaderboard->lboard = static_cast(rc_buffer_alloc(&game->buffer, sizeof(rc_lboard_t)));
+ memset(leaderboard->lboard, 0, sizeof(*leaderboard->lboard));
+ leaderboard->lboard->state = static_cast(
+ rc_client_get_hardcore_enabled(GetClient()) ? RC_LBOARD_STATE_ACTIVE : RC_LBOARD_STATE_INACTIVE);
+
+ return leaderboard;
+}
+
} // namespace mocks
} // namespace context
} // namespace ra
diff --git a/tests/devkit/context/mocks/MockRcClient.hh b/tests/devkit/context/mocks/MockRcClient.hh
index 901343e0..01f28366 100644
--- a/tests/devkit/context/mocks/MockRcClient.hh
+++ b/tests/devkit/context/mocks/MockRcClient.hh
@@ -6,6 +6,9 @@
#include "services\ServiceLocator.hh"
+typedef struct rc_client_achievement_info_t rc_client_achievement_info_t;
+typedef struct rc_client_leaderboard_info_t rc_client_leaderboard_info_t;
+
namespace ra {
namespace context {
namespace mocks {
@@ -31,6 +34,8 @@ public:
void SetHardcoreEnabled(bool bValue) noexcept;
void MockGame(uint32_t nGameId, const char* title, uint32_t nConsoleId = 1);
+ rc_client_achievement_info_t* MockAchievement(uint32_t nId, const char* sTitle = nullptr);
+ rc_client_leaderboard_info_t* MockLeaderboard(uint32_t nId, const char* sTitle = nullptr);
private:
typedef struct MockApiResponse
diff --git a/tests/data/models/AchievementModel_Tests.cpp b/tests/devkit/data/models/AchievementModel_Tests.cpp
similarity index 82%
rename from tests/data/models/AchievementModel_Tests.cpp
rename to tests/devkit/data/models/AchievementModel_Tests.cpp
index 19d3779a..29eacdd9 100644
--- a/tests/data/models/AchievementModel_Tests.cpp
+++ b/tests/devkit/data/models/AchievementModel_Tests.cpp
@@ -1,20 +1,20 @@
-#include "CppUnitTest.h"
+#include "data/models/AchievementModel.hh"
-#include "data\models\AchievementModel.hh"
-#include "data\models\LocalBadgesModel.hh"
+#include "context/mocks/MockEmulatorMemoryContext.hh"
+#include "context/mocks/MockGameContext.hh"
+#include "context/mocks/MockRcClient.hh"
+#include "context/mocks/MockUserContext.hh"
-#include "services\impl\StringTextWriter.hh"
+#include "data/models/LocalBadgesModel.hh"
-#include "tests\RA_UnitTestHelpers.h"
-#include "tests\data\DataAsserts.hh"
+#include "services/impl/StringTextWriter.hh"
+#include "services/mocks/MockClock.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\testutil\AssetAsserts.hh"
-#include "tests\mocks\MockAchievementRuntime.hh"
-#include "tests\mocks\MockGameContext.hh"
+#include "testutil/AchievementAsserts.hh"
+#include "testutil/AssetAsserts.hh"
+#include "testutil/CppUnitTest.hh"
+
+#include
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
@@ -33,29 +33,15 @@ TEST_CLASS(AchievementModel_Tests)
public:
AchievementModelHarness() noexcept
{
- GSL_SUPPRESS_F6 mockRuntime.MockGame();
+ GSL_SUPPRESS_F6 mockRcClient.MockGame(1, "Game Title");
}
ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
+ ra::context::mocks::MockGameContext mockGameContext;
ra::context::mocks::MockRcClient mockRcClient;
ra::context::mocks::MockUserContext mockUserContext;
- ra::data::context::mocks::MockGameContext mockGameContext;
ra::services::impl::StringTextWriter textWriter;
- ra::services::mocks::MockAchievementRuntime mockRuntime;
ra::services::mocks::MockClock mockClock;
-
- 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(AssetType::LocalBadges, 0)));
- }
};
public:
@@ -82,7 +68,6 @@ TEST_CLASS(AchievementModel_Tests)
{
AchievementModelHarness achievement;
achievement.mockGameContext.SetGameId(22);
- achievement.AddLocalBadgesModel();
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -90,7 +75,7 @@ TEST_CLASS(AchievementModel_Tests)
achievement.SetTrigger("0xH1234=1");
achievement.SetBadge(L"local\\22-ABC.png");
- const auto& pLocalBadges = achievement.GetLocalBadgesModel();
+ const auto& pLocalBadges = achievement.mockGameContext.LocalBadges();
Assert::AreEqual(1, pLocalBadges.GetReferenceCount(L"local\\22-ABC.png", false));
Assert::AreEqual(0, pLocalBadges.GetReferenceCount(L"local\\22-ABC.png", true));
@@ -105,7 +90,6 @@ TEST_CLASS(AchievementModel_Tests)
{
AchievementModelHarness achievement;
achievement.mockGameContext.SetGameId(22);
- achievement.AddLocalBadgesModel();
achievement.SetBadge(L"12345.png");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -114,7 +98,7 @@ TEST_CLASS(AchievementModel_Tests)
achievement.SetTrigger("0xH1234=1");
achievement.SetBadge(L"local\\22-ABC.png");
- const auto& pLocalBadges = achievement.GetLocalBadgesModel();
+ const auto& pLocalBadges = achievement.mockGameContext.LocalBadges();
Assert::AreEqual(1, pLocalBadges.GetReferenceCount(L"local\\22-ABC.png", false));
Assert::AreEqual(0, pLocalBadges.GetReferenceCount(L"local\\22-ABC.png", true));
@@ -132,7 +116,6 @@ TEST_CLASS(AchievementModel_Tests)
AchievementModelHarness achievement;
achievement.mockGameContext.SetGameId(22);
achievement.mockGameContext.SetNote(0x1234, L"Note");
- achievement.AddLocalBadgesModel();
achievement.SetBadge(L"12345.png");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -171,7 +154,6 @@ TEST_CLASS(AchievementModel_Tests)
{
AchievementModelHarness achievement;
achievement.mockGameContext.SetGameId(22);
- achievement.AddLocalBadgesModel();
achievement.SetBadge(L"12345.png");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -203,7 +185,6 @@ TEST_CLASS(AchievementModel_Tests)
{
AchievementModelHarness achievement;
achievement.mockGameContext.SetGameId(22);
- achievement.AddLocalBadgesModel();
achievement.SetBadge(L"12345.png");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -239,12 +220,12 @@ TEST_CLASS(AchievementModel_Tests)
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
- achievement.mockRuntime.MockGame();
- auto* achievement_info = achievement.mockRuntime.MockAchievementWithTrigger(achievement.GetID());
+ auto* achievement_info = achievement.mockRcClient.MockAchievement(achievement.GetID());
+ Expects(achievement_info != nullptr);
achievement.SetLocalAchievementInfo(*achievement_info);
g_bEventSeen = false;
- achievement.mockRuntime.GetClient()->callbacks.event_handler =
+ achievement.mockRcClient.GetClient()->callbacks.event_handler =
[](const rc_client_event_t* pEvent, rc_client_t*)
{
Assert::AreEqual({RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE}, pEvent->type);
@@ -272,12 +253,12 @@ TEST_CLASS(AchievementModel_Tests)
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
- achievement.mockRuntime.MockGame();
- auto* achievement_info = achievement.mockRuntime.MockAchievementWithTrigger(achievement.GetID());
+ auto* achievement_info = achievement.mockRcClient.MockAchievement(achievement.GetID());
+ Expects(achievement_info != nullptr);
achievement.SetLocalAchievementInfo(*achievement_info);
g_bEventSeen = false;
- achievement.mockRuntime.GetClient()->callbacks.event_handler = [](const rc_client_event_t* pEvent,
+ achievement.mockRcClient.GetClient()->callbacks.event_handler = [](const rc_client_event_t* pEvent,
rc_client_t*) {
Assert::AreEqual({RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE}, pEvent->type);
Assert::AreEqual({53}, pEvent->achievement->id);
diff --git a/tests/data/models/LeaderboardModel_Tests.cpp b/tests/devkit/data/models/LeaderboardModel_Tests.cpp
similarity index 90%
rename from tests/data/models/LeaderboardModel_Tests.cpp
rename to tests/devkit/data/models/LeaderboardModel_Tests.cpp
index 7aecf4d0..1a34288c 100644
--- a/tests/data/models/LeaderboardModel_Tests.cpp
+++ b/tests/devkit/data/models/LeaderboardModel_Tests.cpp
@@ -1,18 +1,17 @@
-#include "CppUnitTest.h"
+#include "data/models/LeaderboardModel.hh"
-#include "data\models\LeaderboardModel.hh"
+#include "context/mocks/MockEmulatorMemoryContext.hh"
+#include "context/mocks/MockGameContext.hh"
+#include "context/mocks/MockRcClient.hh"
+#include "context/mocks/MockUserContext.hh"
-#include "services\impl\StringTextWriter.hh"
+#include "services/impl/StringTextWriter.hh"
-#include "tests\RA_UnitTestHelpers.h"
+#include "testutil/AssetAsserts.hh"
+#include "testutil/CppUnitTest.hh"
+#include "testutil/ValueAsserts.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\testutil\AssetAsserts.hh"
-#include "tests\devkit\testutil\ValueAsserts.hh"
-#include "tests\mocks\MockAchievementRuntime.hh"
-#include "tests\mocks\MockGameContext.hh"
+#include
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
@@ -30,11 +29,10 @@ TEST_CLASS(LeaderboardModel_Tests)
{
public:
ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
+ ra::context::mocks::MockGameContext mockGameContext;
ra::context::mocks::MockRcClient mockRcClient;
ra::context::mocks::MockUserContext mockUserContext;
- ra::data::context::mocks::MockGameContext mockGameContext;
ra::services::impl::StringTextWriter textWriter;
- ra::services::mocks::MockAchievementRuntime mockRuntime;
};
public:
@@ -280,14 +278,15 @@ TEST_CLASS(LeaderboardModel_Tests)
leaderboard.CreateServerCheckpoint();
leaderboard.CreateLocalCheckpoint();
- leaderboard.mockRuntime.MockGame();
- auto* leaderboard_info = leaderboard.mockRuntime.MockLeaderboardWithLboard(leaderboard.GetID());
+ leaderboard.mockRcClient.MockGame(1, "Game");
+ auto* leaderboard_info = leaderboard.mockRcClient.MockLeaderboard(leaderboard.GetID());
+ Expects(leaderboard_info != nullptr);
leaderboard.SetLocalLeaderboardInfo(*leaderboard_info);
- rc_client_allocate_leaderboard_tracker(leaderboard.mockRuntime.GetClient()->game, leaderboard_info);
+ rc_client_allocate_leaderboard_tracker(leaderboard.mockRcClient.GetClient()->game, leaderboard_info);
g_bEventSeen = false;
- leaderboard.mockRuntime.GetClient()->callbacks.event_handler =
+ leaderboard.mockRcClient.GetClient()->callbacks.event_handler =
[](const rc_client_event_t* pEvent, rc_client_t*) {
Assert::AreEqual({RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE}, pEvent->type);
Assert::AreEqual({1}, pEvent->leaderboard_tracker->id);
@@ -316,16 +315,17 @@ TEST_CLASS(LeaderboardModel_Tests)
leaderboard.CreateServerCheckpoint();
leaderboard.CreateLocalCheckpoint();
- leaderboard.mockRuntime.MockGame();
- auto* leaderboard_info = leaderboard.mockRuntime.MockLeaderboardWithLboard(leaderboard.GetID());
+ leaderboard.mockRcClient.MockGame(1, "Game");
+ auto* leaderboard_info = leaderboard.mockRcClient.MockLeaderboard(leaderboard.GetID());
+ Expects(leaderboard_info != nullptr);
leaderboard.SetLocalLeaderboardInfo(*leaderboard_info);
- rc_client_allocate_leaderboard_tracker(leaderboard.mockRuntime.GetClient()->game, leaderboard_info);
- auto* leaderboard_info2 = leaderboard.mockRuntime.MockLeaderboardWithLboard(99);
- rc_client_allocate_leaderboard_tracker(leaderboard.mockRuntime.GetClient()->game, leaderboard_info2);
+ rc_client_allocate_leaderboard_tracker(leaderboard.mockRcClient.GetClient()->game, leaderboard_info);
+ auto* leaderboard_info2 = leaderboard.mockRcClient.MockLeaderboard(99);
+ rc_client_allocate_leaderboard_tracker(leaderboard.mockRcClient.GetClient()->game, leaderboard_info2);
g_bEventSeen = false;
- leaderboard.mockRuntime.GetClient()->callbacks.event_handler =
+ leaderboard.mockRcClient.GetClient()->callbacks.event_handler =
[](const rc_client_event_t*, rc_client_t*) {
g_bEventSeen = true;
};
@@ -352,14 +352,15 @@ TEST_CLASS(LeaderboardModel_Tests)
leaderboard.CreateServerCheckpoint();
leaderboard.CreateLocalCheckpoint();
- leaderboard.mockRuntime.MockGame();
- auto* leaderboard_info = leaderboard.mockRuntime.MockLeaderboardWithLboard(leaderboard.GetID());
+ leaderboard.mockRcClient.MockGame(1, "Game");
+ auto* leaderboard_info = leaderboard.mockRcClient.MockLeaderboard(leaderboard.GetID());
+ Expects(leaderboard_info != nullptr);
leaderboard.SetLocalLeaderboardInfo(*leaderboard_info);
- rc_client_allocate_leaderboard_tracker(leaderboard.mockRuntime.GetClient()->game, leaderboard_info);
+ rc_client_allocate_leaderboard_tracker(leaderboard.mockRcClient.GetClient()->game, leaderboard_info);
g_bEventSeen = false;
- leaderboard.mockRuntime.GetClient()->callbacks.event_handler =
+ leaderboard.mockRcClient.GetClient()->callbacks.event_handler =
[](const rc_client_event_t* pEvent, rc_client_t*) {
Assert::AreEqual({RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE}, pEvent->type);
Assert::AreEqual({1}, pEvent->leaderboard_tracker->id);
@@ -391,15 +392,16 @@ TEST_CLASS(LeaderboardModel_Tests)
leaderboard.CreateServerCheckpoint();
leaderboard.CreateLocalCheckpoint();
- leaderboard.mockRuntime.MockGame();
- auto* leaderboard_info = leaderboard.mockRuntime.MockLeaderboard(leaderboard.GetID());
+ leaderboard.mockRcClient.MockGame(1, "Game");
+ auto* leaderboard_info = leaderboard.mockRcClient.MockLeaderboard(leaderboard.GetID());
+ Expects(leaderboard_info != nullptr);
leaderboard.SetLocalLeaderboardInfo(*leaderboard_info);
// forcefully start the leaderboard
leaderboard.SetState(AssetState::Primed);
const auto* pLboard = leaderboard_info->lboard;
Assert::IsNotNull(pLboard);
- rc_client_allocate_leaderboard_tracker(leaderboard.mockRuntime.GetClient()->game, leaderboard_info);
+ rc_client_allocate_leaderboard_tracker(leaderboard.mockRcClient.GetClient()->game, leaderboard_info);
Assert::IsTrue(leaderboard.IsActive());
Assert::AreEqual({ RC_LBOARD_STATE_STARTED }, leaderboard_info->lboard->state);
diff --git a/tests/devkit/testutil/AchievementAsserts.hh b/tests/devkit/testutil/AchievementAsserts.hh
new file mode 100644
index 00000000..c45d6c36
--- /dev/null
+++ b/tests/devkit/testutil/AchievementAsserts.hh
@@ -0,0 +1,44 @@
+#ifndef RA_ACHIEVEMENT_ASSERTS_H
+#define RA_ACHIEVEMENT_ASSERTS_H
+#pragma once
+
+#include "CppUnitTest.hh"
+
+#include "data/models/AchievementModel.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::AchievementType& t)
+{
+ switch (t)
+ {
+ 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(t));
+ }
+}
+
+#pragma warning(pop)
+
+} // namespace CppUnitTestFramework
+} // namespace VisualStudio
+} // namespace Microsoft
+
+#endif /* !RA_ACHIEVEMENT_ASSERTS_H */