-/*
- * Application.cpp
- *
- * Created on: Apr 8, 2012
- * Author: holy
- */
-
#include "Application.h"
#include "State.h"
+#include "../sdl/InitScreen.h"
#include <cassert>
namespace app {
-Application::Application(sdl::InitScreen *screen, State *initialState)
+Application::Application(sdl::InitScreen &screen, State *initialState)
: screen(screen)
, states()
, last(SDL_GetTicks())
+, remaining(0)
, inStateChage(false) {
- assert(screen && "cannot create application without screen");
assert(initialState && "cannot create application without initial state");
RealPushState(initialState);
}
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());
}
}
void Application::PopAllStates() {
while (!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());
delete states.top();
states.pop();
}
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:
void Application::UpdateWorld(Uint32 deltaT) {
if (!CurrentState()) return;
- for (Uint32 i(0); i < deltaT && !StateChangePending(); ++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();
}
}