editor/map/map_context.hpp

Go to the documentation of this file.
00001 /* $Id: map_context.hpp 53522 2012-03-13 18:19:16Z 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 #ifndef EDITOR_MAP_CONTEXT_HPP_INCLUDED
00017 #define EDITOR_MAP_CONTEXT_HPP_INCLUDED
00018 
00019 #include "editor_map.hpp"
00020 #include "map_label.hpp"
00021 
00022 #include <boost/utility.hpp>
00023 
00024 namespace editor {
00025 
00026 /**
00027  * This class wraps around a map to provide a concise interface for the editor to work with.
00028  * The actual map object can change rapidly (be assigned to), the map context persists
00029  * data (like the undo stacks) in this case. The functionality is here, not in editor_controller
00030  * as e.g. the undo stack is part of the map, not the editor as a whole. This might allow many
00031  * maps to be open at the same time.
00032  */
00033 class map_context : private boost::noncopyable
00034 {
00035 public:
00036     /**
00037      * Create a map context from an existing map. The filename is set to be
00038      * empty, indicating a new map.
00039      * Marked "explicit" to avoid automatic conversions.
00040      */
00041     explicit map_context(const editor_map& map);
00042 
00043     /**
00044      * Create map_context from a map file. If the map cannot be loaded, an
00045      * exception will be thrown and the object will not be constructed. If the
00046      * map file is a scenario, the map specified in its map_data key will be
00047      * loaded, and the stored filename updated accordingly. Maps embedded
00048      * inside scenarios do not change the filename, but set the "embedded" flag
00049      * instead.
00050      */
00051     map_context(const config& game_config, const std::string& filename, const display& disp);
00052 
00053     /**
00054      * Map context destructor
00055      */
00056     ~map_context();
00057 
00058     /**
00059      * Map accesor
00060      */
00061     editor_map& get_map() { return map_; };
00062 
00063     /**
00064      * Map accesor - const version
00065      */
00066     const editor_map& get_map() const { return map_; }
00067 
00068     /**
00069      * Draw a terrain on a single location on the map.
00070      * Sets the refresh flags accordingly.
00071      */
00072     void draw_terrain(t_translation::t_terrain terrain, const map_location& loc,
00073         bool one_layer_only = false);
00074 
00075     /**
00076      * Actual drawing function used by both overloaded variants of draw_terrain.
00077      */
00078     void draw_terrain_actual(t_translation::t_terrain terrain, const map_location& loc,
00079         bool one_layer_only = false);
00080 
00081     /**
00082      * Draw a terrain on a set of locations on the map.
00083      * Sets the refresh flags accordingly.
00084      */
00085     void draw_terrain(t_translation::t_terrain terrain, const std::set<map_location>& locs,
00086         bool one_layer_only = false);
00087 
00088     /**
00089      * Getter for the reload flag. Reload is the highest level of required refreshing,
00090      * set when the map size has changed or the map was reassigned.
00091      */
00092     bool needs_reload() const { return needs_reload_; }
00093 
00094     /**
00095      * Setter for the reload flag
00096      */
00097     void set_needs_reload(bool value=true) { needs_reload_ = value; }
00098 
00099     /**
00100      * Getter for the terrain rebuild flag. Set whenever any terrain has changed.
00101      */
00102     bool needs_terrain_rebuild() const { return needs_terrain_rebuild_; }
00103 
00104     /**
00105      * Setter for the terrain rebuild flag
00106      */
00107     void set_needs_terrain_rebuild(bool value=true) { needs_terrain_rebuild_ = value; }
00108 
00109     /**
00110      * Getter fo the labels reset flag. Set when the labels need to be refreshed.
00111      */
00112     bool needs_labels_reset() const { return needs_labels_reset_; }
00113 
00114     /**
00115      * Setter for the labels reset flag
00116      */
00117     void set_needs_labels_reset(bool value=true) { needs_labels_reset_ = value; }
00118 
00119     const std::set<map_location> changed_locations() const { return changed_locations_; }
00120     void clear_changed_locations();
00121     void add_changed_location(const map_location& loc);
00122     void add_changed_location(const std::set<map_location>& locs);
00123     void set_everything_changed();
00124     bool everything_changed() const;
00125 
00126     void set_labels(display& disp);
00127 
00128     void clear_starting_position_labels(display& disp);
00129 
00130     void set_starting_position_labels(display& disp);
00131 
00132     void reset_starting_position_labels(display& disp);
00133 
00134     const std::string& get_filename() const { return filename_; }
00135 
00136     void set_filename(const std::string& fn) { filename_ = fn; }
00137 
00138     const std::string& get_map_data_key() const { return map_data_key_; }
00139 
00140     bool is_embedded() const { return embedded_; }
00141 
00142     void set_embedded(bool v) { embedded_ = v; }
00143 
00144     /**
00145      * Saves the map under the current filename. Filename must be valid.
00146      * May throw an exception on failure.
00147      */
00148     bool save();
00149 
00150     void set_map(const editor_map& map);
00151 
00152     /**
00153      * Performs an action (thus modyfying the map). An appropriate undo action is added to
00154      * the undo stack. The redo stack is cleared. Note that this may throw, use caution
00155      * when calling this with a dereferennced pointer that you own (i.e. use a smart pointer).
00156      */
00157     void perform_action(const editor_action& action);
00158 
00159     /**
00160      * Performs a partial action, assumes that the top undo action has been modified to
00161      * maintain coherent state of the undo stacks, and so a new undo action is not
00162      * created.
00163      */
00164     void perform_partial_action(const editor_action& action);
00165 
00166     /** @return whether the map was modified since the last save */
00167     bool modified() const;
00168 
00169     /** Clear the modified state */
00170     void clear_modified();
00171 
00172     /** @return true when undo can be performed, false otherwise */
00173     bool can_undo() const;
00174 
00175     /** @return true when redo can be performed, false otherwise */
00176     bool can_redo() const;
00177 
00178     /** @return a pointer to the last undo action or NULL if the undo stack is empty */
00179     editor_action* last_undo_action();
00180 
00181     /** @return a pointer to the last redo action or NULL if the undo stack is empty */
00182     editor_action* last_redo_action();
00183 
00184     /** const version of last_undo_action */
00185     const editor_action* last_undo_action() const;
00186 
00187     /** const version of last_redo_action */
00188     const editor_action* last_redo_action() const;
00189 
00190     /** Un-does the last action, and puts it in the redo stack for a possible redo */
00191     void undo();
00192 
00193     /** Re-does a previousle undid action, and puts it back in the undo stack. */
00194     void redo();
00195 
00196     /**
00197      * Un-does a single step from a undo action chain. The action is separated
00198      * from the chain and it's undo (the redo) is added as a standalone action
00199      * to the redo stack.
00200      * Precodnition: the last undo action has to actually be an action chain.
00201      */
00202     void partial_undo();
00203 
00204     /**
00205      * Clear the undo and redo stacks
00206      */
00207     void clear_undo_redo();
00208 
00209 protected:
00210     /**
00211      * The actual filename of this map. An empty string indicates a new map.
00212      */
00213     std::string filename_;
00214 
00215     /**
00216      * When a scenario file is loaded, the referenced map is loaded instead.
00217      * The verbatim form of the reference is kept here.
00218      */
00219     std::string map_data_key_;
00220 
00221     /**
00222      * Whether the map context refers to a map embedded in a scenario file.
00223      * This distinction is important in order to avoid overwriting the scenario.
00224      */
00225     bool embedded_;
00226 
00227     /**
00228      * The map object of this map_context.
00229      */
00230     editor_map map_;
00231 
00232 
00233     /**
00234      * Container type used to store actions in the undo and redo stacks
00235      */
00236     typedef std::deque<editor_action*> action_stack;
00237 
00238     /**
00239      * Checks if an action stack reached its capacity and removes the front element if so.
00240      */
00241     void trim_stack(action_stack& stack);
00242 
00243     /**
00244      * Clears an action stack and deletes all its contents. Helper function used when the undo
00245      * or redo stack needs to be cleared
00246      */
00247     void clear_stack(action_stack& stack);
00248 
00249     /**
00250      * Perform an action at the back of one stack, and then move it to the back of the other stack.
00251      * This is the implementation of both undo and redo which only differ in the direction.
00252      */
00253     void perform_action_between_stacks(action_stack& from, action_stack& to);
00254 
00255     /**
00256      * The undo stack. A double-ended queues due to the need to add items to one end,
00257      * and remove from both when performing the undo or when trimming the size. This container owns
00258      * all contents, i.e. no action in the stack shall be deleted, and unless otherwise noted the contents
00259      * could be deleted at an time during normal operation of the stack. To work on an action, either
00260      * remove it from the container or make a copy. Actions are inserted at the back of the container
00261      * and disappear from the front when the capacity is exceeded.
00262      * @todo Use boost's pointer-owning container?
00263      */
00264     action_stack undo_stack_;
00265 
00266     /**
00267      * The redo stack. @see undo_stack_
00268      */
00269     action_stack redo_stack_;
00270 
00271     /**
00272      * Action stack (i.e. undo and redo) maximum size
00273      */
00274     static const size_t max_action_stack_size_;
00275 
00276     /**
00277      * Number of actions performed since the map was saved. Zero means the map was not modified.
00278      */
00279     int actions_since_save_;
00280 
00281     /**
00282      * Cache of set starting position labels. Necessary for removing them.
00283      */
00284     std::set<map_location> starting_position_label_locs_;
00285 
00286     /**
00287      * Refresh flag indicating the map in this context should be completely reloaded by the display
00288      */
00289     bool needs_reload_;
00290 
00291     /**
00292      * Refresh flag indicating the terrain in the map has changed and requires a rebuild
00293      */
00294     bool needs_terrain_rebuild_;
00295 
00296     /**
00297      * Refresh flag indicating the labels in the map have changed
00298      */
00299     bool needs_labels_reset_;
00300 
00301     std::set<map_location> changed_locations_;
00302     bool everything_changed_;
00303 };
00304 
00305 
00306 } //end namespace editor
00307 
00308 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:50 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs