00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "StateManager.h"
00010
00011 #include "GameState.h"
00012
00013 #include "MessagerAgent.h"
00014 #include "SimpleMsg.h"
00015 #include "LogicException.h"
00016
00017
00018 StateManager::~StateManager()
00019 {
00020 emptyTrash();
00021
00022 t_states::iterator end = m_states.end();
00023 for (t_states::iterator i = m_states.begin(); i != end; ++i) {
00024 delete (*i);
00025 }
00026 }
00027
00028 void
00029 StateManager::emptyTrash()
00030 {
00031 t_states::iterator end = m_trash.end();
00032 for (t_states::iterator i = m_trash.begin(); i != end; ++i) {
00033 delete (*i);
00034 }
00035 m_trash.clear();
00036 }
00037
00038
00039
00040
00041
00042
00043 void
00044 StateManager::updateGame()
00045 {
00046 t_states::iterator end = m_states.end();
00047 for (t_states::iterator i = m_states.begin(); i != end; ) {
00048
00049 GameState *cur = *(i++);
00050 if (cur->isRunning()) {
00051 cur->updateState();
00052 }
00053 }
00054
00055 emptyTrash();
00056 }
00057
00058
00059
00060
00061
00062
00063 void
00064 StateManager::removeState(GameState *state)
00065 {
00066 state->cleanState();
00067 m_trash.push_back(state);
00068 m_states.remove(state);
00069 }
00070
00071
00072
00073
00074 void
00075 StateManager::changeState(GameState *who, GameState *new_state)
00076 {
00077 insertAfter(who, new_state);
00078 removeState(who);
00079 new_state->initState(this);
00080 checkStack();
00081 }
00082
00083
00084
00085
00086 void
00087 StateManager::pushState(GameState *who, GameState *new_state)
00088 {
00089 insertAfter(who, new_state);
00090 new_state->initState(this);
00091 checkStack();
00092 }
00093
00094
00095
00096
00097
00098 void
00099 StateManager::popState(GameState *who)
00100 {
00101 removeState(who);
00102
00103 if (!m_states.empty()) {
00104 checkStack();
00105 }
00106 else {
00107 MessagerAgent::agent()->forwardNewMsg(
00108 new SimpleMsg(Name::APP_NAME, "quit"));
00109 }
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 void
00119 StateManager::insertAfter(GameState *who, GameState *new_state)
00120 {
00121 if (NULL == who) {
00122 m_states.push_front(new_state);
00123 }
00124 else {
00125 t_states::iterator it = findIter(who);
00126 m_states.insert(++it, new_state);
00127 }
00128 }
00129
00130
00131
00132
00133
00134 StateManager::t_states::iterator
00135 StateManager::findIter(GameState *who)
00136 {
00137 t_states::iterator end = m_states.end();
00138 for (t_states::iterator i = m_states.begin(); i != end; ++i) {
00139 if (who == (*i)) {
00140 return i;
00141 }
00142 }
00143 throw LogicException(ExInfo("game state is not found in stack")
00144 .addInfo("state", who ? who->getName() : "(null)"));
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 void
00154 StateManager::checkStack()
00155 {
00156 if (m_states.empty()) {
00157 throw LogicException(ExInfo("game state stack is empty"));
00158 }
00159
00160 t_states::iterator topIt = m_states.end();
00161 --topIt;
00162 GameState *top = (*topIt);
00163 if (top->isOnBg()) {
00164 top->noteFg();
00165 }
00166 pauseBg(topIt);
00167 resumeBg(topIt);
00168 installHandlers();
00169 }
00170
00171
00172
00173
00174
00175
00176 void
00177 StateManager::pauseBg(t_states::iterator stateIt)
00178 {
00179 if (stateIt != m_states.begin()) {
00180 t_states::iterator prev = stateIt;
00181 --prev;
00182 if (!(*stateIt)->isRunning() || !(*stateIt)->allowBg()) {
00183 if ((*prev)->isRunning()) {
00184 (*prev)->pauseState();
00185 }
00186 }
00187 pauseBg(prev);
00188 }
00189 }
00190
00191
00192
00193
00194
00195
00196 void
00197 StateManager::resumeBg(t_states::iterator stateIt)
00198 {
00199 if ((*stateIt)->allowBg() && stateIt != m_states.begin()) {
00200 t_states::iterator prev = stateIt;
00201 --prev;
00202 resumeBg(prev);
00203 (*prev)->noteBg();
00204 }
00205
00206 if (!(*stateIt)->isRunning()) {
00207 (*stateIt)->resumeState();
00208 }
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 void
00220 StateManager::installHandlers()
00221 {
00222 t_states::iterator end = m_states.end();
00223 for (t_states::iterator i = m_states.begin(); i != end; ++i) {
00224 if ((*i)->isRunning()) {
00225 (*i)->unHandlers();
00226 (*i)->installHandlers();
00227 }
00228 else {
00229 (*i)->unHandlers();
00230 }
00231 }
00232 }
00233