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