refactor: inject IPlatformLeaderboard into Minecraft and StatsCounter via constructor

This commit is contained in:
MatthewBeshay 2026-04-09 20:19:50 +10:00
parent 08d8e341b9
commit aa250ff560
5 changed files with 46 additions and 21 deletions

View file

@ -48,9 +48,9 @@ static void sigsegv_handler(int sig) {
#include <string>
#include <vector>
#include "app/common/Leaderboards/LeaderboardManager.h"
#include "minecraft/stats/StatsCounter.h"
#include "minecraft/world/level/Level.h"
// #include "app/common/Leaderboards/LeaderboardManager.h"
// #include "../Common/XUI/XUI_Scene_Container.h"
// #include "NetworkManager.h"
#include "platform/PlatformTypes.h"
@ -513,7 +513,12 @@ int main(int argc, const char* argv[]) {
Level::enableLightingCache();
Tile::CreateNewThreadStorage();
Minecraft::main();
// Composition root: read the leaderboard backend from the existing
// LinuxLeaderboardManager singleton (still used by the legacy UI
// scenes) and pass it down via constructor injection. Once the UI
// side is also injected, the singleton can be deleted entirely and
// the backend constructed via std::make_unique here.
Minecraft::main(*LeaderboardManager::Instance());
Minecraft* pMinecraft = Minecraft::GetInstance();
app.InitGameSettings();

View file

@ -157,7 +157,8 @@ ResourceLocation Minecraft::ALT_FONT_LOCATION = ResourceLocation(TN_ALT_FONT);
Minecraft::Minecraft(Component* mouseComponent, Canvas* parent,
MinecraftApplet* minecraftApplet, int width, int height,
bool fullscreen) {
bool fullscreen, IPlatformLeaderboard& leaderboard_)
: leaderboard(leaderboard_) {
// 4J - added this block of initialisers
gameMode = nullptr;
hasCrashed = false;
@ -324,7 +325,7 @@ void Minecraft::init() {
EntityRenderDispatcher::instance->itemInHandRenderer =
new ItemInHandRenderer(this, false);
for (int i = 0; i < 4; ++i) stats[i] = new StatsCounter();
for (int i = 0; i < 4; ++i) stats[i] = new StatsCounter(leaderboard);
/* 4J - TODO, 4J-JEV: Unnecessary.
Achievements::openInventory->setDescFormatter(nullptr);
@ -4100,13 +4101,15 @@ void Minecraft::respawnPlayer(int iPad, int dimension, int newEntityId) {
gameRenderer->EnableUpdateThread();
}
void Minecraft::start(const std::string& name, const std::string& sid) {
startAndConnectTo(name, sid, "");
void Minecraft::start(const std::string& name, const std::string& sid,
IPlatformLeaderboard& leaderboard) {
startAndConnectTo(name, sid, "", leaderboard);
}
void Minecraft::startAndConnectTo(const std::string& name,
const std::string& sid,
const std::string& url) {
const std::string& url,
IPlatformLeaderboard& leaderboard) {
bool fullScreen = false;
std::string userName = name;
@ -4129,7 +4132,9 @@ void Minecraft::startAndConnectTo(const std::string& name,
Minecraft* minecraft;
// 4J - was new Minecraft(frame, canvas, nullptr, 854, 480, fullScreen);
minecraft = new Minecraft(nullptr, nullptr, nullptr, 1280, 720, fullScreen);
minecraft =
new Minecraft(nullptr, nullptr, nullptr, 1280, 720, fullScreen,
leaderboard);
/* - 4J - removed
{
@ -4201,7 +4206,7 @@ bool useLomp = false;
int g_iMainThreadId;
void Minecraft::main() {
void Minecraft::main(IPlatformLeaderboard& leaderboard) {
std::string name;
std::string sessionId;
@ -4241,7 +4246,7 @@ void Minecraft::main() {
// On PS4, we call Minecraft::Start from another thread, as this has been
// timed taking ~2.5 seconds and we need to do some basic rendering stuff so
// that we don't break the TRCs on SubmitDone calls
Minecraft::start(name, sessionId);
Minecraft::start(name, sessionId, leaderboard);
}
bool Minecraft::renderNames() {

View file

@ -32,6 +32,7 @@ class HumanoidModel;
class HitResult;
class Options;
class SoundEngine;
class IPlatformLeaderboard;
class MinecraftApplet;
class MouseHandler;
class TexturePackRepository;
@ -69,7 +70,7 @@ public:
static const std::string VERSION_STRING;
Minecraft(Component* mouseComponent, Canvas* parent,
MinecraftApplet* minecraftApplet, int width, int height,
bool fullscreen);
bool fullscreen, IPlatformLeaderboard& leaderboard);
void init();
// 4J - removed
@ -215,6 +216,11 @@ public:
// 4J- this should really be in localplayer
StatsCounter* stats[4];
// Borrowed from the composition root - Minecraft does not own the
// backend. The reference is valid for the lifetime of the Minecraft
// singleton (the leaderboard outlives Minecraft).
IPlatformLeaderboard& leaderboard;
private:
std::string connectToIp;
int connectToPort;
@ -337,12 +343,14 @@ public:
std::string gatherStats4();
void respawnPlayer(int iPad, int dimension, int newEntityId);
static void start(const std::string& name, const std::string& sid);
static void start(const std::string& name, const std::string& sid,
IPlatformLeaderboard& leaderboard);
static void startAndConnectTo(const std::string& name,
const std::string& sid,
const std::string& url);
const std::string& url,
IPlatformLeaderboard& leaderboard);
ClientConnection* getConnection(int iPad); // 4J Stu added iPad param
static void main();
static void main(IPlatformLeaderboard& leaderboard);
static bool renderNames();
static bool useFancyGraphics();
static bool useAmbientOcclusion();

View file

@ -11,7 +11,7 @@
#include "app/common/App_structs.h"
#include "app/linux/LinuxGame.h"
#include "platform/leaderboard/leaderboard.h"
#include "platform/leaderboard/IPlatformLeaderboard.h"
#include "minecraft/stats/Achievement.h"
#include "minecraft/stats/Achievements.h"
#include "minecraft/stats/GenericStats.h"
@ -29,7 +29,8 @@ Stat** StatsCounter::LARGE_STATS[] = {&Stats::walkOneM, &Stats::swimOneM,
std::unordered_map<Stat*, int> StatsCounter::statBoards;
StatsCounter::StatsCounter() {
StatsCounter::StatsCounter(IPlatformLeaderboard& leaderboard)
: m_leaderboard(leaderboard) {
requiresSave = false;
saveCounter = 0;
modifiedBoards = 0;
@ -248,9 +249,9 @@ void StatsCounter::save(int player, bool force) {
}
void StatsCounter::flushLeaderboards() {
if (PlatformLeaderboard.OpenSession()) {
if (m_leaderboard.OpenSession()) {
writeStats();
PlatformLeaderboard.FlushStats();
m_leaderboard.FlushStats();
} else {
Log::info(
"Failed to open a session in order to write to leaderboard\n");
@ -264,9 +265,9 @@ void StatsCounter::flushLeaderboards() {
}
void StatsCounter::saveLeaderboards() {
if (PlatformLeaderboard.OpenSession()) {
if (m_leaderboard.OpenSession()) {
writeStats();
PlatformLeaderboard.CloseSession();
m_leaderboard.CloseSession();
} else {
Log::info(
"Failed to open a session in order to write to leaderboard\n");

View file

@ -2,6 +2,7 @@
#include <cstdint>
#include <unordered_map>
class IPlatformLeaderboard;
class Stat;
class Achievement;
class StatsSyncher;
@ -70,8 +71,13 @@ private:
static std::unordered_map<Stat*, int> statBoards;
int flushCounter;
// Borrowed from the composition root - StatsCounter does not own the
// backend. The reference is valid for the lifetime of the StatsCounter
// (the leaderboard outlives all StatsCounter instances).
IPlatformLeaderboard& m_leaderboard;
public:
StatsCounter();
explicit StatsCounter(IPlatformLeaderboard& leaderboard);
void award(Stat* stat, unsigned int difficulty, unsigned int count);
bool hasTaken(Achievement* ach);
bool canTake(Achievement* ach);