Fix deleting UndoCommand instances from stack in undo_tests

This bug was introduced in e730b9095870bd09c5d2330982e1abf9bb02e422
to fix memory leaks in "app". Now a new UndoCommand::dispose() member
function was added to fix this problem.

Also std::function<> and std::tr1::function<> was removed from the test.
We're in the middle of a transition between OS X SDK 10.4 to 10.9/10
and this brings some problems.
This commit is contained in:
David Capello 2015-05-29 10:03:20 -03:00
parent 217a3c51c6
commit 8adbae888f
5 changed files with 41 additions and 44 deletions

View File

@ -62,6 +62,11 @@ void Cmd::redo()
#endif #endif
} }
void Cmd::dispose()
{
delete this;
}
std::string Cmd::label() const std::string Cmd::label() const
{ {
return onLabel(); return onLabel();

View File

@ -24,8 +24,12 @@ namespace app {
virtual ~Cmd(); virtual ~Cmd();
void execute(Context* ctx); void execute(Context* ctx);
// undo::UndoCommand impl
void undo() override; void undo() override;
void redo() override; void redo() override;
void dispose() override;
std::string label() const; std::string label() const;
size_t memSize() const; size_t memSize() const;

View File

@ -15,6 +15,7 @@ namespace undo {
virtual ~UndoCommand() { } virtual ~UndoCommand() { }
virtual void undo() = 0; virtual void undo() = 0;
virtual void redo() = 0; virtual void redo() = 0;
virtual void dispose() = 0;
}; };
} // namespace undo } // namespace undo

View File

@ -27,7 +27,8 @@ namespace undo {
, m_cmd(cmd) { , m_cmd(cmd) {
} }
~UndoState() { ~UndoState() {
delete m_cmd; if (m_cmd)
m_cmd->dispose();
} }
UndoState* prev() const { return m_prev; } UndoState* prev() const { return m_prev; }
UndoState* next() const { return m_next; } UndoState* next() const { return m_next; }

View File

@ -13,42 +13,29 @@
#include "undo/undo_command.h" #include "undo/undo_command.h"
#include "undo/undo_history.h" #include "undo/undo_history.h"
#ifdef _WIN32
#include <functional>
using namespace std;
#else
#include <tr1/functional>
using namespace std::tr1;
#endif
using namespace undo; using namespace undo;
class Cmd : public UndoCommand { class Cmd : public UndoCommand {
public: public:
template<typename UndoT, typename RedoT> Cmd(int& model, int redo_value, int undo_value)
Cmd(RedoT redoFunc, UndoT undoFunc) : m_model(model)
: m_redo(redoFunc), m_undo(undoFunc) { , m_redo_value(redo_value)
, m_undo_value(undo_value) {
} }
void redo() override { m_redo(); } void redo() override { m_model = m_redo_value; }
void undo() override { m_undo(); } void undo() override { m_model = m_undo_value; }
void dispose() override { }
private: private:
function<void()> m_redo; int& m_model;
function<void()> m_undo; int m_redo_value;
int m_undo_value;
}; };
TEST(Undo, Basics) TEST(Undo, Basics)
{ {
UndoHistory history;
int model = 0; int model = 0;
EXPECT_EQ(0, model); Cmd cmd1(model, 1, 0);
Cmd cmd2(model, 2, 1);
Cmd cmd1(
[&]{ model = 1; }, // redo
[&]{ model = 0; }); // undo
Cmd cmd2(
[&]{ model = 2; }, // redo
[&]{ model = 1; }); // undo
EXPECT_EQ(0, model); EXPECT_EQ(0, model);
cmd1.redo(); cmd1.redo();
@ -56,6 +43,7 @@ TEST(Undo, Basics)
cmd2.redo(); cmd2.redo();
EXPECT_EQ(2, model); EXPECT_EQ(2, model);
UndoHistory history;
EXPECT_FALSE(history.canUndo()); EXPECT_FALSE(history.canUndo());
EXPECT_FALSE(history.canRedo()); EXPECT_FALSE(history.canRedo());
history.add(&cmd1); history.add(&cmd1);
@ -86,17 +74,16 @@ TEST(Undo, Basics)
TEST(Undo, Tree) TEST(Undo, Tree)
{ {
UndoHistory history;
int model = 0;
// 1 --- 2 // 1 --- 2
// \ // \
// ------ 3 --- 4 // ------ 3 --- 4
Cmd cmd1([&]{ model = 1; }, [&]{ model = 0; }); int model = 0;
Cmd cmd2([&]{ model = 2; }, [&]{ model = 1; }); Cmd cmd1(model, 1, 0);
Cmd cmd3([&]{ model = 3; }, [&]{ model = 1; }); Cmd cmd2(model, 2, 1);
Cmd cmd4([&]{ model = 4; }, [&]{ model = 3; }); Cmd cmd3(model, 3, 1);
Cmd cmd4(model, 4, 3);
UndoHistory history;
cmd1.redo(); history.add(&cmd1); cmd1.redo(); history.add(&cmd1);
cmd2.redo(); history.add(&cmd2); cmd2.redo(); history.add(&cmd2);
history.undo(); history.undo();
@ -126,21 +113,20 @@ TEST(Undo, Tree)
TEST(Undo, ComplexTree) TEST(Undo, ComplexTree)
{ {
UndoHistory history;
int model = 0;
// 1 --- 2 --- 3 --- 4 ------ 7 --- 8 // 1 --- 2 --- 3 --- 4 ------ 7 --- 8
// \ / // \ /
// ------------- 5 --- 6 // ------------- 5 --- 6
Cmd cmd1([&]{ model = 1; }, [&]{ model = 0; }); int model = 0;
Cmd cmd2([&]{ model = 2; }, [&]{ model = 1; }); Cmd cmd1(model, 1, 0);
Cmd cmd3([&]{ model = 3; }, [&]{ model = 2; }); Cmd cmd2(model, 2, 1);
Cmd cmd4([&]{ model = 4; }, [&]{ model = 3; }); Cmd cmd3(model, 3, 2);
Cmd cmd5([&]{ model = 5; }, [&]{ model = 2; }); Cmd cmd4(model, 4, 3);
Cmd cmd6([&]{ model = 6; }, [&]{ model = 5; }); Cmd cmd5(model, 5, 2);
Cmd cmd7([&]{ model = 7; }, [&]{ model = 5; }); Cmd cmd6(model, 6, 5);
Cmd cmd8([&]{ model = 8; }, [&]{ model = 7; }); Cmd cmd7(model, 7, 5);
Cmd cmd8(model, 8, 7);
UndoHistory history;
cmd1.redo(); history.add(&cmd1); cmd1.redo(); history.add(&cmd1);
cmd2.redo(); history.add(&cmd2); cmd2.redo(); history.add(&cmd2);
cmd3.redo(); history.add(&cmd3); cmd3.redo(); history.add(&cmd3);