Merge pull request #678 from Daft-Freak/no-test

Remove test code from logo example
diff --git a/32blit/engine/timer.cpp b/32blit/engine/timer.cpp
index 71ad4e5..d269dc6 100644
--- a/32blit/engine/timer.cpp
+++ b/32blit/engine/timer.cpp
@@ -8,6 +8,19 @@
 
   Timer::Timer() = default;
 
+  Timer::Timer(TimerCallback callback, uint32_t duration, int32_t loops) {
+    init(callback, duration, loops);
+  }
+
+  Timer::~Timer() {
+    for(auto it = timers.begin(); it != timers.end(); ++it) {
+      if(*it == this) {
+        timers.erase(it);
+        break;
+      }
+    }
+  }
+
   /**
    * Initialize the timer.
    *
@@ -19,21 +32,41 @@
     this->callback = callback;
     this->duration = duration;
     this->loops = loops;
-    timers.push_back(this);
   }
 
   /**
    * Start the timer.
    */
   void Timer::start() {
-    this->started = blit::now();
+    if(state == UNINITIALISED)
+      timers.push_back(this);
+
+    if(state == PAUSED)
+      started = blit::now() - (paused - started); // Modify start time based on when timer was paused.
+    else {
+      started = blit::now();
+      loop_count = 0;
+    }
+
     this->state = RUNNING;
   }
 
   /**
+   * Pause the timer.
+   */
+  void Timer::pause() {
+    if (state != RUNNING) return;
+
+    paused = blit::now();
+    state = PAUSED;
+  }
+
+  /**
    * Stop the running timer.
    */
   void Timer::stop() {
+    if(state == UNINITIALISED) return;
+
     this->state = STOPPED;
   }
 
@@ -51,9 +84,9 @@
           }
           else
           {
-            t->loops--;
+            t->loop_count++;
             t->started = time;
-            if (t->loops == 0){
+            if (t->loop_count == t->loops){
               t->state = Timer::FINISHED;
             }
           }
diff --git a/32blit/engine/timer.hpp b/32blit/engine/timer.hpp
index de9d580..a96f9cf 100644
--- a/32blit/engine/timer.hpp
+++ b/32blit/engine/timer.hpp
@@ -6,26 +6,26 @@
 namespace blit {
 
   struct Timer {
-    using TimerCallback = void (*)(Timer &timer);
+    using TimerCallback = std::function<void (Timer &timer)>;
 
-    // uint32_t callback;                      // reference to Lua callback function (can be obtained via `ref = _G['function_name']`)
-    
     TimerCallback callback = nullptr;
-    void *user_data = nullptr;
-   
+
     uint32_t duration = 0;                  // how many milliseconds between callbacks
     uint32_t started = 0;                   // system time when timer started in milliseconds
-    int16_t loops = -1;                     // number of times to repeat timer (-1 == forever)
-    enum state {                            // state of the timer 
-      STOPPED, 
-      RUNNING, 
+    uint32_t paused = 0;                    // time when timer was paused
+    int32_t loops = -1, loop_count = 0;     // number of times to repeat timer (-1 == forever)
+    enum state {                            // state of the timer
+      UNINITIALISED,
+      STOPPED,
+      RUNNING,
       PAUSED,
       FINISHED
     };
-    uint8_t state = STOPPED;
+    uint8_t state = UNINITIALISED;
 
     void init(TimerCallback callback, uint32_t duration, int32_t loops = -1);
     void start();
+    void pause();
     void stop();
 
     bool is_running()   { return this->state == RUNNING; }
@@ -34,16 +34,9 @@
     bool is_finished()  { return this->state == FINISHED; }
 
     Timer();
-  };
-
-  extern std::vector<Timer *> timers;
-
-  struct timer_event_t {
-
+    Timer(TimerCallback callback, uint32_t duration, int32_t loops = -1);
+    ~Timer();
   };
 
   extern void update_timers(uint32_t time);
-
-  //extern std::vector<timer *> timers;  
-
 }
diff --git a/32blit/engine/tweening.cpp b/32blit/engine/tweening.cpp
index 06b54ce..4544e3a 100644
--- a/32blit/engine/tweening.cpp
+++ b/32blit/engine/tweening.cpp
@@ -10,6 +10,21 @@
 namespace blit {
   std::vector<Tween *> tweens;
 
+  Tween::Tween() = default;
+
+  Tween::Tween(TweenFunction function, float start, float end, uint32_t duration, int32_t loops) {
+    init(function, start, end, duration, loops);
+  }
+
+  Tween::~Tween() {
+    for(auto it = tweens.begin(); it != tweens.end(); ++it) {
+      if(*it == this) {
+        tweens.erase(it);
+        break;
+      }
+    }
+  }
+
   /**
    * Initialize the tween.
    *
@@ -26,23 +41,42 @@
     this->to = to;
     this->duration = duration;
     this->loop_count = 0;
-    tweens.push_back(this);
   }
 
   /**
    * Start the tween.
    */
   void Tween::start() {
-    this->started = blit::now();
-    this->loop_count = 0;
+    if(state == UNINITIALISED)
+      tweens.push_back(this);
+
+    if(state == PAUSED) {
+      started = blit::now() - (paused - started); // Modify start time based on when tween was paused.
+    } else {
+      this->started = blit::now();
+      this->loop_count = 0;
+      this->value = this->from;
+    }
+
     this->state = RUNNING;
-    this->value = this->from;
+  }
+
+  /**
+   * Pause the tween.
+   */
+  void Tween::pause() {
+    if (state != RUNNING) return;
+
+    paused = blit::now();
+    state = PAUSED;
   }
 
   /**
    * Stop the running tween.
    */
   void Tween::stop() {
+    if(state == UNINITIALISED) return;
+
     this->state = STOPPED;
   }
 
@@ -79,17 +113,17 @@
   void update_tweens(uint32_t time) {
     for (auto tween : tweens) {
       if (tween->state == Tween::RUNNING){
-        uint32_t elapsed = blit::now() - tween->started;
+        uint32_t elapsed = time - tween->started;
         tween->value = tween->function(elapsed, tween->from, tween->to, tween->duration);
 
         if (elapsed >= tween->duration) {
           if(tween->loops == -1){
-            tween->started = blit::now();
+            tween->started = time;
           }
           else
           {
             tween->loop_count++;
-            tween->started = blit::now();
+            tween->started = time;
             if (tween->loop_count == tween->loops){
               tween->state = Tween::FINISHED;
             }
diff --git a/32blit/engine/tweening.hpp b/32blit/engine/tweening.hpp
index 034180d..a181ee4 100644
--- a/32blit/engine/tweening.hpp
+++ b/32blit/engine/tweening.hpp
@@ -7,9 +7,8 @@
   const uint32_t LINEAR = 1UL << 0;
 
   struct Tween {
-    using TweenFunction = float (*)(uint32_t t, float b, float c, uint32_t d);
+    using TweenFunction = std::function<float(uint32_t t, float b, float c, uint32_t d)>;
     TweenFunction function = nullptr;
-    void *user_data = nullptr;
 
     float from = 0.0f;
     float to = 1.0f;
@@ -19,23 +18,30 @@
     int32_t loops = -1;
     int32_t loop_count = 0;
     uint32_t started = 0;
+    uint32_t paused = 0;                    // time when tween was paused
 
     enum state {
-      STOPPED, 
-      RUNNING, 
+      UNINITIALISED,
+      STOPPED,
+      RUNNING,
       PAUSED,
       FINISHED
     };
-    uint8_t state = STOPPED;
+    uint8_t state = UNINITIALISED;
 
     void init(TweenFunction function, float start, float end, uint32_t duration, int32_t loops = -1);
     void start();
+    void pause();
     void stop();
 
     bool is_running()   { return this->state == RUNNING; }
     bool is_paused()    { return this->state == PAUSED; }
     bool is_stopped()   { return this->state == STOPPED; }
     bool is_finished()  { return this->state == FINISHED; }
+
+    Tween();
+    Tween(TweenFunction function, float start, float end, uint32_t duration, int32_t loops = -1);
+    ~Tween();
   };
 
   extern std::vector<Tween *> tweens;
diff --git a/examples/tween-demo/tween-demo.cpp b/examples/tween-demo/tween-demo.cpp
index 2c3b0bf..d251e72 100644
--- a/examples/tween-demo/tween-demo.cpp
+++ b/examples/tween-demo/tween-demo.cpp
@@ -71,4 +71,11 @@
     tween.function = tween_funcs[current_tween_func].func;

     tween.start();

   }

-}
\ No newline at end of file
+

+  if(buttons.released & Button::A) {

+    if(tween.is_paused())

+      tween.start();

+    else

+      tween.pause();

+  }

+}