1 #include "Application.h"
4 #include "../sdl/InitScreen.h"
10 Application::Application(sdl::InitScreen &screen, State *initialState)
13 , last(SDL_GetTicks())
15 , inStateChage(false) {
16 assert(initialState && "cannot create application without initial state");
17 RealPushState(initialState);
20 Application::~Application() {
25 State *Application::CurrentState() {
26 return states.empty() ? 0 : states.top();
29 void Application::UpdateState() {
31 while (!stateChanges.empty()) {
32 switch (stateChanges.front().type) {
33 case StateCommand::PUSH:
34 RealPushState(stateChanges.front().state);
36 case StateCommand::POP:
39 case StateCommand::CHANGE:
40 RealChangeState(stateChanges.front().state);
48 void Application::ChangeState(State *s) {
53 cmd.type = StateCommand::CHANGE;
55 stateChanges.push(cmd);
59 void Application::PushState(State *s) {
64 cmd.type = StateCommand::PUSH;
66 stateChanges.push(cmd);
70 void Application::PopState() {
75 cmd.type = StateCommand::POP;
77 stateChanges.push(cmd);
81 void Application::RealChangeState(State *s) {
82 if (!states.empty()) {
83 states.top()->PauseState(screen.Screen());
84 states.top()->ExitState(*this, screen.Screen());
88 s->EnterState(*this, screen.Screen());
89 s->ResumeState(screen.Screen());
92 void Application::RealPushState(State *s) {
93 if (!states.empty()) {
94 states.top()->PauseState(screen.Screen());
97 s->EnterState(*this, screen.Screen());
98 s->ResumeState(screen.Screen());
101 void Application::RealPopState() {
102 if (states.empty()) return;
103 states.top()->PauseState(screen.Screen());
104 states.top()->ExitState(*this, screen.Screen());
107 if (!states.empty()) {
108 states.top()->ResumeState(screen.Screen());
112 void Application::Quit() {
116 void Application::PopAllStates() {
117 while (!states.empty()) {
118 states.top()->PauseState(screen.Screen());
119 states.top()->ExitState(*this, screen.Screen());
126 void Application::Run() {
127 while (CurrentState()) {
132 void Application::Loop() {
133 Uint32 now(SDL_GetTicks());
134 Uint32 deltaT(now - last);
135 GlobalTimers().Update(deltaT);
136 if (deltaT > 30) deltaT = 30;
138 if (CurrentState()) {
139 CurrentState()->GraphicsTimers().Update(deltaT);
142 if (!StateChangePending()) {
152 void Application::HandleEvents() {
153 if (!CurrentState()) return;
154 input.ResetInteractiveState();
156 while (!StateChangePending() && SDL_PollEvent(&event)) {
157 switch (event.type) {
161 case SDL_VIDEORESIZE:
162 screen.Resize(event.resize.w, event.resize.h);
163 CurrentState()->Resize(event.resize.w, event.resize.h);
167 input.HandleKeyboardEvent(event.key);
174 if (CurrentState()) CurrentState()->HandleEvents(input);
177 void Application::UpdateWorld(Uint32 deltaT) {
178 if (!CurrentState()) return;
180 Uint32 step = CurrentState()->Timestep();
182 for (; remaining >= step && !StateChangePending(); remaining -= step) {
183 CurrentState()->PhysicsTimers().Update(step);
184 CurrentState()->UpdateWorld(step);
187 CurrentState()->PhysicsTimers().Update(deltaT);
188 CurrentState()->UpdateWorld(deltaT);
192 void Application::Render(void) {
193 if (!CurrentState()) return;
194 CurrentState()->Render(screen.Screen());