editor/action.hpp

Go to the documentation of this file.
00001 /* $Id: action.hpp 53296 2012-02-28 10:31:13Z fendrin $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Tomasz Sniatowski <kailoran@gmail.com>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * @file
00018  * Editor action classes. Some important points:
00019  * - This is a polymorphic hierarchy of classes, so actions are usually passed around
00020  *   as editor_action pointers
00021  * - The pointers can, in general, be null. Always check for null before doing anything.
00022  *   The helper functions perform_ that take a pointer do that.
00023  * - The perform() functions can throw when an error occurs. Use smart pointers if you
00024  *   need to ensure the pointer is deleted.
00025  */
00026 
00027 #ifndef EDITOR_ACTION_HPP
00028 #define EDITOR_ACTION_HPP
00029 
00030 #include "action_base.hpp"
00031 #include "map_fragment.hpp"
00032 
00033 namespace editor {
00034 
00035 /**
00036  * Replace contents of the entire map,
00037  * Useful as a fallback undo method when something else would be impractical
00038  */
00039 class editor_action_whole_map : public editor_action
00040 {
00041     public:
00042         editor_action_whole_map(const editor_map& m)
00043         : m_(m)
00044         {
00045         }
00046         editor_action_whole_map* clone() const;
00047         void perform_without_undo(map_context& m) const;
00048         const char* get_name() const { return "whole_map"; }
00049     protected:
00050         editor_map m_;
00051 };
00052 
00053 /**
00054  * Base class for actions that:
00055  * 1) operate on an area
00056  * 2) can be used as undo for a click-drag operation
00057  * 3) can be extended so one undo action undos several actual drag actions
00058  */
00059 class editor_action_extendable : public editor_action
00060 {
00061     public:
00062         editor_action_extendable()
00063         {
00064         }
00065         /**
00066          * The crux of the extendable contract. This member function must be
00067          * implemented so that the undo behaviour is consistent, exactly the
00068          * same as would be with separate undo actions for every part of
00069          * the drag.
00070          */
00071         virtual void extend(const editor_map& map, const std::set<map_location>& locs) = 0;
00072         const char* get_name() const { return "extendable"; }
00073 };
00074 
00075 /**
00076  * Container action wrapping several actions into one.
00077  * The actions are performed in the order they are added,
00078  * i.e. in the usual iteration order through the container.
00079  */
00080 class editor_action_chain : public editor_action
00081 {
00082     public:
00083         /**
00084          * Create an empty action chain
00085          */
00086         editor_action_chain() :
00087             actions_()
00088         {
00089         }
00090 
00091         editor_action_chain(const editor_action_chain& other);
00092 
00093         editor_action_chain& operator=(const editor_action_chain& other);
00094 
00095         editor_action_chain* clone() const;
00096 
00097         /**
00098          * Create an action chain from a deque of action pointers.
00099          * Note: the action chain assumes ownership of the pointers.
00100          */
00101         explicit editor_action_chain(std::deque<editor_action*> actions)
00102         : actions_(actions)
00103         {
00104         }
00105 
00106         /**
00107          * Create an action chain by wrapping around a single action pointer.
00108          * Note: the action chain assumes ownership of the pointer.
00109          */
00110         explicit editor_action_chain(editor_action* action)
00111         : actions_(1, action)
00112         {
00113         }
00114 
00115         /**
00116          * The destructor deletes all the owned action pointers
00117          */
00118         ~editor_action_chain();
00119 
00120         /**
00121          * Go through the chain and add up all the action counts
00122          */
00123         int action_count() const;
00124 
00125         /**
00126          * Add an action at the end of the chain
00127          */
00128         void append_action(editor_action* a);
00129 
00130         /**
00131          * Add an action at the beginning of the chain
00132          */
00133         void prepend_action(editor_action* a);
00134 
00135         /**
00136          * @return true when there are no actions in the chain. Empty
00137          * action chains should usually be discarded as to not keep
00138          * "empty" actions around.
00139          */
00140         bool empty() const;
00141 
00142         /**
00143          * Remove the last added action and return it, transferring
00144          * ownership to the caller
00145          */
00146         editor_action* pop_last_action();
00147 
00148         /**
00149          * Remove the first added action and return it, transferring
00150          * ownership to the caller
00151          */
00152         editor_action* pop_first_action();
00153 
00154         /**
00155          * Perform all the actions in order and create a undo action chain
00156          */
00157         editor_action_chain* perform(map_context& m) const;
00158 
00159         /**
00160          * Perform all the actions in order
00161          */
00162         void perform_without_undo(map_context& m) const;
00163 
00164         const char* get_name() const { return "chain"; }
00165 
00166     protected:
00167         /**
00168          * The action pointers owned by this action chain
00169          */
00170         std::deque<editor_action*> actions_;
00171 };
00172 
00173 
00174 /**
00175  * Base class for actions which act on a specified location (and possibly on other locations
00176  * that can be derived from the staring hex)
00177  */
00178 class editor_action_location : public editor_action
00179 {
00180     public:
00181         editor_action_location(map_location loc)
00182         : loc_(loc)
00183         {
00184         }
00185         const char* get_name() const { return "location"; }
00186     protected:
00187         map_location loc_;
00188 };
00189 
00190 /** Base class for actions which in addition to acting on a hex,
00191  * act with one terrain type, i.e. paint-related actions.
00192  */
00193 class editor_action_location_terrain : public editor_action_location
00194 {
00195     public:
00196         editor_action_location_terrain(map_location loc,
00197             t_translation::t_terrain t)
00198         : editor_action_location(loc), t_(t)
00199         {
00200         }
00201         const char* get_name() const { return "location_terrain"; }
00202     protected:
00203         t_translation::t_terrain t_;
00204 };
00205 
00206 /**
00207  * Base class for area-affecting actions
00208  */
00209 class editor_action_area : public editor_action_extendable
00210 {
00211     public:
00212         editor_action_area(const std::set<map_location>& area)
00213         : area_(area)
00214         {
00215         }
00216         void extend(const editor_map& map, const std::set<map_location>& locs);
00217         const char* get_name() const { return "area"; }
00218     protected:
00219         std::set<map_location> area_;
00220 };
00221 
00222 /**
00223  * Paste a map fragment into the map. No offset is used.
00224  */
00225 class editor_action_paste : public editor_action_extendable
00226 {
00227     public:
00228         editor_action_paste(const map_fragment& paste, const map_location& offset = map_location(0,0))
00229         : offset_(offset), paste_(paste)
00230         {
00231         }
00232         editor_action_paste* clone() const;
00233         editor_action_paste* perform(map_context& mc) const;
00234         void perform_without_undo(map_context& mc) const;
00235         void extend(const editor_map& map, const std::set<map_location>& locs);
00236         const char* get_name() const { return "paste"; }
00237     protected:
00238         map_location offset_;
00239         map_fragment paste_;
00240 };
00241 
00242 /**
00243  * Paint the same terrain on a number of locations on the map.
00244  */
00245 class editor_action_paint_area : public editor_action_area
00246 {
00247     public:
00248         editor_action_paint_area(const std::set<map_location>& area,
00249             t_translation::t_terrain t, bool one_layer=false)
00250         : editor_action_area(area), t_(t), one_layer_(one_layer)
00251         {
00252         }
00253         editor_action_paint_area* clone() const;
00254         editor_action_paste* perform(map_context& mc) const;
00255         void perform_without_undo(map_context& mc) const;
00256         const char* get_name() const { return "paint_area"; }
00257     protected:
00258         t_translation::t_terrain t_;
00259         bool one_layer_;
00260 };
00261 
00262 /**
00263  * Flood fill. Somewhat redundant with paint_area.
00264  */
00265 class editor_action_fill : public editor_action_location_terrain
00266 {
00267     public:
00268         editor_action_fill(map_location loc,
00269             t_translation::t_terrain t, bool one_layer=false)
00270         : editor_action_location_terrain(loc, t), one_layer_(one_layer)
00271         {
00272         }
00273         editor_action_fill* clone() const;
00274         editor_action_paint_area* perform(map_context& mc) const;
00275         void perform_without_undo(map_context& mc) const;
00276         const char* get_name() const { return "fill"; }
00277     protected:
00278         bool one_layer_;
00279 };
00280 
00281 /**
00282  * Set starting position action
00283  */
00284 class editor_action_starting_position : public editor_action_location
00285 {
00286     public:
00287         editor_action_starting_position(map_location loc, int player)
00288         : editor_action_location(loc), player_(player)
00289         {
00290         }
00291         editor_action_starting_position* clone() const;
00292         editor_action* perform(map_context& mc) const;
00293         void perform_without_undo(map_context& mc) const;
00294         const char* get_name() const { return "starting_pos"; }
00295     protected:
00296         int player_;
00297 };
00298 
00299 
00300 /**
00301  * Select the given locations
00302  */
00303 class editor_action_select : public editor_action_area
00304 {
00305     public:
00306         editor_action_select(const std::set<map_location>& area)
00307         : editor_action_area(area)
00308         {
00309         }
00310         editor_action_select* clone() const;
00311         void extend(const editor_map& map, const std::set<map_location>& locs);
00312         editor_action* perform(map_context& mc) const;
00313         void perform_without_undo(map_context& mc) const;
00314         const char* get_name() const { return "select"; }
00315 };
00316 
00317 /**
00318  * Deselect the given locations
00319  */
00320 class editor_action_deselect : public editor_action_area
00321 {
00322     public:
00323         editor_action_deselect(const std::set<map_location>& area)
00324         : editor_action_area(area)
00325         {
00326         }
00327         editor_action_deselect* clone() const;
00328         void extend(const editor_map& map, const std::set<map_location>& locs);
00329         editor_action* perform(map_context& mc) const;
00330         void perform_without_undo(map_context& mc) const;
00331         const char* get_name() const { return "deselect"; }
00332 };
00333 
00334 /**
00335  * Select the entire map
00336  */
00337 class editor_action_select_all : public editor_action
00338 {
00339     public:
00340         editor_action_select_all()
00341         {
00342         }
00343         editor_action_select_all* clone() const;
00344         editor_action_deselect* perform(map_context& mc) const;
00345         void perform_without_undo(map_context& mc) const;
00346         const char* get_name() const { return "select_all"; }
00347 };
00348 
00349 /**
00350  * Clear selection
00351  */
00352 class editor_action_select_none : public editor_action
00353 {
00354     public:
00355         editor_action_select_none()
00356         {
00357         }
00358         editor_action_select_none* clone() const;
00359         editor_action_select* perform(map_context& mc) const;
00360         void perform_without_undo(map_context& mc) const;
00361         const char* get_name() const { return "select_none"; }
00362 };
00363 
00364 /**
00365  * Invert the selection
00366  */
00367 class editor_action_select_inverse : public editor_action
00368 {
00369     public:
00370         editor_action_select_inverse()
00371         {
00372         }
00373         editor_action_select_inverse* clone() const;
00374         editor_action_select_inverse* perform(map_context& mc) const;
00375         void perform_without_undo(map_context& mc) const;
00376         const char* get_name() const { return "select_inverse"; }
00377 };
00378 
00379 /**
00380  * Resize the map. The offsets specify, indirectly, the direction of expanding/shrinking,
00381  * and fill=NONE enables copying of edge terrain instead of filling.
00382  */
00383 class editor_action_resize_map : public editor_action
00384 {
00385     public:
00386         editor_action_resize_map(int x_size, int y_size, int x_offset, int y_offset,
00387             t_translation::t_terrain fill = t_translation::NONE_TERRAIN)
00388         : x_size_(x_size), y_size_(y_size), x_offset_(x_offset), y_offset_(y_offset), fill_(fill)
00389         {
00390         }
00391         editor_action_resize_map* clone() const;
00392         void perform_without_undo(map_context& mc) const;
00393         const char* get_name() const { return "resize"; }
00394     protected:
00395         int x_size_;
00396         int y_size_;
00397         int x_offset_;
00398         int y_offset_;
00399         t_translation::t_terrain fill_;
00400 };
00401 
00402 class editor_action_apply_mask : public editor_action
00403 {
00404     public:
00405         editor_action_apply_mask(const gamemap& mask)
00406         : mask_(mask)
00407         {
00408         }
00409         editor_action_apply_mask* clone() const;
00410         void perform_without_undo(map_context& mc) const;
00411         const char* get_name() const { return "apply_mask"; }
00412     private:
00413         gamemap mask_;
00414 };
00415 
00416 class editor_action_create_mask : public editor_action
00417 {
00418     public:
00419         editor_action_create_mask(const editor_map& target)
00420         : target_(target)
00421         {
00422         }
00423         editor_action_create_mask* clone() const;
00424         void perform_without_undo(map_context& mc) const;
00425         const char* get_name() const { return "create_mask"; }
00426     private:
00427         editor_map target_;
00428 };
00429 
00430 /**
00431  * Randomize terrain in an area
00432  */
00433 class editor_action_shuffle_area : public editor_action_area
00434 {
00435     public:
00436         editor_action_shuffle_area(const std::set<map_location>& area)
00437         : editor_action_area(area)
00438         {
00439         }
00440         editor_action_shuffle_area* clone() const;
00441         editor_action_paste* perform(map_context& mc) const;
00442         void perform_without_undo(map_context& mc) const;
00443         const char* get_name() const { return "shuffle_area"; }
00444 };
00445 
00446 
00447 } //end namespace editor
00448 
00449 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Tue Mar 13 2012 01:02:39 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs