X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fapp%2FApplication.cpp;h=830223ef0381c5025245cac2a6c09c1cce821895;hb=60e0b9e8ec660a4f6b8e500bf0b77a31bb817b45;hp=c1e4f15311526ec5f767078d5faf30d5d9a72eb5;hpb=dafa7913073e730f352db1c2a76f55bbff39475c;p=l2e.git diff --git a/src/app/Application.cpp b/src/app/Application.cpp index c1e4f15..830223e 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -1,23 +1,18 @@ -/* - * Application.cpp - * - * Created on: Apr 8, 2012 - * Author: holy - */ - #include "Application.h" #include "State.h" +#include "../sdl/InitScreen.h" #include namespace app { -Application::Application(sdl::InitScreen *screen, State *initialState) +Application::Application(sdl::InitScreen &screen, State *initialState) : screen(screen) , states() -, last(SDL_GetTicks()) { - assert(screen && "cannot create application without screen"); +, last(SDL_GetTicks()) +, remaining(0) +, inStateChage(false) { assert(initialState && "cannot create application without initial state"); RealPushState(initialState); } @@ -32,6 +27,7 @@ State *Application::CurrentState() { } void Application::UpdateState() { + inStateChage = true; while (!stateChanges.empty()) { switch (stateChanges.front().type) { case StateCommand::PUSH: @@ -46,57 +42,70 @@ void Application::UpdateState() { } stateChanges.pop(); } + inStateChage = false; } void Application::ChangeState(State *s) { - StateCommand cmd; - cmd.type = StateCommand::CHANGE; - cmd.state = s; - stateChanges.push(cmd); + if (inStateChage) { + RealChangeState(s); + } else { + StateCommand cmd; + cmd.type = StateCommand::CHANGE; + cmd.state = s; + stateChanges.push(cmd); + } } void Application::PushState(State *s) { - StateCommand cmd; - cmd.type = StateCommand::PUSH; - cmd.state = s; - stateChanges.push(cmd); + if (inStateChage) { + RealPushState(s); + } else { + StateCommand cmd; + cmd.type = StateCommand::PUSH; + cmd.state = s; + stateChanges.push(cmd); + } } void Application::PopState() { - StateCommand cmd; - cmd.type = StateCommand::POP; - cmd.state = 0; - stateChanges.push(cmd); + if (inStateChage) { + RealPopState(); + } else { + 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.top()->PauseState(screen.Screen()); + states.top()->ExitState(*this, screen.Screen()); states.pop(); } states.push(s); - s->EnterState(*this, screen->Screen()); - s->ResumeState(*this, screen->Screen()); + s->EnterState(*this, screen.Screen()); + s->ResumeState(screen.Screen()); } void Application::RealPushState(State *s) { if (!states.empty()) { - states.top()->PauseState(*this, screen->Screen()); + states.top()->PauseState(screen.Screen()); } states.push(s); - s->EnterState(*this, screen->Screen()); - s->ResumeState(*this, screen->Screen()); + s->EnterState(*this, screen.Screen()); + s->ResumeState(screen.Screen()); } void Application::RealPopState() { if (states.empty()) return; - states.top()->PauseState(*this, screen->Screen()); - states.top()->ExitState(*this, screen->Screen()); + states.top()->PauseState(screen.Screen()); + states.top()->ExitState(*this, screen.Screen()); delete states.top(); states.pop(); if (!states.empty()) { - states.top()->ResumeState(*this, screen->Screen()); + states.top()->ResumeState(screen.Screen()); } } @@ -106,7 +115,10 @@ void Application::Quit() { void Application::PopAllStates() { while (!states.empty()) { - RealPopState(); + states.top()->PauseState(screen.Screen()); + states.top()->ExitState(*this, screen.Screen()); + delete states.top(); + states.pop(); } } @@ -121,7 +133,7 @@ void Application::Loop() { Uint32 now(SDL_GetTicks()); Uint32 deltaT(now - last); GlobalTimers().Update(deltaT); - if (deltaT > 34) deltaT = 34; + if (deltaT > 30) deltaT = 30; if (CurrentState()) { CurrentState()->GraphicsTimers().Update(deltaT); @@ -141,13 +153,13 @@ void Application::HandleEvents() { if (!CurrentState()) return; input.ResetInteractiveState(); SDL_Event event; - while (SDL_PollEvent(&event)) { + while (!StateChangePending() && SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: PopAllStates(); break; case SDL_VIDEORESIZE: - screen->Resize(event.resize.w, event.resize.h); + screen.Resize(event.resize.w, event.resize.h); CurrentState()->Resize(event.resize.w, event.resize.h); break; case SDL_KEYDOWN: @@ -159,21 +171,28 @@ void Application::HandleEvents() { break; } } - CurrentState()->HandleEvents(input); + if (CurrentState()) CurrentState()->HandleEvents(input); } void Application::UpdateWorld(Uint32 deltaT) { if (!CurrentState()) return; - for (Uint32 i(0); i < deltaT; ++i) { - CurrentState()->PhysicsTimers().Update(0.001f); - CurrentState()->UpdateWorld(0.001f); + remaining += deltaT; + Uint32 step = CurrentState()->Timestep(); + if (step > 0) { + for (; remaining >= step && !StateChangePending(); remaining -= step) { + CurrentState()->PhysicsTimers().Update(step); + CurrentState()->UpdateWorld(step); + } + } else { + CurrentState()->PhysicsTimers().Update(deltaT); + CurrentState()->UpdateWorld(deltaT); } } void Application::Render(void) { if (!CurrentState()) return; - CurrentState()->Render(screen->Screen()); - screen->Flip(); + CurrentState()->Render(screen.Screen()); + screen.Flip(); } }