Leaderboard: clear button and hygiene for migrated legacy data
A scratch test earlier in development wrote a fake 42s Beginner record into the legacy ~/.config/minesweeper/leaderboard.ini, which the migration imported; as a stored best it can never be beaten by slower real games, so the popover showed a lower time than actually played. - Add a 'Clear scores' button to the leaderboard popover - Delete the legacy file after a successful migration so stale data can't be re-imported
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include <glibmm/keyfile.h>
|
#include <glibmm/keyfile.h>
|
||||||
#include <glibmm/miscutils.h>
|
#include <glibmm/miscutils.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string file_path() {
|
std::string file_path() {
|
||||||
@@ -19,9 +20,11 @@ void Leaderboard::load() {
|
|||||||
auto path = file_path();
|
auto path = file_path();
|
||||||
auto legacy = Glib::build_filename(
|
auto legacy = Glib::build_filename(
|
||||||
Glib::get_user_config_dir(), "minesweeper", "leaderboard.ini");
|
Glib::get_user_config_dir(), "minesweeper", "leaderboard.ini");
|
||||||
|
bool migrated = false;
|
||||||
if (!Glib::file_test(path, Glib::FileTest::EXISTS) &&
|
if (!Glib::file_test(path, Glib::FileTest::EXISTS) &&
|
||||||
Glib::file_test(legacy, Glib::FileTest::EXISTS)) {
|
Glib::file_test(legacy, Glib::FileTest::EXISTS)) {
|
||||||
path = legacy;
|
path = legacy;
|
||||||
|
migrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -32,6 +35,11 @@ void Leaderboard::load() {
|
|||||||
times_[group.raw()] = kf->get_integer(group, "best");
|
times_[group.raw()] = kf->get_integer(group, "best");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (migrated) {
|
||||||
|
// Stale legacy files can hold outdated/experimental data; drop it
|
||||||
|
// so it can never be re-imported after the current file is gone.
|
||||||
|
g_remove(legacy.c_str());
|
||||||
|
}
|
||||||
} catch (const Glib::Error&) {
|
} catch (const Glib::Error&) {
|
||||||
// No file yet or unreadable — start with an empty leaderboard
|
// No file yet or unreadable — start with an empty leaderboard
|
||||||
}
|
}
|
||||||
@@ -52,6 +60,12 @@ std::optional<int> Leaderboard::best_time(const std::string& difficulty) const {
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Leaderboard::clear() {
|
||||||
|
load();
|
||||||
|
times_.clear();
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
void Leaderboard::save() {
|
void Leaderboard::save() {
|
||||||
auto kf = Glib::KeyFile::create();
|
auto kf = Glib::KeyFile::create();
|
||||||
for (const auto& [difficulty, seconds] : times_) {
|
for (const auto& [difficulty, seconds] : times_) {
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ public:
|
|||||||
// Best time in seconds for the difficulty, if one exists.
|
// Best time in seconds for the difficulty, if one exists.
|
||||||
std::optional<int> best_time(const std::string& difficulty) const;
|
std::optional<int> best_time(const std::string& difficulty) const;
|
||||||
|
|
||||||
|
// Removes all recorded scores and rewrites the file.
|
||||||
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load();
|
void load();
|
||||||
void save();
|
void save();
|
||||||
|
|||||||
@@ -178,6 +178,14 @@ void MainWindow::refresh_leaderboard() {
|
|||||||
row->set_text(diff.name + ": " + time_str);
|
row->set_text(diff.name + ": " + time_str);
|
||||||
box_leaderboard_.append(*row);
|
box_leaderboard_.append(*row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* clear_btn = Gtk::make_managed<Gtk::Button>("Clear scores");
|
||||||
|
clear_btn->set_margin_top(8);
|
||||||
|
clear_btn->signal_clicked().connect([this]() {
|
||||||
|
leaderboard_.clear();
|
||||||
|
menu_leaderboard_.popdown(); // Rebuilds on next show
|
||||||
|
});
|
||||||
|
box_leaderboard_.append(*clear_btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setup_board() {
|
void MainWindow::setup_board() {
|
||||||
|
|||||||
Reference in New Issue
Block a user