Bladeren bron

Add state machine
WIP, still needs a way to be controlled from within the states.

Streetwalrus Einstein 10 jaren geleden
bovenliggende
commit
f80c104d5a
4 gewijzigde bestanden met toevoegingen van 88 en 35 verwijderingen
  1. 1 0
      include/State.h
  2. 23 0
      include/StateMachine.h
  3. 60 0
      src/StateMachine.cpp
  4. 4 35
      src/main.cpp

+ 1 - 0
include/State.h

@@ -10,6 +10,7 @@ namespace WalrusRPG
         class State
         {
           public:
+            virtual ~State(){};
             virtual void update(unsigned dt) = 0;
             virtual void render(unsigned dt) = 0;
         };

+ 23 - 0
include/StateMachine.h

@@ -0,0 +1,23 @@
+#ifndef INCLUDE_STATEMACHINE_H
+#define INCLUDE_STATEMACHINE_H
+
+#include <TINYSTL/vector.h>
+#include "State.h"
+
+namespace WalrusRPG
+{
+    class StateMachine
+    {
+      protected:
+        tinystl::vector<WalrusRPG::States::State *> stack;
+
+      public:
+        StateMachine(WalrusRPG::States::State *state);
+        ~StateMachine();
+        void push(WalrusRPG::States::State *state);
+        void pop();
+        void run();
+    };
+}
+
+#endif

+ 60 - 0
src/StateMachine.cpp

@@ -0,0 +1,60 @@
+#include "StateMachine.h"
+#include "Timers.h"
+#include "Graphics.h"
+#include "Text.h"
+#include "version.h"
+#include <os.h>
+
+#define STATEMACHINE WalrusRPG::StateMachine
+
+STATEMACHINE::StateMachine(WalrusRPG::States::State *state)
+{
+    push(state);
+}
+
+STATEMACHINE::~StateMachine()
+{
+}
+
+void STATEMACHINE::push(WalrusRPG::States::State *state)
+{
+    stack.push_back(state);
+}
+
+void STATEMACHINE::pop()
+{
+    delete stack.back();
+    stack.pop_back();
+}
+
+void STATEMACHINE::run()
+{
+    Timers::mode(0, true, false, false, 1, true);
+    Timers::load(0, 0);
+    const unsigned loop_time = 546; // 32768Hz/60
+    unsigned loop_next = -loop_time;
+    unsigned last_frame = 0;
+
+    while (!stack.empty())
+    {
+        stack.back()->update(loop_time);
+
+        if (Timers::read(0) > loop_next)
+        {
+            stack.back()->render(loop_time);
+            Graphics::Text::print_format(0, 0, "WalrusRPG test build %s", git_version);
+            unsigned frame_stamp = Timers::read(0);
+            Graphics::Text::print_format(0, 240 - 8, "%u fps",
+                                         32768 / (last_frame - frame_stamp));
+            last_frame = frame_stamp;
+            Graphics::buffer_swap_render();
+        }
+
+        if (isKeyPressed(KEY_NSPIRE_ESC))
+            this->pop();
+
+        while (Timers::read(0) > loop_next)
+            ;
+        loop_next -= loop_time;
+    }
+}

+ 4 - 35
src/main.cpp

@@ -11,43 +11,10 @@
 #include "version.h"
 #include "Interrupts.h"
 #include "StateMap.h"
+#include "StateMachine.h"
 
 using namespace WalrusRPG;
 
-void map_loop(unsigned x, unsigned y, Map &map)
-{
-    // Free-running, no interrupts, divider = 1, 32 bit, wrapping
-    Timers::mode(0, true, false, false, 1, true);
-    Timers::load(0, 0);
-    unsigned loop_time = 546; // 32768Hz/60ups
-    unsigned loop_next = -loop_time;
-
-    unsigned keep_running = 1;
-
-    States::StateMap statemap(x, y, map);
-
-    while (keep_running)
-    {
-        if (isKeyPressed(KEY_NSPIRE_ESC))
-            keep_running = 0;
-
-        statemap.update(1);
-
-        // Frameskip
-        if (Timers::read(0) > loop_next)
-        {
-            statemap.render(1);
-            Graphics::Text::print_format(0, 0, "WalrusRPG test build %s", git_version);
-            Graphics::buffer_swap_render();
-        }
-
-        // Frame limiting
-        while (Timers::read(0) > loop_next)
-            ;
-        loop_next -= loop_time;
-    }
-}
-
 int main(int argc, char *argv[])
 {
     UNUSED(argc);
@@ -115,7 +82,9 @@ int main(int argc, char *argv[])
     stripe22.push_back({21, 41});
     map.anim.add_animation(21, {stripe21, true});
     map.anim.add_animation(22, {stripe22, true});
-    map_loop(0, 0, map);
+
+    StateMachine machine(new States::StateMap(0, 0, map));
+    machine.run();
 
     Interrupts::off();
     Timers::restore(0);