Remove dependency of "undo" library with "base"

This commit is contained in:
David Capello 2013-08-05 22:11:54 -03:00
parent c88f9b172b
commit 9eebfc5812
5 changed files with 187 additions and 192 deletions

View File

@ -7,77 +7,77 @@
#ifndef UNDO_OBJECTS_CONTAINER_H_INCLUDED #ifndef UNDO_OBJECTS_CONTAINER_H_INCLUDED
#define UNDO_OBJECTS_CONTAINER_H_INCLUDED #define UNDO_OBJECTS_CONTAINER_H_INCLUDED
#include "base/exception.h"
#include "undo/object_id.h" #include "undo/object_id.h"
#include <stdexcept>
namespace undo { namespace undo {
// Thrown when you use ObjectsContainer::insertObject() with an // Thrown when you use ObjectsContainer::insertObject() with an
// existent ID or pointer. // existent ID or pointer.
class ExistentObjectException : base::Exception class ExistentObjectException : public std::runtime_error {
{ public:
public: ExistentObjectException()
ExistentObjectException() { } : std::runtime_error("Duplicated object in container") { }
}; };
// Thrown when an object is not found when // Thrown when an object is not found when
// ObjectsContainer::getObject() or removeObject() methods are used. // ObjectsContainer::getObject() or removeObject() methods are used.
class ObjectNotFoundException : base::Exception class ObjectNotFoundException : public std::runtime_error {
{ public:
public: ObjectNotFoundException()
ObjectNotFoundException() { } : std::runtime_error("Object not found in container") { }
}; };
// A container of any kind of object used to generate serializable // A container of any kind of object used to generate serializable
// references (ID) to instances in memory. It converts a pointer to a // references (ID) to instances in memory. It converts a pointer to a
// 32-bits ID, and then you can get back the original object pointer // 32-bits ID, and then you can get back the original object pointer
// from the ID. // from the ID.
// //
// If the original pointer is deleted, you must use removeObject(), // If the original pointer is deleted, you must use removeObject(),
// and if the object is re-created (e.g. by an undo operation), // and if the object is re-created (e.g. by an undo operation),
// the object can be added back to the container using insertObject(). // the object can be added back to the container using insertObject().
class ObjectsContainer class ObjectsContainer {
{ public:
public: virtual ~ObjectsContainer() { };
virtual ~ObjectsContainer() { };
// Adds an object in the container and returns an ID, so then you // Adds an object in the container and returns an ID, so then you
// can retrieve the original object pointer using getObject() // can retrieve the original object pointer using getObject()
// method. If the object is already in the container, the returned // method. If the object is already in the container, the returned
// ID must be the same as the already assigned. It means that this // ID must be the same as the already assigned. It means that this
// method cannot return different IDs for the same given "void*" // method cannot return different IDs for the same given "void*"
// pointer. // pointer.
virtual ObjectId addObject(void* object) = 0; virtual ObjectId addObject(void* object) = 0;
// Inserts an existent object with the specific ID. If an object // Inserts an existent object with the specific ID. If an object
// with the given ID or the pointer already exist in the container, // with the given ID or the pointer already exist in the container,
// it should throw an ExistentObjectException. This method is used // it should throw an ExistentObjectException. This method is used
// to insert back in the container a previously removed object // to insert back in the container a previously removed object
// with a removeObject() call. // with a removeObject() call.
virtual void insertObject(ObjectId id, void* object) = 0; virtual void insertObject(ObjectId id, void* object) = 0;
// Removes the given object from the container because it cannot be // Removes the given object from the container because it cannot be
// referenced anymore. Anyway the ID is not re-used by following // referenced anymore. Anyway the ID is not re-used by following
// calls to addObject(), so the object can be added back into the // calls to addObject(), so the object can be added back into the
// container with the same ID using insertObject() method. If the // container with the same ID using insertObject() method. If the
// object does not exist in the container, it throws an // object does not exist in the container, it throws an
// ObjectNotFoundException exception. // ObjectNotFoundException exception.
virtual void removeObject(ObjectId id) = 0; virtual void removeObject(ObjectId id) = 0;
// Returns the object pointer associated to the given ID. The // Returns the object pointer associated to the given ID. The
// pointer is the same as the used in addObject() or insertObject() // pointer is the same as the used in addObject() or insertObject()
// method. If the object does not exist, it throws an // method. If the object does not exist, it throws an
// ObjectNotFoundException. // ObjectNotFoundException.
virtual void* getObject(ObjectId id) = 0; virtual void* getObject(ObjectId id) = 0;
// Helper method to cast getObject() to the expected object type. // Helper method to cast getObject() to the expected object type.
template<class T> template<class T>
T* getObjectT(ObjectId id) T* getObjectT(ObjectId id)
{ {
return reinterpret_cast<T*>(getObject(id)); return reinterpret_cast<T*>(getObject(id));
} }
}; };
} // namespace undo } // namespace undo

View File

@ -7,15 +7,14 @@
#ifndef UNDO_UNDO_EXCEPTION_H_INCLUDED #ifndef UNDO_UNDO_EXCEPTION_H_INCLUDED
#define UNDO_UNDO_EXCEPTION_H_INCLUDED #define UNDO_UNDO_EXCEPTION_H_INCLUDED
#include "base/exception.h" #include <stdexcept>
namespace undo { namespace undo {
class UndoException : public base::Exception class UndoException : public std::runtime_error {
{ public:
public: UndoException(const char* msg) throw() : std::runtime_error(msg) { }
UndoException(const char* msg) throw() : base::Exception(msg) { } };
};
} // namespace undo } // namespace undo

View File

@ -14,67 +14,65 @@
namespace undo { namespace undo {
class ObjectsContainer; class ObjectsContainer;
class UndoersStack; class UndoersStack;
class UndoConfigProvider; class UndoConfigProvider;
class UndoHistoryDelegate class UndoHistoryDelegate {
{ public:
public: virtual ~UndoHistoryDelegate() { }
virtual ~UndoHistoryDelegate() { }
// Container of objects to insert & retrieve objects by ID // Container of objects to insert & retrieve objects by ID
virtual ObjectsContainer* getObjects() const = 0; virtual ObjectsContainer* getObjects() const = 0;
// Returns the limit of undo history in bytes. // Returns the limit of undo history in bytes.
virtual size_t getUndoSizeLimit() const = 0; virtual size_t getUndoSizeLimit() const = 0;
}; };
class UndoHistory : public UndoersCollector class UndoHistory : public UndoersCollector {
{ public:
public: UndoHistory(UndoHistoryDelegate* delegate);
UndoHistory(UndoHistoryDelegate* delegate); virtual ~UndoHistory();
virtual ~UndoHistory();
bool canUndo() const; bool canUndo() const;
bool canRedo() const; bool canRedo() const;
void doUndo(); void doUndo();
void doRedo(); void doRedo();
void clearRedo(); void clearRedo();
Undoer* getNextUndoer(); Undoer* getNextUndoer();
Undoer* getNextRedoer(); Undoer* getNextRedoer();
bool isSavedState() const; bool isSavedState() const;
void markSavedState(); void markSavedState();
ObjectsContainer* getObjects() const { return m_delegate->getObjects(); } ObjectsContainer* getObjects() const { return m_delegate->getObjects(); }
// UndoersCollector interface // UndoersCollector interface
void pushUndoer(Undoer* undoer); void pushUndoer(Undoer* undoer);
// Special method to add new undoers inside the last added group. // Special method to add new undoers inside the last added group.
// Returns true if the undoer was added in a group. // Returns true if the undoer was added in a group.
bool implantUndoerInLastGroup(Undoer* undoer); bool implantUndoerInLastGroup(Undoer* undoer);
private: private:
enum Direction { UndoDirection, RedoDirection }; enum Direction { UndoDirection, RedoDirection };
void runUndo(Direction direction); void runUndo(Direction direction);
void discardTail(); void discardTail();
void updateUndo(); void updateUndo();
void postUndoerAddedEvent(Undoer* undoer); void postUndoerAddedEvent(Undoer* undoer);
void checkSizeLimit(); void checkSizeLimit();
UndoHistoryDelegate* m_delegate; UndoHistoryDelegate* m_delegate;
UndoersStack* m_undoers; UndoersStack* m_undoers;
UndoersStack* m_redoers; UndoersStack* m_redoers;
int m_groupLevel; int m_groupLevel;
int m_diffCount; int m_diffCount;
int m_diffSaved; int m_diffSaved;
}; };
} // namespace undo } // namespace undo

View File

@ -11,42 +11,41 @@
namespace undo { namespace undo {
class ObjectsContainer; class ObjectsContainer;
class UndoersCollector; class UndoersCollector;
// Generic interface to undo/revert an action. // Generic interface to undo/revert an action.
class Undoer class Undoer {
{ public:
public: virtual ~Undoer() { }
virtual ~Undoer() { }
// Used to destroy the undoer when it is not needed anymore. A // Used to destroy the undoer when it is not needed anymore. A
// undoer is added in UndoersCollector, and then destroyed by // undoer is added in UndoersCollector, and then destroyed by
// UndoHistory using this method. // UndoHistory using this method.
// //
// This method is available because the Undo library does not know // This method is available because the Undo library does not know
// how this Undoer was created. So we cannot call just "delete undoer". // how this Undoer was created. So we cannot call just "delete undoer".
virtual void dispose() = 0; virtual void dispose() = 0;
// Returns the amount of memory (in bytes) which this instance is // Returns the amount of memory (in bytes) which this instance is
// using to revert the action. // using to revert the action.
virtual size_t getMemSize() const = 0; virtual size_t getMemSize() const = 0;
// Returns the kind of modification that this item does with the // Returns the kind of modification that this item does with the
// document. // document.
virtual Modification getModification() const = 0; virtual Modification getModification() const = 0;
// Returns true if this undoer is the first action of a group. // Returns true if this undoer is the first action of a group.
virtual bool isOpenGroup() const = 0; virtual bool isOpenGroup() const = 0;
// Returns true if this undoer is the last action of a group. // Returns true if this undoer is the last action of a group.
virtual bool isCloseGroup() const = 0; virtual bool isCloseGroup() const = 0;
// Reverts the action and adds to the "redoers" stack other set of // Reverts the action and adds to the "redoers" stack other set of
// actions to redo the reverted action. It is the main method used // actions to redo the reverted action. It is the main method used
// to undo any action. // to undo any action.
virtual void revert(ObjectsContainer* objects, UndoersCollector* redoers) = 0; virtual void revert(ObjectsContainer* objects, UndoersCollector* redoers) = 0;
}; };
} // namespace undo } // namespace undo

View File

@ -13,61 +13,60 @@
namespace undo { namespace undo {
class UndoHistory; class UndoHistory;
class Undoer; class Undoer;
// A stack of undoable actions (Undoers). There exist two stacks (see // A stack of undoable actions (Undoers). There exist two stacks (see
// the UndoHistory class): One stack to hold actions to be undone (the // the UndoHistory class): One stack to hold actions to be undone (the
// "undoers stack"), and another stack were actions are held to redo // "undoers stack"), and another stack were actions are held to redo
// reverted actions (the "redoers stack"). // reverted actions (the "redoers stack").
class UndoersStack : public UndoersCollector class UndoersStack : public UndoersCollector {
{ public:
public: enum PopFrom {
enum PopFrom { PopFromHead,
PopFromHead, PopFromTail
PopFromTail };
typedef std::vector<Undoer*> Items;
typedef Items::iterator iterator;
typedef Items::const_iterator const_iterator;
// Ctor and dtor
UndoersStack(UndoHistory* undoHistory);
~UndoersStack();
UndoHistory* getUndoHistory() const { return m_undoHistory; }
// Returns the collection of well-known serialized objects.
ObjectsContainer* getObjects() const;
iterator begin() { return m_items.begin(); }
iterator end() { return m_items.end(); }
const_iterator begin() const { return m_items.begin(); }
const_iterator end() const { return m_items.end(); }
bool empty() const { return m_items.empty(); }
void clear();
size_t getMemSize() const;
// UndoersCollector implementation
void pushUndoer(Undoer* undoer);
// Removes a undoer from the stack, the returned undoer must be
// deleted by the caller using Undoer::dispose().
Undoer* popUndoer(PopFrom popFrom);
size_t countUndoGroups() const;
private:
UndoHistory* m_undoHistory;
Items m_items;
// Bytes occupied by all undoers in the stack.
size_t m_size;
}; };
typedef std::vector<Undoer*> Items;
typedef Items::iterator iterator;
typedef Items::const_iterator const_iterator;
// Ctor and dtor
UndoersStack(UndoHistory* undoHistory);
~UndoersStack();
UndoHistory* getUndoHistory() const { return m_undoHistory; }
// Returns the collection of well-known serialized objects.
ObjectsContainer* getObjects() const;
iterator begin() { return m_items.begin(); }
iterator end() { return m_items.end(); }
const_iterator begin() const { return m_items.begin(); }
const_iterator end() const { return m_items.end(); }
bool empty() const { return m_items.empty(); }
void clear();
size_t getMemSize() const;
// UndoersCollector implementation
void pushUndoer(Undoer* undoer);
// Removes a undoer from the stack, the returned undoer must be
// deleted by the caller using Undoer::dispose().
Undoer* popUndoer(PopFrom popFrom);
size_t countUndoGroups() const;
private:
UndoHistory* m_undoHistory;
Items m_items;
// Bytes occupied by all undoers in the stack.
size_t m_size;
};
} // namespace undo } // namespace undo
#endif // UNDO_UNDOERS_STACK_H_INCLUDED #endif // UNDO_UNDOERS_STACK_H_INCLUDED