From 3f9f41338d8100a719e161a3a1cdda9dd227e2b4 Mon Sep 17 00:00:00 2001
From: Daniel Karbach <daniel.karbach@localhorst.tv>
Date: Tue, 9 Oct 2012 22:40:06 +0200
Subject: [PATCH] better handling of nested state changes

---
 src/app/Application.cpp | 41 ++++++++++++++++++++++++++++-------------
 src/app/Application.h   |  1 +
 2 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/app/Application.cpp b/src/app/Application.cpp
index 4ff75d8..4de48d4 100644
--- a/src/app/Application.cpp
+++ b/src/app/Application.cpp
@@ -16,7 +16,8 @@ namespace app {
 Application::Application(sdl::InitScreen *screen, State *initialState)
 : screen(screen)
 , states()
-, last(SDL_GetTicks()) {
+, last(SDL_GetTicks())
+, inStateChage(false) {
 	assert(screen && "cannot create application without screen");
 	assert(initialState && "cannot create application without initial state");
 	RealPushState(initialState);
@@ -32,6 +33,7 @@ State *Application::CurrentState() {
 }
 
 void Application::UpdateState() {
+	inStateChage = true;
 	while (!stateChanges.empty()) {
 		switch (stateChanges.front().type) {
 			case StateCommand::PUSH:
@@ -46,27 +48,40 @@ 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) {
diff --git a/src/app/Application.h b/src/app/Application.h
index b7b0001..41198bc 100644
--- a/src/app/Application.h
+++ b/src/app/Application.h
@@ -71,6 +71,7 @@ private:
 	Timers<Uint32> globalTimers;
 	Input input;
 	Uint32 last;
+	bool inStateChage;
 
 };
 
-- 
2.39.5