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.
22 #include "misc/smartptr.hpp"
26 extern std::string gd_last_folder
; // TO DELETE
32 /// @ingroup Framework
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
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
42 * The memory management of Command objects is handler via the SmartPtr
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. */
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. */
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. */
69 class Command1Param
: public Command
{
72 * @param app The parent App. */
73 Command1Param(App
*app
) : Command(app
) {}
74 /** The value to be remembered. */
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
> {
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
);
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
{
108 * @param app The parent app. */
109 PopActivityCommand(App
*app
): Command(app
) {}
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
{
123 * @param app The parent app. */
124 PopAllActivitiesCommand(App
*app
): Command(app
) {}
126 virtual void execute();
130 /** Push an activity to the App. */
131 class PushActivityCommand
: public Command
{
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
);
138 * If the Command is destructed before pushing the App, it will delete the Activity that did not
140 ~PushActivityCommand();
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
{
154 * @param app The parent app. */
155 RestartWithTitleScreenCommand(App
*app
): Command(app
) {}
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
{
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
)
172 highlight_cave(highlight_cave
),
173 highlight_line(highlight_line
) {}
176 CaveStored
*highlight_cave
;
177 /** The line number to be highlighted in the highscore list. */
179 virtual void execute();
183 /** Show the info of caves in the CaveSet assigned to the App. */
184 class ShowCaveInfoCommand
: public Command
{
187 * @param app The parent app. */
188 ShowCaveInfoCommand(App
*app
): Command(app
) {}
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
{
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
) {}
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
> {
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
),
227 this->filename
= filename
;
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
> {
243 * @param app The parent app. */
244 SaveCavesetToFileCommand(App
*app
)
245 : Command1Param
<std::string
>(app
),
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
{
261 * @param app The parent app, which also knows the caveset. */
262 SaveFileCommand(App
*app
) : Command(app
) { }
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
{
274 * @param app The parent app, which also knows the caveset. */
275 SaveFileAsCommand(App
*app
) : Command(app
) { }
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
{
286 SelectFileToLoadIfDiscardableCommand(App
*app
, std::string
const &start_dir
) : Command(app
), start_dir(start_dir
) {}
289 std::string start_dir
;
290 virtual void execute();
294 /** Show the errors which are in the Logger. */
295 class ShowErrorsCommand
: public Command
{
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
) {}
303 /** The logger is remembered to read the messages from it when executing the command. */
305 virtual void execute();