Author: ilor
Date: Mon Jul  7 15:53:16 2008
New Revision: 27814

URL: http://svn.gna.org/viewcvs/wesnoth?rev=27814&view=rev
Log:
Code undo and redo internal handling in editor2, add action.cpp to the build

Modified:
    trunk/src/CMakeLists.txt
    trunk/src/Makefile.am
    trunk/src/SConscript
    trunk/src/editor2/action.cpp
    trunk/src/editor2/action.hpp
    trunk/src/editor2/action_base.hpp
    trunk/src/editor2/editor_controller.cpp
    trunk/src/editor2/editor_controller.hpp
    trunk/src/editor2/editor_mouse_handler.cpp
    trunk/src/editor2/editor_mouse_handler.hpp

Modified: trunk/src/CMakeLists.txt
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/CMakeLists.txt?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/CMakeLists.txt (original)
+++ trunk/src/CMakeLists.txt Mon Jul  7 15:53:16 2008
@@ -296,6 +296,7 @@
 IF(ENABLE_EDITOR2)
 
 SET(wesnoth-editor2_SRC
+    editor2/action.cpp
     editor2/editor_main.cpp
     editor2/editor_controller.cpp
     editor2/editor_display.cpp

Modified: trunk/src/Makefile.am
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/Makefile.am?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Mon Jul  7 15:53:16 2008
@@ -145,6 +145,7 @@
     
 # used with editor2 option in the wesnoth target
 wesnoth_editor2_SOURCES = \
+       editor2/action.cpp \
        editor2/editor_main.cpp \
        editor2/editor_controller.cpp \
        editor2/editor_display.cpp \

Modified: trunk/src/SConscript
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/SConscript?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/SConscript (original)
+++ trunk/src/SConscript Mon Jul  7 15:53:16 2008
@@ -237,6 +237,7 @@
 
 # used with editor2 option in the wesnoth target
 wesnoth_editor2_sources = Split("""
+    editor2/action.cpp
     editor2/editor_main.cpp
     editor2/editor_controller.cpp
     editor2/editor_display.cpp

Modified: trunk/src/editor2/action.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor2/action.cpp?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/editor2/action.cpp (original)
+++ trunk/src/editor2/action.cpp Mon Jul  7 15:53:16 2008
@@ -20,12 +20,12 @@
 
 namespace editor2 {
        
-editor_action_whole_map* editor_action_whole_map::perform(editor_map& m) {
+editor_action_whole_map* editor_action_whole_map::perform(editor_map& m) const 
{
        editor_action_whole_map* undo = new editor_action_whole_map(m);
        perform_without_undo(m);
        return undo;
 }
-void editor_action_whole_map::perform_without_undo(editor_map& m) {
+void editor_action_whole_map::perform_without_undo(editor_map& m) const {
        m = m_;
 }
 
@@ -35,7 +35,7 @@
                delete a;
        }
 }
-editor_action_chain* editor_action_chain::perform(editor_map& m) {
+editor_action_chain* editor_action_chain::perform(editor_map& m) const {
        std::vector<editor_action*> undo;
        foreach (editor_action* a, actions_) {
                undo.push_back(a->perform(m));
@@ -43,81 +43,81 @@
        std::reverse(undo.begin(), undo.end());
        return new editor_action_chain(undo);
 }
-void editor_action_chain::perform_without_undo(editor_map& m)
+void editor_action_chain::perform_without_undo(editor_map& m) const
 {
     foreach (editor_action* a, actions_) {
                a->perform_without_undo(m);
        }
 }
 
-editor_action_paste* editor_action_paste::perform(editor_map& map)
+editor_action_paste* editor_action_paste::perform(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_paste::perform_without_undo(editor_map& map)
+void editor_action_paste::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
 
-editor_action_paint_hex* editor_action_paint_hex::perform(editor_map& m)
+editor_action_paint_hex* editor_action_paint_hex::perform(editor_map& m) const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_paint_hex::perform_without_undo(editor_map& map)
+void editor_action_paint_hex::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
 
-editor_action_paste* editor_action_paint_brush::perform(editor_map& m)
+editor_action_paste* editor_action_paint_brush::perform(editor_map& m) const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_paint_brush::perform_without_undo(editor_map& map)
+void editor_action_paint_brush::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
 
-editor_action_fill* editor_action_fill::perform(editor_map& map)
+editor_action_fill* editor_action_fill::perform(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_fill::perform_without_undo(editor_map& map)
+void editor_action_fill::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
 
-editor_action_whole_map* editor_action_resize_map::perform(editor_map& map)
+editor_action_whole_map* editor_action_resize_map::perform(editor_map& map) 
const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_resize_map::perform_without_undo(editor_map& map)
+void editor_action_resize_map::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
 
-editor_action_rotate_map* editor_action_rotate_map::perform(editor_map& map)
+editor_action_rotate_map* editor_action_rotate_map::perform(editor_map& map) 
const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_rotate_map::perform_without_undo(editor_map& map)
+void editor_action_rotate_map::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
 
-editor_action_mirror_map* editor_action_mirror_map::perform(editor_map& map)
+editor_action_mirror_map* editor_action_mirror_map::perform(editor_map& map) 
const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_mirror_map::perform_without_undo(editor_map& map)
+void editor_action_mirror_map::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
 
-editor_action_paste* editor_action_plot_route::perform(editor_map& map)
+editor_action_paste* editor_action_plot_route::perform(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }
-void editor_action_plot_route::perform_without_undo(editor_map& map)
+void editor_action_plot_route::perform_without_undo(editor_map& map) const
 {
        throw editor_action_not_implemented();
 }

Modified: trunk/src/editor2/action.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor2/action.hpp?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/editor2/action.hpp (original)
+++ trunk/src/editor2/action.hpp Mon Jul  7 15:53:16 2008
@@ -30,8 +30,10 @@
 {
 };
        
-//Replace contents of the entire map action
-//useful as a fallback undo method when something else would be impractical
+/**
+ * Replace contents of the entire map,
+ * Useful as a fallback undo method when something else would be impractical
+ */
 class editor_action_whole_map : public editor_action
 {
     public:
@@ -39,13 +41,15 @@
         : m_(m)
         {
         }
-        editor_action_whole_map* perform(editor_map& m);
-        void perform_without_undo(editor_map& m);
+        editor_action_whole_map* perform(editor_map& m) const;
+        void perform_without_undo(editor_map& m) const;
     protected:
         editor_map m_;
 };
 
-//container wrapping several actions as one
+/**
+ * Container action wrapping several actions into one
+ */
 class editor_action_chain : public editor_action
 {
        public:
@@ -54,8 +58,8 @@
                {
                }
                ~editor_action_chain();
-               editor_action_chain* perform(editor_map& m);
-           void perform_without_undo(editor_map& m);
+               editor_action_chain* perform(editor_map& m) const;
+           void perform_without_undo(editor_map& m) const;
     protected:
         std::vector<editor_action*> actions_;
 };
@@ -127,8 +131,8 @@
         : editor_action_location(loc), paste_(paste)
         {
         }
-        editor_action_paste* perform(editor_map& map);
-        void perform_without_undo(editor_map& map);
+        editor_action_paste* perform(editor_map& map) const;
+        void perform_without_undo(editor_map& map) const;
     protected:
         gamemap paste_;
 };
@@ -142,8 +146,8 @@
         : editor_action_location_terrain(loc, t)
         {
         }
-        editor_action_paint_hex* perform(editor_map& m);            
-        void perform_without_undo(editor_map& map);
+        editor_action_paint_hex* perform(editor_map& m) const;            
+        void perform_without_undo(editor_map& map) const;
 };
 
 //paint a terrain on the map with a brush. The brush is a special mask type
@@ -156,8 +160,8 @@
         : editor_action_location_terrain(loc, t), b_(b)
         {
         }
-        editor_action_paste* perform(editor_map& map);
-        void perform_without_undo(editor_map& map);
+        editor_action_paste* perform(editor_map& map) const;
+        void perform_without_undo(editor_map& map) const;
     protected:
         brush b_;
 };
@@ -171,8 +175,8 @@
         : editor_action_location_terrain(loc, t), b_(b)
         {
         }
-        editor_action_fill* perform(editor_map& map);
-        void perform_without_undo(editor_map& map);
+        editor_action_fill* perform(editor_map& map) const;
+        void perform_without_undo(editor_map& map) const;
     protected:
                brush b_;
 };
@@ -185,8 +189,8 @@
                : to_x_size_(to_x_size), to_y_size_(to_y_size)
                {
                }
-               editor_action_whole_map* perform(editor_map& map);
-               void perform_without_undo(editor_map& map);
+               editor_action_whole_map* perform(editor_map& map) const;
+               void perform_without_undo(editor_map& map) const;
        protected:
                int to_x_size_;
                int to_y_size_;
@@ -200,8 +204,8 @@
                : angle_(angle)
                {
                }
-               editor_action_rotate_map* perform(editor_map& map);
-               void perform_without_undo(editor_map& map);
+               editor_action_rotate_map* perform(editor_map& map) const;
+               void perform_without_undo(editor_map& map) const;
        protected:
                int angle_;
 };
@@ -215,8 +219,8 @@
                : angle_(angle)
                {
                }
-               editor_action_mirror_map* perform(editor_map& map);
-               void perform_without_undo(editor_map& map);
+               editor_action_mirror_map* perform(editor_map& map) const;
+               void perform_without_undo(editor_map& map) const;
        protected:
                int angle_;
 };
@@ -231,8 +235,8 @@
                , loc2_(l2)
                {
                }
-               editor_action_paste* perform(editor_map& map);
-               void perform_without_undo(editor_map& map);
+               editor_action_paste* perform(editor_map& map) const;
+               void perform_without_undo(editor_map& map) const;
        protected:
                gamemap::location loc2_;
 };

Modified: trunk/src/editor2/action_base.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor2/action_base.hpp?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/editor2/action_base.hpp (original)
+++ trunk/src/editor2/action_base.hpp Mon Jul  7 15:53:16 2008
@@ -39,8 +39,8 @@
         virtual ~editor_action()
         {
         }        
-        virtual editor_action* perform(editor_map&) = 0;
-        virtual void perform_without_undo(editor_map&) = 0;
+        virtual editor_action* perform(editor_map&) const = 0;
+        virtual void perform_without_undo(editor_map&) const = 0;
 };
 
 

Modified: trunk/src/editor2/editor_controller.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor2/editor_controller.cpp?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/editor2/editor_controller.cpp (original)
+++ trunk/src/editor2/editor_controller.cpp Mon Jul  7 15:53:16 2008
@@ -15,12 +15,15 @@
 #include "editor_display.hpp"
 #include "editor_map.hpp"
 #include "../config_adapter.hpp"
+#include "../foreach.hpp"
 #include "../preferences.hpp"
 
 
 #include "SDL.h"
 
 namespace editor2 {
+
+const int editor_controller::max_action_stack_size_ = 100;
 
 editor_controller::editor_controller(const config &game_config, CVideo& video)
 : controller_base(SDL_GetTicks(), game_config, video)
@@ -48,6 +51,8 @@
 editor_controller::~editor_controller()
 {
     delete gui_;
+       clear_stack(undo_stack_);
+       clear_stack(redo_stack_);
 }
 
 void editor_controller::main_loop()
@@ -72,4 +77,62 @@
        return *gui_;
 }
 
+
+
+void editor_controller::perform_action(const editor_action& action)
+{
+       editor_action* undo = action.perform(map_);
+       undo_stack_.push_back(undo);
+       trim_stack(undo_stack_);
+       clear_stack(redo_stack_);
+}
+
+void editor_controller::trim_stack(action_stack& stack)
+{
+       if (stack.size() > max_action_stack_size_) {
+               delete stack.front();
+               stack.pop_front();
+       }
+}
+
+void editor_controller::clear_stack(action_stack& stack)
+{
+       foreach (editor_action* a, stack) {
+               delete a;
+       }
+       stack.clear();
+}
+
+bool editor_controller::can_undo() const
+{
+       return !undo_stack_.empty();
+}
+
+bool editor_controller::can_redo() const
+{
+       return !redo_stack_.empty();
+}
+
+void editor_controller::undo()
+{
+       perform_action_between_stacks(undo_stack_, redo_stack_);
+}
+
+void editor_controller::redo()
+{
+       perform_action_between_stacks(redo_stack_, undo_stack_);
+}
+
+void editor_controller::perform_action_between_stacks(action_stack& from, 
action_stack& to)
+{
+       assert(!from.empty());
+       editor_action* action = from.back();
+       from.pop_back();
+       editor_action* reverse_action = action->perform(map_);
+       to.push_back(reverse_action);
+       trim_stack(to);
+}
+
+
+
 } //end namespace editor2

Modified: trunk/src/editor2/editor_controller.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor2/editor_controller.hpp?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/editor2/editor_controller.hpp (original)
+++ trunk/src/editor2/editor_controller.hpp Mon Jul  7 15:53:16 2008
@@ -14,6 +14,7 @@
 #ifndef EDITOR2_EDITOR_CONTROLLER_HPP_INCLUDED
 #define EDITOR2_EDITOR_CONTROLLER_HPP_INCLUDED
 
+#include "action_base.hpp"
 #include "editor_common.hpp"
 #include "editor_display.hpp"
 #include "editor_map.hpp"
@@ -26,6 +27,7 @@
 #include "../key.hpp"
 #include "../sdl_utils.hpp"
 
+#include <deque>
 #include <boost/utility.hpp>
 
 namespace editor2 {
@@ -42,15 +44,85 @@
                editor_mouse_handler& get_mouse_handler_base();
                editor_display& get_display();  
        private:    
+               /**
+                * Container type used to store actions in the undo and redo 
stacks
+                */
+               typedef std::deque<editor_action*> action_stack;
+               
                /** init the display object and general set-up */ 
                void init(CVideo& video);
+               
+               /**
+                * Performs an action (thus modyfying the map). An appropriate 
undo action is added to
+                * the undo stack. The redo stack is cleared.
+                */
+               void perform_action(const editor_action& action);
+
+               /**
+                * Checks if an action stack reached its capacity and removes 
the front element if so.
+                */
+               void trim_stack(action_stack& stack);
+
+               /**
+                * Clears an action stack and deletes all its contents. Helper 
function used when the undo
+                * or redo stack needs to be cleared
+                */
+               void clear_stack(action_stack& stack);
+
+               /**
+                * @return true when undo can be performed, false otherwise
+                */
+               bool can_undo() const;
+
+               /**
+                * @return true when redo can be performed, false otherwise
+                */
+               bool can_redo() const;
+
+               /**
+                * Un-does an action, and puts it in the redo stack for a 
possible redo
+                */
+               void undo();
+
+               /**
+                * Re-does a previousle undid action, and puts it back in the 
undo stack.
+                */
+               void redo();
+
+               /**
+                * Perform an action at the back of one stack, and then move it 
to the back of the other stack.
+                * This is the implementation of both undo and redo which only 
differ in the direction.
+                */
+               void perform_action_between_stacks(action_stack& from, 
action_stack& to);
+               
                /** The current map object */
                editor_map map_;
+               
                /** The display object used and owned by the editor. Possibly 
recreated when a new map is created */
                editor_display* gui_;
+               
                editor_mouse_handler mouse_handler_;
                
-        bool map_dirty_;
+               /**
+                * The undo stack. A double-ended queues due to the need to add 
items to one end,
+                * and remove from both when performing the undo or when 
trimming the size. This container owns
+                * all contents, i.e. no action in the stack shall be deleted, 
and unless otherwise noted the contents 
+                * could be deleted at an time during normal operation of the 
stack. To work on an action, either
+                * remove it from the container or make a copy. Actions are 
inserted at the back of the container
+                * and disappear from the front when the capacity is exceeded.
+                * @todo Use boost's pointer-owning container?
+                */
+               action_stack undo_stack_;
+               
+               /**
+                * The redo stack. @see undo_stack_
+                */
+               action_stack redo_stack_;
+               
+               /**
+                * Action stack (i.e. undo and redo) maximum size
+                */
+               static const int max_action_stack_size_;
 };
 
 } //end namespace editor2

Modified: trunk/src/editor2/editor_mouse_handler.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor2/editor_mouse_handler.cpp?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/editor2/editor_mouse_handler.cpp (original)
+++ trunk/src/editor2/editor_mouse_handler.cpp Mon Jul  7 15:53:16 2008
@@ -23,7 +23,7 @@
 namespace editor2 {
 
 editor_mouse_handler::editor_mouse_handler(editor_display* disp, editor_map& 
map)
-: mouse_handler_base(disp, map)
+: mouse_handler_base(disp, map), current_action_(NULL)
 {
 }
 

Modified: trunk/src/editor2/editor_mouse_handler.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor2/editor_mouse_handler.hpp?rev=27814&r1=27813&r2=27814&view=diff
==============================================================================
--- trunk/src/editor2/editor_mouse_handler.hpp (original)
+++ trunk/src/editor2/editor_mouse_handler.hpp Mon Jul  7 15:53:16 2008
@@ -28,6 +28,9 @@
        void mouse_motion(int x, int y, const bool browse, bool update);
        void set_gui(editor_display* gui);
        editor_display& gui() { return static_cast<editor_display&>(*gui_); }
+
+private:
+       editor_action* current_action_;
 };
 
 } //end namespace editor2


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to