]> git.localhorst.tv Git - blank.git/commitdiff
enhanced application state control
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 11 Aug 2015 08:06:11 +0000 (10:06 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 11 Aug 2015 08:06:11 +0000 (10:06 +0200)
src/app/State.hpp
src/app/UnloadState.cpp
src/app/UnloadState.hpp
src/app/WorldState.cpp
src/app/WorldState.hpp
src/app/app.cpp
src/app/runtime.cpp

index 2bdd41b238f87518cd56d649add03d0fd11c39c1..86ff0ad36c84852167f4bbb34b321dcdc7d8210b 100644 (file)
@@ -6,16 +6,28 @@
 
 namespace blank {
 
+class Application;
 class Viewport;
 
 struct State {
 
+       friend class Application;
+
        virtual void Handle(const SDL_Event &) = 0;
 
        virtual void Update(int dt) = 0;
 
        virtual void Render(Viewport &) = 0;
 
+
+private:
+       int ref_count = 0;
+
+       virtual void OnEnter() { }
+       virtual void OnResume() { }
+       virtual void OnPause() { }
+       virtual void OnExit() { }
+
 };
 
 };
index 49801bfbc5dcaab19ed7a48d6c994d25959e8ccb..9da6989d128b5403e018daa4a4e39136fc695d8f 100644 (file)
@@ -22,6 +22,14 @@ UnloadState::UnloadState(Environment &env, ChunkLoader &loader)
 }
 
 
+void UnloadState::OnResume() {
+       cur = loader.Loaded().begin();
+       end = loader.Loaded().end();
+       done = 0;
+       total = loader.Loaded().size();
+}
+
+
 void UnloadState::Handle(const SDL_Event &) {
        // ignore everything
 }
index 56394bb60c8105e4aee5eeb20cf4b7b26aff3b1c..6d5cea71ae2a89ecd3f417ad286a4ba7705e639b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef BLANK_APP_PRELOADSTATE_HPP_
-#define BLANK_APP_PRELOADSTATE_HPP_
+#ifndef BLANK_APP_UNLOADSTATE_HPP_
+#define BLANK_APP_UNLOADSTATE_HPP_
 
 #include "State.hpp"
 
@@ -22,6 +22,8 @@ class UnloadState
 public:
        UnloadState(Environment &, ChunkLoader &);
 
+       void OnResume();
+
        void Handle(const SDL_Event &) override;
        void Update(int dt) override;
        void Render(Viewport &) override;
index 86e3eac93bdaa619fd344d7709f92b6ff4a65421..372b659f8975b4c564bc73a8d91485abb6eafd69 100644 (file)
@@ -1,7 +1,6 @@
 #include "WorldState.hpp"
 
 #include "Environment.hpp"
-#include "UnloadState.hpp"
 
 #include <SDL.h>
 
@@ -17,11 +16,18 @@ WorldState::WorldState(
 : env(env)
 , world(env.assets, wc, save)
 , spawner(world)
-, interface(ic, env, world) {
+, interface(ic, env, world)
+, preload(env, world.Loader())
+, unload(env, world.Loader()) {
 
 }
 
 
+void WorldState::OnEnter() {
+       env.state.Push(&preload);
+}
+
+
 void WorldState::Handle(const SDL_Event &event) {
        switch (event.type) {
                case SDL_KEYDOWN:
@@ -43,8 +49,7 @@ void WorldState::Handle(const SDL_Event &event) {
                        interface.Handle(event.wheel);
                        break;
                case SDL_QUIT:
-                       // don't care about this leak just now
-                       env.state.Switch(new UnloadState(env, world.Loader()));
+                       env.state.Switch(&unload);
                        break;
                default:
                        break;
index 38f894420b717115c0cb049beb67c1f130b2b702..6ab613f85e88634b6dd03bf276964276330a649d 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef BLANK_APP_WORLDSTATE_HPP_
 #define BLANK_APP_WORLDSTATE_HPP_
 
+#include "PreloadState.hpp"
 #include "State.hpp"
+#include "UnloadState.hpp"
 #include "../ai/Spawner.hpp"
 #include "../ui/Interface.hpp"
 #include "../world/World.hpp"
@@ -22,6 +24,8 @@ public:
                const WorldSave &
        );
 
+       void OnEnter() override;
+
        void Handle(const SDL_Event &) override;
        void Update(int dt) override;
        void Render(Viewport &) override;
@@ -34,6 +38,9 @@ private:
        Spawner spawner;
        Interface interface;
 
+       PreloadState preload;
+       UnloadState unload;
+
 };
 
 }
index 4a4769b4c688ae4cd7462e983040474536fd4ee3..880dc7118eaf2fcaa43e93b2a2e92c6ec91de5f1 100644 (file)
@@ -145,18 +145,41 @@ void Application::Render() {
 
 
 void Application::PushState(State *s) {
+       if (!states.empty()) {
+               states.top()->OnPause();
+       }
        states.emplace(s);
+       ++s->ref_count;
+       if (s->ref_count == 1) {
+               s->OnEnter();
+       }
+       s->OnResume();
 }
 
 State *Application::PopState() {
        State *s = states.top();
        states.pop();
+       s->OnPause();
+       s->OnExit();
+       if (!states.empty()) {
+               states.top()->OnResume();
+       }
        return s;
 }
 
 State *Application::SwitchState(State *s_new) {
        State *s_old = states.top();
        states.top() = s_new;
+       --s_old->ref_count;
+       ++s_new->ref_count;
+       s_old->OnPause();
+       if (s_old->ref_count == 0) {
+               s_old->OnExit();
+       }
+       if (s_new->ref_count == 1) {
+               s_new->OnEnter();
+       }
+       s_new->OnResume();
        return s_old;
 }
 
index 32a401220215dbeeb557e3a53e9b6a5f7ccf6737..85d8280987b8459f3e50fbaac37d026a5924a92a 100644 (file)
@@ -1,6 +1,5 @@
 #include "Application.hpp"
 #include "Environment.hpp"
-#include "PreloadState.hpp"
 #include "Runtime.hpp"
 #include "WorldState.hpp"
 
@@ -244,9 +243,6 @@ int Runtime::Execute() {
        WorldState world_state(env, config.interface, config.world, save);
        app.PushState(&world_state);
 
-       PreloadState preloader(env, world_state.GetWorld().Loader());
-       app.PushState(&preloader);
-
        switch (mode) {
                default:
                case NORMAL: