1 /*
2 * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9 #include "GameState.h"
10
11 #include "StateManager.h"
12 #include "InputHandler.h"
13 #include "MultiDrawer.h"
14
15 #include "Log.h"
16 #include "LogicException.h"
17 #include "InputAgent.h"
18 #include "VideoAgent.h"
19 #include "MessagerAgent.h"
20 #include "SimpleMsg.h"
21
22 //-----------------------------------------------------------------
GameState()23 GameState::GameState()
24 {
25 m_nextState = NULL;
26 m_handler = NULL;
27 m_active = false;
28 m_onBg = false;
29 m_drawer = new MultiDrawer();
30 }
31 //-----------------------------------------------------------------
~GameState()32 GameState::~GameState()
33 {
34 if (m_handler) {
35 delete m_handler;
36 }
37 delete m_drawer;
38 }
39 //-----------------------------------------------------------------
40 /**
41 * Obtain input handler.
42 * @param new_handler new input handler
43 */
44 void
takeHandler(InputHandler * new_handler)45 GameState::takeHandler(InputHandler *new_handler)
46 {
47 if (m_handler) {
48 delete m_handler;
49 }
50 m_handler = new_handler;
51 }
52 //-----------------------------------------------------------------
53 /**
54 * Returns wrapped input.
55 */
56 const InputProvider *
getInput()57 GameState::getInput()
58 {
59 return m_handler;
60 }
61 //-----------------------------------------------------------------
62 void
initState(StateManager * manager)63 GameState::initState(StateManager *manager)
64 {
65 LOG_DEBUG(ExInfo("initState").addInfo("name", getName()));
66 MessagerAgent::agent()->addListener(this);
67 m_manager = manager;
68 m_active = true;
69 m_onBg = false;
70 own_initState();
71 }
72 //-----------------------------------------------------------------
73 /**
74 * @throws LogicException when state is not active
75 */
76 void
updateState()77 GameState::updateState()
78 {
79 if (!m_active) {
80 throw LogicException(ExInfo("update - state is not active")
81 .addInfo("name", getName()));
82 }
83
84 own_updateState();
85 }
86 //-----------------------------------------------------------------
87 /**
88 * @throws LogicException when state is not active
89 */
90 void
pauseState()91 GameState::pauseState()
92 {
93 if (!m_active) {
94 throw LogicException(ExInfo("pause - state is not active")
95 .addInfo("name", getName()));
96 }
97
98 own_pauseState();
99 m_active = false;
100 m_onBg = false;
101 }
102 //-----------------------------------------------------------------
103 /**
104 * Reactivate state after pause.
105 * @throws LogicException when state is already active
106 */
107 void
resumeState()108 GameState::resumeState()
109 {
110 if (m_active) {
111 throw LogicException(ExInfo("resume - state is already active")
112 .addInfo("name", getName()));
113 }
114 m_active = true;
115 own_resumeState();
116 }
117 //-----------------------------------------------------------------
118 /**
119 * Clean state after run.
120 * @throws LogicException when state is not active
121 */
122 void
cleanState()123 GameState::cleanState()
124 {
125 LOG_DEBUG(ExInfo("cleanState").addInfo("name", getName()));
126 if (!m_active) {
127 throw LogicException(ExInfo("clean - state is not active")
128 .addInfo("name", getName()));
129 }
130 own_cleanState();
131 unHandlers();
132
133 m_active = false;
134 m_onBg = false;
135 m_manager = NULL;
136 removeWatchers();
137 MessagerAgent::agent()->removeListener(getName());
138 }
139 //-----------------------------------------------------------------
140 void
quitState()141 GameState::quitState()
142 {
143 if (m_nextState) {
144 changeState(m_nextState);
145 }
146 else {
147 m_manager->popState(this);
148 }
149 }
150 //-----------------------------------------------------------------
151 void
pushState(GameState * new_state)152 GameState::pushState(GameState *new_state)
153 {
154 m_manager->pushState(this, new_state);
155 }
156 //-----------------------------------------------------------------
157 void
changeState(GameState * new_state)158 GameState::changeState(GameState *new_state)
159 {
160 m_manager->changeState(this, new_state);
161 }
162 //-----------------------------------------------------------------
163 void
noteBg()164 GameState::noteBg()
165 {
166 LOG_DEBUG(ExInfo("noteBg").addInfo("name", getName()));
167 own_noteBg();
168 m_onBg = true;
169 }
170 //-----------------------------------------------------------------
171 void
noteFg()172 GameState::noteFg()
173 {
174 LOG_DEBUG(ExInfo("noteFg").addInfo("name", getName()));
175 m_onBg = false;
176 own_noteFg();
177 }
178 //-----------------------------------------------------------------
179 /**
180 * Install own video and input handler.
181 */
182 void
installHandlers()183 GameState::installHandlers()
184 {
185 LOG_DEBUG(ExInfo("installHandlers").addInfo("state", getName()));
186 InputAgent::agent()->installHandler(m_handler);
187 VideoAgent::agent()->acceptDrawer(m_drawer);
188 }
189 //-----------------------------------------------------------------
190 /**
191 * Uninstall own video and input handler.
192 */
193 void
unHandlers()194 GameState::unHandlers()
195 {
196 InputAgent::agent()->installHandler(NULL);
197 VideoAgent::agent()->removeDrawer(m_drawer);
198 }
199
200 //-----------------------------------------------------------------
201 /**
202 * Add new drawable to drawers fifo.
203 * NOTE: order is important,
204 * the first inserted drawer will be on background
205 */
206 void
registerDrawable(Drawable * drawable)207 GameState::registerDrawable(Drawable *drawable)
208 {
209 m_drawer->acceptDrawer(drawable);
210 }
211 //-----------------------------------------------------------------
212 void
deregisterDrawable(const Drawable * drawable)213 GameState::deregisterDrawable(const Drawable *drawable)
214 {
215 m_drawer->removeDrawer(drawable);
216 }
217 //-----------------------------------------------------------------
218 /**
219 * Handle incoming message.
220 * Messages:
221 * - quit ... quit state
222 */
223 void
receiveSimple(const SimpleMsg * msg)224 GameState::receiveSimple(const SimpleMsg *msg)
225 {
226 if (msg->equalsName("quit")) {
227 quitState();
228 }
229 else {
230 LOG_WARNING(ExInfo("unknown msg")
231 .addInfo("msg", msg->toString()));
232 }
233 }
234
235
236