From 26c8f41bb14f1096caccddfa77e55def85eface1 Mon Sep 17 00:00:00 2001
From: Joshua Saxby <Joshua2.Saxby@live.uwe.ac.uk>
Date: Sun, 9 Feb 2020 01:18:58 +0000
Subject: [PATCH] Revert "Perhaps C++ event-handlers are broken..."

This reverts commit f117a6faf146d065103562a2e21a369fa5c92588.
---
 source/main.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 112 insertions(+), 7 deletions(-)

diff --git a/source/main.cpp b/source/main.cpp
index b9bbbb4..26941b5 100755
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -17,23 +17,128 @@
 
 #include "MicroBit.h"
 
-MicroBit micro_bit;
 
-void event_handler(MicroBitEvent) {
-    micro_bit.display.printAsync("A", 200);
+/**
+ * @brief Main class responsible for the game loop and logic
+ */
+class Game {
+public:
+    /**
+     * @brief Constructor
+     * @details takes reference to the micro-bit instance for the sake of not
+     * using global variables.
+     */
+    Game(MicroBit& micro_bit);
+
+    /**
+     * @brief Starts a new run of the game
+     * @note method blocks until game over.
+     */
+    void run();
+
+    /* begin event handler methods */
+
+    /**
+     * Handles Button A Press event
+     */
+    void press_button_a(MicroBitEvent e);
+
+    /**
+     * Handles Button B Press event
+     */
+    void press_button_b(MicroBitEvent e);
+
+    /* end event handler methods */
+
+private:
+    /**
+     * @brief Draws whatever's in the screen buffer to display
+     */
+    void draw();
+
+    // reference to our MicroBit instance
+    MicroBit& micro_bit;
+    // internal screen-buffer, which we draw to first before pasting to display
+    MicroBitImage screen_buffer;
+};
+
+Game::Game(MicroBit& micro_bit)
+    : micro_bit(micro_bit)
+    , screen_buffer(5, 5) // our screen buffer mirrors the display dimensions
+{}
+
+void Game::run() {
+    // this->micro_bit.display.scroll("NEW GAME!");
+    // init screen display mode, to be sure it is in a known-state
+    // TODO: consider changing to greyscale to allow "mutli-coloured" blocks
+    // this->micro_bit.display.setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE);
+    // register event-handlers
+    this->micro_bit.messageBus.listen(
+        MICROBIT_ID_BUTTON_A,
+        MICROBIT_BUTTON_EVT_CLICK,
+        this,
+        &Game::press_button_a
+    );
+    this->micro_bit.messageBus.listen(
+        MICROBIT_ID_BUTTON_B,
+        MICROBIT_BUTTON_EVT_CLICK,
+        this,
+        &Game::press_button_b
+    );
+    while (true) { // TODO: change to use game-over condition
+        // this->draw(); // render screen buffer
+        // sleep to conserve CPU cycles and allow other fibers a chance to run
+        this->micro_bit.sleep(100); // a 100ms sleep gives us a 10Hz tick-rate
+    }
+    // TODO: add the rest of the game logic
+    this->micro_bit.display.scroll("GAME OVER!");
+    // TODO: display final score
+    // TODO: de-register event-handlers
+    this->micro_bit.messageBus.ignore(
+        MICROBIT_ID_BUTTON_A,
+        MICROBIT_BUTTON_EVT_CLICK,
+        this,
+        &Game::press_button_a
+    );
+    this->micro_bit.messageBus.ignore(
+        MICROBIT_ID_BUTTON_B,
+        MICROBIT_BUTTON_EVT_CLICK,
+        this,
+        &Game::press_button_b
+    );
+}
+
+void Game::draw() {
+    // XXX: debug drawing, fill the screen buffer with black
+    this->screen_buffer.clear();
+    // render our screen buffer
+    this->micro_bit.display.image.paste(this->screen_buffer);
 }
 
+void Game::press_button_a(MicroBitEvent e) {
+    // XXX: debug
+    this->micro_bit.display.print("A");
+}
+
+void Game::press_button_b(MicroBitEvent e) {
+    // XXX: debug
+    this->micro_bit.display.print("B");
+}
+
+
+MicroBit micro_bit;
 
 int main() {
     // Initialise the micro:bit runtime.
     micro_bit.init();
 
-    micro_bit.messageBus.listen(
-        MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, event_handler
-    );
+    // startup message displays the name of the game
+    micro_bit.display.scroll("BLOCKS!");
 
+    // infinitely start new games
     while (true) {
-        micro_bit.sleep(10); // 10ms sleep, or 100Hz tick rate
+        Game game(micro_bit);
+        game.run();
     }
 
     // TODO: potentially remove this call, if clarified that it is not required.
-- 
GitLab