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