]> git.localhorst.tv Git - l2e.git/blobdiff - src/app/Application.cpp
added Maxim's melee animation
[l2e.git] / src / app / Application.cpp
index e06e231d785535488554f9b09975410f8942f667..6e46203aa94184de00c55d90ff41025b7433d12d 100644 (file)
@@ -22,72 +22,124 @@ Application::Application(sdl::InitScreen *screen, State *initialState)
        RealPushState(initialState);
 }
 
-Application::~Application(void) {
+Application::~Application() {
        PopAllStates();
 }
 
 
-State *Application::CurrentState(void) {
-       return states.top();
+State *Application::CurrentState() {
+       return states.empty() ? 0 : states.top();
+}
+
+void Application::UpdateState() {
+       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) {
-       RealPopState();
-       RealPushState(s);
+       StateCommand cmd;
+       cmd.type = StateCommand::CHANGE;
+       cmd.state = s;
+       stateChanges.push(cmd);
 }
 
 void Application::PushState(State *s) {
-       RealPushState(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(void) {
-       RealPopState();
+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(void) {
+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(void) {
+void Application::Quit() {
        PopAllStates();
 }
 
-void Application::PopAllStates(void) {
+void Application::PopAllStates() {
        while (!states.empty()) {
                RealPopState();
        }
 }
 
 
-void Application::Run(void) {
+void Application::Run() {
        while (CurrentState()) {
                Loop();
        }
 }
 
-void Application::Loop(void) {
+void Application::Loop() {
        Uint32 now(SDL_GetTicks());
        Uint32 deltaT(now - last);
-       if (deltaT > 34) deltaT = 34;
+       GlobalTimers().Update(deltaT);
+       if (deltaT > 30) deltaT = 30;
 
+       if (CurrentState()) {
+               CurrentState()->GraphicsTimers().Update(deltaT);
+       }
        HandleEvents();
-       UpdateWorld(deltaT);
-       Render();
+       if (!StateChangePending()) {
+               UpdateWorld(deltaT);
+               Render();
+       }
 
        last = now;
+       UpdateState();
 }
 
 
-void Application::HandleEvents(void) {
+void Application::HandleEvents() {
        if (!CurrentState()) return;
+       input.ResetInteractiveState();
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
                switch (event.type) {
@@ -98,16 +150,22 @@ void Application::HandleEvents(void) {
                                screen->Resize(event.resize.w, event.resize.h);
                                CurrentState()->Resize(event.resize.w, event.resize.h);
                                break;
+                       case SDL_KEYDOWN:
+                       case SDL_KEYUP:
+                               input.HandleKeyboardEvent(event.key);
+                               break;
                        default:
-                               CurrentState()->HandleEvent(event);
+                               // skip event
                                break;
                }
        }
+       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);
        }
 }