ソースを参照

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

Bernardo Magri 10 ヶ月 前
コミット
4ff86eb027
4 ファイル変更36 行追加19 行削除
  1. 7 2
      src/minefield.cpp
  2. 4 1
      src/minefield.hpp
  3. 21 15
      src/window.cpp
  4. 4 1
      src/window.hpp

+ 7 - 2
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;

+ 4 - 1
src/minefield.hpp

@@ -1,5 +1,6 @@
 #pragma once
 
+#include <atomic>
 #include <sigc++/signal.h>
 #include <utility>
 #include <vector>
@@ -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);
 

+ 21 - 15
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);

+ 4 - 1
src/window.hpp

@@ -1,5 +1,6 @@
 #pragma once
 
+#include "glibmm/dispatcher.h"
 #include "minefield.hpp"
 #include <memory>
 #include <gtkmm.h>
@@ -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();