]> git.localhorst.tv Git - l2e.git/blobdiff - src/app/Application.cpp
made application state changes yet a bit safer
[l2e.git] / src / app / Application.cpp
index 19aa06a18543de3e1c7662a490098d794e8e0aca..29eaee781e9ba20780fafa2cc4bde331777d059a 100644 (file)
@@ -16,8 +16,7 @@ namespace app {
 Application::Application(sdl::InitScreen *screen, State *initialState)
 : screen(screen)
 , states()
-, last(SDL_GetTicks())
-, toPop(0) {
+, last(SDL_GetTicks()) {
        assert(screen && "cannot create application without screen");
        assert(initialState && "cannot create application without initial state");
        RealPushState(initialState);
@@ -33,40 +32,72 @@ State *Application::CurrentState() {
 }
 
 void Application::UpdateState() {
-       while (toPop > 0) {
-               RealPopState();
-               --toPop;
-       }
-       while (!toPush.empty()) {
-               State *s(toPush.front());
-               toPush.pop();
-               RealPushState(s);
+       while (!stateChanges.empty()) {
+               switch (stateChanges.front().type) {
+                       case StateCommand::PUSH:
+                               RealPushState(stateChanges.front().state);
+                               break;
+                       case StateCommand::POP:
+                               RealPopState();
+                               break;
+                       case StateCommand::CHANGE:
+                               RealChangeState(stateChanges.front().state);
+                               break;
+               }
+               stateChanges.pop();
        }
 }
 
 void Application::ChangeState(State *s) {
-       PopState();
-       PushState(s);
+       StateCommand cmd;
+       cmd.type = StateCommand::CHANGE;
+       cmd.state = s;
+       stateChanges.push(cmd);
 }
 
 void Application::PushState(State *s) {
-       toPush.push(s);
+       StateCommand cmd;
+       cmd.type = StateCommand::PUSH;
+       cmd.state = s;
+       stateChanges.push(cmd);
 }
 
-void Application::RealPushState(State *s) {
+void Application::PopState() {
+       StateCommand cmd;
+       cmd.type = StateCommand::POP;
+       cmd.state = 0;
+       stateChanges.push(cmd);
+}
+
+void Application::RealChangeState(State *s) {
+       if (!states.empty()) {
+               states.top()->PauseState(*this, screen->Screen());
+               states.top()->ExitState(*this, screen->Screen());
+               states.pop();
+       }
        states.push(s);
        s->EnterState(*this, screen->Screen());
+       s->ResumeState(*this, screen->Screen());
 }
 
-void Application::PopState() {
-       ++toPop;
+void Application::RealPushState(State *s) {
+       if (!states.empty()) {
+               states.top()->PauseState(*this, screen->Screen());
+       }
+       states.push(s);
+       s->EnterState(*this, screen->Screen());
+       s->ResumeState(*this, screen->Screen());
 }
 
 void Application::RealPopState() {
        if (states.empty()) return;
-       states.top()->ExitState();
+       states.top()->PauseState(*this, screen->Screen());
+       states.top()->ExitState(*this, screen->Screen());
        delete states.top();
        states.pop();
+       if (!states.empty()) {
+               states.top()->ResumeState(*this, screen->Screen());
+       }
 }
 
 void Application::Quit() {
@@ -92,8 +123,10 @@ void Application::Loop() {
        if (deltaT > 34) deltaT = 34;
 
        HandleEvents();
-       UpdateWorld(deltaT);
-       Render();
+       if (!StateChangePending()) {
+               UpdateWorld(deltaT);
+               Render();
+       }
 
        last = now;
        UpdateState();