From 4ff86eb0279c3302c9fcb71fbec58b4274d786d2 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Tue, 11 Mar 2025 17:14:32 +0000 Subject: [PATCH] Fixing the clock signal to use GLib::Dispatcher to emit the signal so the main thread updates the clockLabel widget --- src/minefield.cpp | 9 +++++++-- src/minefield.hpp | 5 ++++- src/window.cpp | 36 +++++++++++++++++++++--------------- src/window.hpp | 5 ++++- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/minefield.cpp b/src/minefield.cpp index a7939b0..c0bb24b 100644 --- a/src/minefield.cpp +++ b/src/minefield.cpp @@ -12,6 +12,10 @@ MineField::MineField(int cols, int rows, int mines): m_rows(rows), } } +MineField::~MineField() { + // stopTimer(); +} + void MineField::timerTick() { auto start = std::chrono::system_clock::now(); @@ -35,7 +39,9 @@ void MineField::startTimer() { void MineField::stopTimer() { m_timerRunning = false; - m_timerThread.join(); + if(m_timerThread.joinable()) { + m_timerThread.join(); + } } void MineField::initBombs(int x, int y) { @@ -63,7 +69,6 @@ void MineField::initBombs(int x, int y) { bool MineField::openCell(int x, int y) { if(isBomb(x, y)) { m_exploded = true; - timerThread.join(); gameOverSignal.emit(); stopTimer(); return false; diff --git a/src/minefield.hpp b/src/minefield.hpp index a877aa7..7f6b44b 100644 --- a/src/minefield.hpp +++ b/src/minefield.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -26,8 +27,8 @@ class MineField { int m_openCells; bool m_exploded; bool m_gameWon; - bool m_timerRunning; size_t m_time; + std::atomic_bool m_timerRunning; std::thread m_timerThread; void computeBombsNearby(int x, int y); void openNeighboorhood(int x, int y); @@ -38,6 +39,7 @@ class MineField { public: MineField(int cols, int rows, int mines); + ~MineField(); void initBombs(int x, int y); bool isBomb(int x, int y); bool isFlagged(int x, int y); @@ -49,6 +51,7 @@ public: int getRows() {return m_rows; }; bool toggleFlag(int x, int y); int getRemainingFlags() {return m_remainingFlags; }; + size_t getCurrentTime() {return m_time; }; int getTotalMines() {return m_totalMines; }; void startNewGame(int cols, int rows, int mines); diff --git a/src/window.cpp b/src/window.cpp index a4941c3..7ab40e8 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,5 +1,6 @@ #include "window.hpp" #include "gdkmm/texture.h" +#include "sigc++/adaptors/bind.h" #include "sigc++/functors/mem_fun.h" @@ -159,26 +160,29 @@ void MainWindow::updateCell(int x, int y) { // return true; // } void MainWindow::gameOver() { - clockSignalConn.disconnect(); + //clockSignalConn.disconnect(); //std::cout << "Signal gameOver emmited\n"; } -void MainWindow::updateClockLabel(size_t time) +void MainWindow::updateClockLabel() { - //++m_elapsedTime; - //int deciseconds = m_elapsedTime % 10; - //int seconds = (m_elapsedTime / 10) % 60; - //int minutes = (m_elapsedTime /600) % 60; + size_t time = field.getCurrentTime(); - Glib::ustring msg = Glib::ustring::compose("Elapsed time: %1", time); + int deciseconds = (time / 100) % 10; + int seconds = (time / 1000) % 60; + int minutes = (time /60000) % 60; - // Glib::ustring msg = Glib::ustring::compose("Elapsed time: %1:%2.%3", \ - // Glib::ustring::format(std::setfill(L'0'), std::setw(2), minutes), \ - // Glib::ustring::format(std::setfill(L'0'), std::setw(2), seconds), \ - // Glib::ustring::format(std::setfill(L'0'), std::setw(1), deciseconds)); + Glib::ustring msg = Glib::ustring::compose("Elapsed time: %1:%2.%3", \ + Glib::ustring::format(std::setfill(L'0'), std::setw(2), minutes), \ + Glib::ustring::format(std::setfill(L'0'), std::setw(2), seconds), \ + Glib::ustring::format(std::setfill(L'0'), std::setw(1), deciseconds)); clockLabel.set_label(msg); - //return true; +} + +void MainWindow::handleClockSig(size_t time) { + (void)time; + m_clockDispatch.emit(); } MainWindow::MainWindow() @@ -212,8 +216,8 @@ MainWindow::MainWindow() //flagLabel.set_hexpand(true); clockLabel.set_margin_top(12); - clockLabel.set_margin_start(12); - clockLabel.set_margin_end(12); + //clockLabel.set_margin_start(12); + //Clocklabel.set_margin_end(12); clockLabel.set_hexpand(true); Glib::ustring clockmsg = Glib::ustring::compose("Elapsed time: 00:00.0"); clockLabel.set_label(clockmsg); @@ -275,7 +279,9 @@ MainWindow::MainWindow() //optionButton.set_icon_name("open-menu"); - field.timerSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateClockLabel))); + field.timerSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::handleClockSig))); + m_clockDispatch.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateClockLabel))); + //field.timerSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateClockLabel))); //if (clockSignalConn.connected()) clockSignalConn.disconnect(); //elapsedTime = 0; //clockSignalConn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::updateClockLabel), 100); diff --git a/src/window.hpp b/src/window.hpp index eb7a5fb..ee6f112 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -1,5 +1,6 @@ #pragma once +#include "glibmm/dispatcher.h" #include "minefield.hpp" #include #include @@ -32,10 +33,12 @@ class MainWindow : public Gtk::Window void updateCell(int x, int y); void openBombs(); void updateFlagsLabel(int flags); - void updateClockLabel(size_t time); + void updateClockLabel(); + void handleClockSig(size_t); void gameWon(); void gameOver(); sigc::connection clockSignalConn; + Glib::Dispatcher m_clockDispatch; // void OpenNearCells(int index); // void Explode();xo // bool AllCellsOpened();