20130313
[gdash.git] / src / framework / commands.hpp
blob6454d0f2a7fea150ec90797d88b881d5468b2de3
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #ifndef _GD_COMMANDS
18 #define _GD_COMMANDS
20 #include <string>
22 #include "misc/smartptr.hpp"
24 class Logger;
26 extern std::string gd_last_folder; // TO DELETE
28 class CaveStored;
29 class App;
30 class Activity;
32 /// @ingroup Framework
33 /**
34 * Commands are little objects which are usually enqueued by an Activity
35 * object in its parent App object to be executed after processing an
36 * event.
38 * The Command class is abstract. The Command::execute() method is intended
39 * to be overloaded by all descendants, as it is the method which should
40 * perform the action.
42 * The memory management of Command objects is handler via the SmartPtr
43 * class by the App.
45 class Command {
46 public:
47 /** Destructor. */
48 virtual ~Command();
50 protected:
51 /** Constructor. Command objects always know the App in which they work.
52 * @param app The parent App. */
53 Command(App *app): app(app) {}
54 /** The parent App. */
55 App * const app;
57 private:
58 /** This method should perform the action which is the role of the Command. */
59 virtual void execute() = 0;
60 /** The App class if a friend of this class, as commands are supposed to be executed only their parent App. */
61 friend class App;
65 /** A generic command with one parameter.
66 * Usually this parameter will be assigned some value by an Activity,
67 * and then given to the App to be executed. */
68 template <typename T>
69 class Command1Param: public Command {
70 protected:
71 /** Ctor.
72 * @param app The parent App. */
73 Command1Param(App *app) : Command(app) {}
74 /** The value to be remembered. */
75 T p1;
77 public:
78 /** Parametrize the Command.
79 * @param p The value to copy into the command. */
80 void set_param1(T const& p) { p1 = p; }
84 /** This Command will start a new GameActivity when executed.
85 * But first, it should be parametrized by the name of the player,
86 * which will be used by the game for highscores. */
87 class NewGameCommand: public Command1Param<std::string> {
88 public:
89 /** Ctor.
90 * @param app The parent app.
91 * @param cavenum The index of the cave on which the game should start.
92 * @param levelnum The level on which the game should start. */
93 NewGameCommand(App *app, int cavenum, int levelnum);
95 private:
96 virtual void execute();
97 /** The name of the user. Set to p1 of the base class. */
98 std::string &username;
99 /** The cave and level number on which the game will start. */
100 int cavenum, levelnum;
104 /** Pop the topmost activity in the parent App. */
105 class PopActivityCommand: public Command {
106 public:
107 /** Ctor.
108 * @param app The parent app. */
109 PopActivityCommand(App *app): Command(app) {}
111 private:
112 virtual void execute();
116 /** Pop all activities in the parent App.
117 * After popping, the activities stack will be empty. However, there may be
118 * some commands left to execute. This command can be used to restart
119 * the activity flow of an App. */
120 class PopAllActivitiesCommand: public Command {
121 public:
122 /** Ctor.
123 * @param app The parent app. */
124 PopAllActivitiesCommand(App *app): Command(app) {}
125 private:
126 virtual void execute();
130 /** Push an activity to the App. */
131 class PushActivityCommand: public Command {
132 public:
133 /** Ctor.
134 * @param app The parent app.
135 * @param activity_to_push The Activity to be pushed onto the stack. Will be deleted by the App. */
136 PushActivityCommand(App *app, Activity *activity_to_push);
137 /** Dtor.
138 * If the Command is destructed before pushing the App, it will delete the Activity that did not
139 * get pushed. */
140 ~PushActivityCommand();
142 private:
143 /** The activity to be pushed. */
144 Activity *activity_to_push;
145 virtual void execute();
149 /** Pop all activities, then create a new title screen activity. */
150 /** @todo Remove? Kinda trivial, why make a class for it. */
151 class RestartWithTitleScreenCommand: public Command {
152 public:
153 /** Ctor.
154 * @param app The parent app. */
155 RestartWithTitleScreenCommand(App *app): Command(app) {}
157 private:
158 virtual void execute();
162 /** Show the highscores in the caveset. */
163 /** @todo Maybe this should be a virtual function of the App like the file selector? */
164 class ShowHighScoreCommand: public Command {
165 public:
166 /** Ctor.
167 * @param app The parent App.
168 * @param highlight_cave The cave to be highlighted.
169 * @param highlight_line The line number to be highlighted in the highscore list. */
170 ShowHighScoreCommand(App *app, CaveStored *highlight_cave, int highlight_line)
171 : Command(app),
172 highlight_cave(highlight_cave),
173 highlight_line(highlight_line) {}
175 private:
176 CaveStored *highlight_cave;
177 /** The line number to be highlighted in the highscore list. */
178 int highlight_line;
179 virtual void execute();
183 /** Show the info of caves in the CaveSet assigned to the App. */
184 class ShowCaveInfoCommand: public Command {
185 public:
186 /** Ctor.
187 * @param app The parent app. */
188 ShowCaveInfoCommand(App *app): Command(app) {}
190 private:
191 virtual void execute();
195 /** Do the Command given as parameter, if the caveset is not edited
196 * or the user accepts discarding his edits. Usually the command
197 * will come forwarded by some activity. For example, a SelectFileActivity
198 * can be given an OpenFileCommand, which will be executed after
199 * selecting the file. If the caveset was edited however, the application
200 * first asks the user if the changes can be discarded, so the
201 * OpenFileCommand (parametrized with the name of the file)
202 * is not executed immediately, but given to an AskIfChangesDiscardedCommand
203 * for possible execution. */
204 class AskIfChangesDiscardedCommand : public Command {
205 public:
206 /** Ctor.
207 * @param app The parent app.
208 * @param command_if_ok The Command to be executed if the caveset is not edited or the edits can be discarded. */
209 AskIfChangesDiscardedCommand(App *app, SmartPtr<Command> command_if_ok): Command(app), command_if_ok(command_if_ok) {}
210 private:
211 /** Remember the command to be executed. */
212 SmartPtr<Command> command_if_ok;
213 virtual void execute();
217 /** Load a caveset, and then restart the App with a new title screen. It may also
218 * show an error message instead, if the file loading was unsuccessful. */
219 class OpenFileCommand: public Command1Param<std::string> {
220 public:
221 /** Ctor.
222 * @param app The parent app, which also knows the CaveSet.
223 * @param filename The file to be loaded. Can be given to the constructor, or omitted and set later via set_param1(). */
224 OpenFileCommand(App *app, std::string const &filename = "")
225 : Command1Param<std::string>(app),
226 filename(p1) {
227 this->filename = filename;
230 private:
231 /** The name of the file to be loaded. The reference is pointed to
232 * the inherited p1 string by the ctor. */
233 std::string &filename;
234 virtual void execute();
238 /** Save the file to the given filename (which is set by set_param1()).
239 * It may also pop up an error message. */
240 class SaveCavesetToFileCommand: public Command1Param<std::string> {
241 public:
242 /** Ctor.
243 * @param app The parent app. */
244 SaveCavesetToFileCommand(App *app)
245 : Command1Param<std::string>(app),
246 filename(p1) {
249 private:
250 /** The filename. A reference of parameter1, pointed to it by the ctor. */
251 std::string &filename;
252 virtual void execute();
256 /** Save the CaveSet to the file, if its filename is known; otherwise, pop
257 * up a file selection dialog for the user to select a filename to save to. */
258 class SaveFileCommand: public Command {
259 public:
260 /** Ctor.
261 * @param app The parent app, which also knows the caveset. */
262 SaveFileCommand(App *app) : Command(app) { }
264 private:
265 virtual void execute();
269 /** Pop up a file selector for the user to select a filename to save the caveset to;
270 * if the selection is successful, save the file. */
271 class SaveFileAsCommand: public Command {
272 public:
273 /** Ctor.
274 * @param app The parent app, which also knows the caveset. */
275 SaveFileAsCommand(App *app) : Command(app) { }
277 private:
278 virtual void execute();
282 /** Select a file to be loaded and load it; but only if the currently loaded caveset is discardable. */
283 class SelectFileToLoadIfDiscardableCommand: public Command {
284 public:
286 SelectFileToLoadIfDiscardableCommand(App *app, std::string const &start_dir) : Command(app), start_dir(start_dir) {}
288 private:
289 std::string start_dir;
290 virtual void execute();
294 /** Show the errors which are in the Logger. */
295 class ShowErrorsCommand: public Command {
296 public:
297 /** Ctor.
298 * @param app The parent app.
299 * @param l The logger to read the error messages from. */
300 ShowErrorsCommand(App *app, Logger &l): Command(app), l(l) {}
302 private:
303 /** The logger is remembered to read the messages from it when executing the command. */
304 Logger &l;
305 virtual void execute();
308 #endif