--- /dev/null
+/*
+ * Application.cpp
+ *
+ * Created on: Apr 8, 2012
+ * Author: holy
+ */
+
+#include "Application.h"
+
+#include "State.h"
+
+#include <cassert>
+
+namespace app {
+
+Application::Application(sdl::InitScreen *screen, State *initialState)
+: screen(screen)
+, states()
+, timer()
+, last(SDL_GetTicks()) {
+ assert(screen && "cannot create application without screen");
+ assert(initialState && "cannot create application without initial state");
+ RealPushState(initialState);
+}
+
+Application::~Application(void) {
+ PopAllStates();
+}
+
+
+State *Application::CurrentState(void) {
+ return states.top();
+}
+
+void Application::ChangeState(State *s) {
+ RealPopState();
+ RealPushState(s);
+}
+
+void Application::PushState(State *s) {
+ RealPushState(s);
+}
+
+void Application::RealPushState(State *s) {
+ states.push(s);
+ s->EnterState(this, screen->Screen());
+}
+
+void Application::PopState(void) {
+ RealPopState();
+}
+
+void Application::RealPopState(void) {
+ if (states.empty()) return;
+ states.top()->ExitState();
+ delete states.top();
+ states.pop();
+}
+
+void Application::Quit(void) {
+ PopAllStates();
+}
+
+void Application::PopAllStates(void) {
+ while (!states.empty()) {
+ RealPopState();
+ }
+}
+
+
+void Application::Run(void) {
+ while (CurrentState()) {
+ Loop();
+ }
+}
+
+void Application::Loop(void) {
+ Uint32 now(SDL_GetTicks());
+ Uint32 deltaT(now - last);
+ if (deltaT > 34) deltaT = 34;
+
+ HandleEvents();
+ UpdateWorld(deltaT);
+ Render();
+
+ last = now;
+}
+
+
+void Application::HandleEvents(void) {
+ if (!CurrentState()) return;
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_QUIT:
+ PopAllStates();
+ break;
+ default:
+ CurrentState()->HandleEvent(event);
+ break;
+ }
+ }
+}
+
+void Application::UpdateWorld(Uint32 deltaT) {
+ if (!CurrentState()) return;
+ for (Uint32 i(0); i < deltaT; ++i) {
+ timer.Update(0.001);
+ CurrentState()->UpdateWorld(timer);
+ }
+}
+
+void Application::Render(void) {
+ if (!CurrentState()) return;
+ CurrentState()->Render(screen->Screen());
+ screen->Flip();
+}
+
+}