Fixing the clock signal to use GLib::Dispatcher to emit the signal so the main thread updates the clockLabel widget

This commit is contained in:
Bernardo Magri
2025-03-11 17:14:32 +00:00
parent b6a6e16d3a
commit 4ff86eb027
4 changed files with 36 additions and 19 deletions

View File

@@ -12,6 +12,10 @@ MineField::MineField(int cols, int rows, int mines): m_rows(rows),
} }
} }
MineField::~MineField() {
// stopTimer();
}
void MineField::timerTick() { void MineField::timerTick() {
auto start = std::chrono::system_clock::now(); auto start = std::chrono::system_clock::now();
@@ -35,7 +39,9 @@ void MineField::startTimer() {
void MineField::stopTimer() { void MineField::stopTimer() {
m_timerRunning = false; m_timerRunning = false;
m_timerThread.join(); if(m_timerThread.joinable()) {
m_timerThread.join();
}
} }
void MineField::initBombs(int x, int y) { 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) { bool MineField::openCell(int x, int y) {
if(isBomb(x, y)) { if(isBomb(x, y)) {
m_exploded = true; m_exploded = true;
timerThread.join();
gameOverSignal.emit(); gameOverSignal.emit();
stopTimer(); stopTimer();
return false; return false;

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <atomic>
#include <sigc++/signal.h> #include <sigc++/signal.h>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -26,8 +27,8 @@ class MineField {
int m_openCells; int m_openCells;
bool m_exploded; bool m_exploded;
bool m_gameWon; bool m_gameWon;
bool m_timerRunning;
size_t m_time; size_t m_time;
std::atomic_bool m_timerRunning;
std::thread m_timerThread; std::thread m_timerThread;
void computeBombsNearby(int x, int y); void computeBombsNearby(int x, int y);
void openNeighboorhood(int x, int y); void openNeighboorhood(int x, int y);
@@ -38,6 +39,7 @@ class MineField {
public: public:
MineField(int cols, int rows, int mines); MineField(int cols, int rows, int mines);
~MineField();
void initBombs(int x, int y); void initBombs(int x, int y);
bool isBomb(int x, int y); bool isBomb(int x, int y);
bool isFlagged(int x, int y); bool isFlagged(int x, int y);
@@ -49,6 +51,7 @@ public:
int getRows() {return m_rows; }; int getRows() {return m_rows; };
bool toggleFlag(int x, int y); bool toggleFlag(int x, int y);
int getRemainingFlags() {return m_remainingFlags; }; int getRemainingFlags() {return m_remainingFlags; };
size_t getCurrentTime() {return m_time; };
int getTotalMines() {return m_totalMines; }; int getTotalMines() {return m_totalMines; };
void startNewGame(int cols, int rows, int mines); void startNewGame(int cols, int rows, int mines);

View File

@@ -1,5 +1,6 @@
#include "window.hpp" #include "window.hpp"
#include "gdkmm/texture.h" #include "gdkmm/texture.h"
#include "sigc++/adaptors/bind.h"
#include "sigc++/functors/mem_fun.h" #include "sigc++/functors/mem_fun.h"
@@ -159,26 +160,29 @@ void MainWindow::updateCell(int x, int y) {
// return true; // return true;
// } // }
void MainWindow::gameOver() { void MainWindow::gameOver() {
clockSignalConn.disconnect(); //clockSignalConn.disconnect();
//std::cout << "Signal gameOver emmited\n"; //std::cout << "Signal gameOver emmited\n";
} }
void MainWindow::updateClockLabel(size_t time) void MainWindow::updateClockLabel()
{ {
//++m_elapsedTime;
//int deciseconds = m_elapsedTime % 10; size_t time = field.getCurrentTime();
//int seconds = (m_elapsedTime / 10) % 60;
//int minutes = (m_elapsedTime /600) % 60;
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 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), minutes), \
// Glib::ustring::format(std::setfill(L'0'), std::setw(2), seconds), \ Glib::ustring::format(std::setfill(L'0'), std::setw(2), seconds), \
// Glib::ustring::format(std::setfill(L'0'), std::setw(1), deciseconds)); Glib::ustring::format(std::setfill(L'0'), std::setw(1), deciseconds));
clockLabel.set_label(msg); clockLabel.set_label(msg);
//return true; }
void MainWindow::handleClockSig(size_t time) {
(void)time;
m_clockDispatch.emit();
} }
MainWindow::MainWindow() MainWindow::MainWindow()
@@ -212,8 +216,8 @@ MainWindow::MainWindow()
//flagLabel.set_hexpand(true); //flagLabel.set_hexpand(true);
clockLabel.set_margin_top(12); clockLabel.set_margin_top(12);
clockLabel.set_margin_start(12); //clockLabel.set_margin_start(12);
clockLabel.set_margin_end(12); //Clocklabel.set_margin_end(12);
clockLabel.set_hexpand(true); clockLabel.set_hexpand(true);
Glib::ustring clockmsg = Glib::ustring::compose("Elapsed time: 00:00.0"); Glib::ustring clockmsg = Glib::ustring::compose("Elapsed time: 00:00.0");
clockLabel.set_label(clockmsg); clockLabel.set_label(clockmsg);
@@ -275,7 +279,9 @@ MainWindow::MainWindow()
//optionButton.set_icon_name("open-menu"); //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(); //if (clockSignalConn.connected()) clockSignalConn.disconnect();
//elapsedTime = 0; //elapsedTime = 0;
//clockSignalConn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::updateClockLabel), 100); //clockSignalConn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::updateClockLabel), 100);

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "glibmm/dispatcher.h"
#include "minefield.hpp" #include "minefield.hpp"
#include <memory> #include <memory>
#include <gtkmm.h> #include <gtkmm.h>
@@ -32,10 +33,12 @@ class MainWindow : public Gtk::Window
void updateCell(int x, int y); void updateCell(int x, int y);
void openBombs(); void openBombs();
void updateFlagsLabel(int flags); void updateFlagsLabel(int flags);
void updateClockLabel(size_t time); void updateClockLabel();
void handleClockSig(size_t);
void gameWon(); void gameWon();
void gameOver(); void gameOver();
sigc::connection clockSignalConn; sigc::connection clockSignalConn;
Glib::Dispatcher m_clockDispatch;
// void OpenNearCells(int index); // void OpenNearCells(int index);
// void Explode();xo // void Explode();xo
// bool AllCellsOpened(); // bool AllCellsOpened();