Added DiffManager system, with simple undo/redo
This commit is contained in:
parent
1eef1ef429
commit
5afd5ec24a
18 changed files with 356 additions and 16 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "DefinitionNode.h"
|
#include "DefinitionNode.h"
|
||||||
|
|
||||||
DefinitionDiff::DefinitionDiff(const std::string &type_name):
|
DefinitionDiff::DefinitionDiff(const DefinitionNode *node):
|
||||||
type_name(type_name)
|
type_name(node->getTypeName()), path(node->getPath())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,14 @@ namespace definition {
|
||||||
class DEFINITIONSHARED_EXPORT DefinitionDiff
|
class DEFINITIONSHARED_EXPORT DefinitionDiff
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DefinitionDiff(const std::string &type_name);
|
DefinitionDiff(const DefinitionNode *node);
|
||||||
|
|
||||||
inline const std::string &getTypeName() const {return type_name;}
|
inline const std::string &getTypeName() const {return type_name;}
|
||||||
|
inline const std::string &getPath() const {return path;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string type_name;
|
std::string type_name;
|
||||||
|
std::string path;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "DefinitionDiff.h"
|
#include "DefinitionDiff.h"
|
||||||
|
#include "DiffManager.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
DefinitionNode::DefinitionNode(DefinitionNode* parent, const std::string &name, const std::string &type_name):
|
DefinitionNode::DefinitionNode(DefinitionNode* parent, const std::string &name, const std::string &type_name):
|
||||||
parent(parent), type_name(type_name), name(name)
|
parent(parent), type_name(type_name), name(name)
|
||||||
|
@ -11,10 +14,12 @@ DefinitionNode::DefinitionNode(DefinitionNode* parent, const std::string &name,
|
||||||
{
|
{
|
||||||
root = parent->root;
|
root = parent->root;
|
||||||
parent->addChild(this);
|
parent->addChild(this);
|
||||||
|
diffs = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
root = this;
|
root = this;
|
||||||
|
diffs = new DiffManager(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +31,12 @@ DefinitionNode::~DefinitionNode()
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diffs)
|
||||||
|
{
|
||||||
|
delete diffs;
|
||||||
|
diffs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Work on a copy, because the child destructor will modify the array by removing itself using removeChild
|
// Work on a copy, because the child destructor will modify the array by removing itself using removeChild
|
||||||
std::vector<DefinitionNode*> children_copy = children;
|
std::vector<DefinitionNode*> children_copy = children;
|
||||||
for (auto child:children_copy)
|
for (auto child:children_copy)
|
||||||
|
@ -72,6 +83,66 @@ std::string DefinitionNode::toString(int indent) const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string DefinitionNode::getPath() const
|
||||||
|
{
|
||||||
|
if (parent == root)
|
||||||
|
{
|
||||||
|
return parent->getPath() + name;
|
||||||
|
}
|
||||||
|
else if (parent)
|
||||||
|
{
|
||||||
|
return parent->getPath() + "/" + name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DefinitionNode *DefinitionNode::findByPath(const std::string &path) const
|
||||||
|
{
|
||||||
|
if (path.empty())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (path[0] == '/')
|
||||||
|
{
|
||||||
|
if (path.length() == 1)
|
||||||
|
{
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
else if (root == this)
|
||||||
|
{
|
||||||
|
return findByPath(path.substr(1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return root->findByPath(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t seppos = path.find("/");
|
||||||
|
std::string child_name = (seppos == std::string::npos) ? path : path.substr(0, seppos);
|
||||||
|
DefinitionNode *child = ((DefinitionNode *)this)->findChildByName(child_name); // FIXME findChildByName should be const
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
if (seppos == std::string::npos)
|
||||||
|
{
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return child->findByPath(path.substr(seppos + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool)
|
bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool)
|
||||||
{
|
{
|
||||||
// Only do type check, subclasses will do the rest
|
// Only do type check, subclasses will do the rest
|
||||||
|
@ -86,6 +157,14 @@ bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefinitionNode::addWatcher(DefinitionWatcher *watcher)
|
||||||
|
{
|
||||||
|
if (root && root->diffs)
|
||||||
|
{
|
||||||
|
root->diffs->addWatcher(this, watcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DefinitionNode::save(PackStream* stream) const
|
void DefinitionNode::save(PackStream* stream) const
|
||||||
{
|
{
|
||||||
int children_count = (int)children.size();
|
int children_count = (int)children.size();
|
||||||
|
@ -202,3 +281,13 @@ int DefinitionNode::getStreamSize() const
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefinitionNode::addDiff(const DefinitionDiff *diff)
|
||||||
|
{
|
||||||
|
assert(diff->getTypeName() == type_name);
|
||||||
|
|
||||||
|
if (root && root->diffs)
|
||||||
|
{
|
||||||
|
root->diffs->addDiff(this, diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
|
|
||||||
inline const DefinitionNode *getParent() const {return parent;}
|
inline const DefinitionNode *getParent() const {return parent;}
|
||||||
inline const DefinitionNode *getRoot() const {return root;}
|
inline const DefinitionNode *getRoot() const {return root;}
|
||||||
|
inline DiffManager *getDiffManager() const {return diffs;}
|
||||||
inline int getChildrenCount() const {return children.size();}
|
inline int getChildrenCount() const {return children.size();}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +38,18 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual std::string toString(int indent = 0) const;
|
virtual std::string toString(int indent = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the path to this node, using '/' delimited syntax, with the first '/' being the root node.
|
||||||
|
*/
|
||||||
|
std::string getPath() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a node in this tree, by its path (as returned by getPath).
|
||||||
|
*
|
||||||
|
* Return NULL if the path does not exists.
|
||||||
|
*/
|
||||||
|
DefinitionNode *findByPath(const std::string &path) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a diff to the internal value of this node.
|
* Apply a diff to the internal value of this node.
|
||||||
*
|
*
|
||||||
|
@ -48,6 +61,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false);
|
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a watcher over this node.
|
||||||
|
*
|
||||||
|
* The watcher will receive DefinitionDiff objects when this node changes.
|
||||||
|
*/
|
||||||
|
void addWatcher(DefinitionWatcher *watcher);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addChild(DefinitionNode* child);
|
void addChild(DefinitionNode* child);
|
||||||
void removeChild(DefinitionNode* child);
|
void removeChild(DefinitionNode* child);
|
||||||
|
@ -61,9 +81,19 @@ protected:
|
||||||
*/
|
*/
|
||||||
int getStreamSize() const;
|
int getStreamSize() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a diff to the DiffManager of this definition tree, for the current node.
|
||||||
|
*
|
||||||
|
* The manager will take immediate ownership of the diff, handling its freeing.
|
||||||
|
*
|
||||||
|
* The manager will decide if the diff should be committed and will call *applyDiff* if needed.
|
||||||
|
*/
|
||||||
|
void addDiff(const DefinitionDiff *diff);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DefinitionNode *parent;
|
DefinitionNode *parent;
|
||||||
DefinitionNode *root;
|
DefinitionNode *root;
|
||||||
|
DiffManager *diffs;
|
||||||
std::string type_name;
|
std::string type_name;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<DefinitionNode*> children;
|
std::vector<DefinitionNode*> children;
|
||||||
|
|
7
src/definition/DefinitionWatcher.cpp
Normal file
7
src/definition/DefinitionWatcher.cpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include "DefinitionWatcher.h"
|
||||||
|
|
||||||
|
DefinitionWatcher::DefinitionWatcher()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
23
src/definition/DefinitionWatcher.h
Normal file
23
src/definition/DefinitionWatcher.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef DEFINITIONWATCHER_H
|
||||||
|
#define DEFINITIONWATCHER_H
|
||||||
|
|
||||||
|
#include "definition_global.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace definition {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for watchers of the definition tree.
|
||||||
|
*
|
||||||
|
* Watchers will be registered in DiffManager to receive DefinitionDiff objects.
|
||||||
|
*/
|
||||||
|
class DEFINITIONSHARED_EXPORT DefinitionWatcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DefinitionWatcher();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEFINITIONWATCHER_H
|
55
src/definition/DiffManager.cpp
Normal file
55
src/definition/DiffManager.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include "DiffManager.h"
|
||||||
|
|
||||||
|
#include "DefinitionNode.h"
|
||||||
|
#include "DefinitionDiff.h"
|
||||||
|
|
||||||
|
DiffManager::DiffManager(DefinitionNode *tree):
|
||||||
|
tree(tree)
|
||||||
|
{
|
||||||
|
undone = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher)
|
||||||
|
{
|
||||||
|
watchers[node].push_back(watcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff)
|
||||||
|
{
|
||||||
|
diffs.push_back(diff);
|
||||||
|
|
||||||
|
// TODO Delayed commit (with merge of consecutive diffs)
|
||||||
|
node->applyDiff(diff);
|
||||||
|
|
||||||
|
for (auto &watcher: watchers[node])
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiffManager::undo()
|
||||||
|
{
|
||||||
|
if (undone <= (int)diffs.size())
|
||||||
|
{
|
||||||
|
undone++;
|
||||||
|
const DefinitionDiff *diff = diffs[diffs.size() - undone];
|
||||||
|
|
||||||
|
// Obtain the node by path and reverse apply diff on it
|
||||||
|
DefinitionNode *node = tree->findByPath(diff->getPath());
|
||||||
|
node->applyDiff(diff, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiffManager::redo()
|
||||||
|
{
|
||||||
|
if (undone > 0)
|
||||||
|
{
|
||||||
|
const DefinitionDiff *diff = diffs[diffs.size() - undone];
|
||||||
|
undone--;
|
||||||
|
|
||||||
|
// Obtain the node by path and re-apply diff on it
|
||||||
|
DefinitionNode *node = tree->findByPath(diff->getPath());
|
||||||
|
node->applyDiff(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
54
src/definition/DiffManager.h
Normal file
54
src/definition/DiffManager.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef DIFFMANAGER_H
|
||||||
|
#define DIFFMANAGER_H
|
||||||
|
|
||||||
|
#include "definition_global.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace definition {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager of diffs produced by a definition tree.
|
||||||
|
*
|
||||||
|
* Watchers can register themselves to received these diffs.
|
||||||
|
*/
|
||||||
|
class DEFINITIONSHARED_EXPORT DiffManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DiffManager(DefinitionNode *tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a watcher for a specific node.
|
||||||
|
*
|
||||||
|
* The watcher reference must remain valid through the manager lifetime.
|
||||||
|
*/
|
||||||
|
void addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new diff of a node to the change flow.
|
||||||
|
*/
|
||||||
|
void addDiff(DefinitionNode *node, const DefinitionDiff *diff);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo a diff in the definition tree.
|
||||||
|
*/
|
||||||
|
void undo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redo a diff in the definition tree, undone by undo().
|
||||||
|
*/
|
||||||
|
void redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DefinitionNode *tree;
|
||||||
|
int undone;
|
||||||
|
std::vector<const DefinitionDiff *> diffs;
|
||||||
|
std::map<const DefinitionNode *, std::vector<DefinitionWatcher *>> watchers;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DIFFMANAGER_H
|
|
@ -1,6 +1,6 @@
|
||||||
#include "FloatDiff.h"
|
#include "FloatDiff.h"
|
||||||
|
|
||||||
FloatDiff::FloatDiff(double oldvalue, double newvalue):
|
FloatDiff::FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue):
|
||||||
DefinitionDiff("float"), oldvalue(oldvalue), newvalue(newvalue)
|
DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace definition {
|
||||||
class DEFINITIONSHARED_EXPORT FloatDiff: public DefinitionDiff
|
class DEFINITIONSHARED_EXPORT FloatDiff: public DefinitionDiff
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FloatDiff(double oldvalue, double newvalue);
|
FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue);
|
||||||
|
|
||||||
inline double getOldValue() const {return oldvalue;}
|
inline double getOldValue() const {return oldvalue;}
|
||||||
inline double getNewValue() const {return newvalue;}
|
inline double getNewValue() const {return newvalue;}
|
||||||
|
|
|
@ -42,9 +42,14 @@ void FloatNode::copy(DefinitionNode *destination) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FloatNode::setValue(double new_value)
|
||||||
|
{
|
||||||
|
addDiff(produceDiff(new_value));
|
||||||
|
}
|
||||||
|
|
||||||
const FloatDiff *FloatNode::produceDiff(double new_value) const
|
const FloatDiff *FloatNode::produceDiff(double new_value) const
|
||||||
{
|
{
|
||||||
return new FloatDiff(value, new_value);
|
return new FloatDiff(this, value, new_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
||||||
|
|
|
@ -23,6 +23,12 @@ public:
|
||||||
virtual void load(PackStream* stream) override;
|
virtual void load(PackStream* stream) override;
|
||||||
virtual void copy(DefinitionNode* destination) const override;
|
virtual void copy(DefinitionNode* destination) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the float value stored.
|
||||||
|
*
|
||||||
|
* The DiffManager is used as intermediary, so that the change may not happen immediately.
|
||||||
|
*/
|
||||||
|
void setValue(double new_value);
|
||||||
const FloatDiff *produceDiff(double new_value) const;
|
const FloatDiff *produceDiff(double new_value) const;
|
||||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
|
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -33,7 +33,9 @@ SOURCES += \
|
||||||
DefinitionNode.cpp \
|
DefinitionNode.cpp \
|
||||||
FloatNode.cpp \
|
FloatNode.cpp \
|
||||||
DefinitionDiff.cpp \
|
DefinitionDiff.cpp \
|
||||||
FloatDiff.cpp
|
FloatDiff.cpp \
|
||||||
|
DiffManager.cpp \
|
||||||
|
DefinitionWatcher.cpp
|
||||||
|
|
||||||
HEADERS +=\
|
HEADERS +=\
|
||||||
definition_global.h \
|
definition_global.h \
|
||||||
|
@ -56,7 +58,9 @@ HEADERS +=\
|
||||||
DefinitionNode.h \
|
DefinitionNode.h \
|
||||||
FloatNode.h \
|
FloatNode.h \
|
||||||
DefinitionDiff.h \
|
DefinitionDiff.h \
|
||||||
FloatDiff.h
|
FloatDiff.h \
|
||||||
|
DiffManager.h \
|
||||||
|
DefinitionWatcher.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -17,6 +17,8 @@ namespace definition {
|
||||||
class DefinitionDiff;
|
class DefinitionDiff;
|
||||||
class FloatNode;
|
class FloatNode;
|
||||||
class FloatDiff;
|
class FloatDiff;
|
||||||
|
class DiffManager;
|
||||||
|
class DefinitionWatcher;
|
||||||
class Scenery;
|
class Scenery;
|
||||||
class CameraDefinition;
|
class CameraDefinition;
|
||||||
class SurfaceMaterial;
|
class SurfaceMaterial;
|
||||||
|
|
|
@ -15,6 +15,35 @@ TEST(DefinitionNode, toString)
|
||||||
EXPECT_EQ("branch\n leaf1\n leaf2", branch.toString());
|
EXPECT_EQ("branch\n leaf1\n leaf2", branch.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DefinitionNode, getPath)
|
||||||
|
{
|
||||||
|
DefinitionNode root(NULL, "root");
|
||||||
|
DefinitionNode branch(&root, "branch");
|
||||||
|
DefinitionNode leaf(&branch, "leaf");
|
||||||
|
|
||||||
|
EXPECT_EQ("/", root.getPath());
|
||||||
|
EXPECT_EQ("/branch", branch.getPath());
|
||||||
|
EXPECT_EQ("/branch/leaf", leaf.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DefinitionNode, findByPath)
|
||||||
|
{
|
||||||
|
DefinitionNode root(NULL, "root");
|
||||||
|
DefinitionNode branch(&root, "branch");
|
||||||
|
DefinitionNode leaf(&branch, "leaf");
|
||||||
|
|
||||||
|
EXPECT_EQ(&root, root.findByPath("/"));
|
||||||
|
EXPECT_EQ(&branch, root.findByPath("/branch"));
|
||||||
|
EXPECT_EQ(NULL, root.findByPath("/branche"));
|
||||||
|
EXPECT_EQ(&leaf, root.findByPath("/branch/leaf"));
|
||||||
|
EXPECT_EQ(NULL, root.findByPath("/branche/leaf"));
|
||||||
|
EXPECT_EQ(NULL, root.findByPath("/branch/leave"));
|
||||||
|
|
||||||
|
EXPECT_EQ(&branch, root.findByPath("branch"));
|
||||||
|
EXPECT_EQ(&leaf, root.findByPath("branch/leaf"));
|
||||||
|
EXPECT_EQ(&leaf, branch.findByPath("leaf"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(DefinitionNode, attachDetach)
|
TEST(DefinitionNode, attachDetach)
|
||||||
{
|
{
|
||||||
DefinitionNode* root = new DefinitionNode(NULL, "root");
|
DefinitionNode* root = new DefinitionNode(NULL, "root");
|
||||||
|
|
32
src/tests/DiffManager_Test.cpp
Normal file
32
src/tests/DiffManager_Test.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "BaseTestCase.h"
|
||||||
|
|
||||||
|
#include "DiffManager.h"
|
||||||
|
#include "DefinitionNode.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
|
||||||
|
TEST(DiffManager, undoRedoSimple)
|
||||||
|
{
|
||||||
|
DefinitionNode root(NULL, "root");
|
||||||
|
FloatNode leaf(&root, "value", 2.6);
|
||||||
|
DiffManager *diffs = root.getDiffManager();
|
||||||
|
|
||||||
|
EXPECT_DOUBLE_EQ(2.6, leaf.getValue());
|
||||||
|
|
||||||
|
leaf.setValue(4.3);
|
||||||
|
EXPECT_DOUBLE_EQ(4.3, leaf.getValue());
|
||||||
|
|
||||||
|
leaf.setValue(-2.1);
|
||||||
|
EXPECT_DOUBLE_EQ(-2.1, leaf.getValue());
|
||||||
|
|
||||||
|
diffs->undo();
|
||||||
|
EXPECT_DOUBLE_EQ(4.3, leaf.getValue());
|
||||||
|
|
||||||
|
diffs->undo();
|
||||||
|
EXPECT_DOUBLE_EQ(2.6, leaf.getValue());
|
||||||
|
|
||||||
|
diffs->redo();
|
||||||
|
EXPECT_DOUBLE_EQ(4.3, leaf.getValue());
|
||||||
|
|
||||||
|
diffs->redo();
|
||||||
|
EXPECT_DOUBLE_EQ(-2.1, leaf.getValue());
|
||||||
|
}
|
|
@ -67,8 +67,9 @@ TEST(FloatNode, produceDiff)
|
||||||
TEST(FloatNode, applyDiff)
|
TEST(FloatNode, applyDiff)
|
||||||
{
|
{
|
||||||
FloatNode node(NULL, "test", 1.2);
|
FloatNode node(NULL, "test", 1.2);
|
||||||
FloatDiff diff(1.2, 2.4);
|
FloatDiff diff(&node, 1.2, 2.4);
|
||||||
DefinitionDiff odiff("badtype");
|
DefinitionNode onode(NULL, "test", "badtype");
|
||||||
|
DefinitionDiff odiff(&onode);
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
EXPECT_DOUBLE_EQ(1.2, node.getValue());
|
EXPECT_DOUBLE_EQ(1.2, node.getValue());
|
||||||
|
|
|
@ -24,7 +24,8 @@ SOURCES += main.cpp \
|
||||||
AtmosphereDefinition_Test.cpp \
|
AtmosphereDefinition_Test.cpp \
|
||||||
Scenery_Test.cpp \
|
Scenery_Test.cpp \
|
||||||
DefinitionNode_Test.cpp \
|
DefinitionNode_Test.cpp \
|
||||||
FloatNode_Test.cpp
|
FloatNode_Test.cpp \
|
||||||
|
DiffManager_Test.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
BaseTestCase.h
|
BaseTestCase.h
|
||||||
|
|
Loading…
Reference in a new issue