1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#pragma once
#include "iundo.h"
#include "Stack.h"
namespace undo
{
/**
* greebo: This class represents a one-shot state saver, only the first
* call to saveState() will submit the IUndoable's state, subsequent calls
* don't have any effect.
*
* The associated UndoStack reference is set up right before an undo/redo
* operation by the UndoSystem, and is cleared after submission in
* the saveState() routine.
*/
class UndoStackFiller final :
public IUndoStateSaver
{
private:
IUndoSystem& _owner;
IUndoable& _undoable;
UndoStack* _stack;
public:
using Ptr = std::shared_ptr<UndoStackFiller>;
UndoStackFiller(IUndoSystem& owner, IUndoable& undoable) :
_owner(owner),
_undoable(undoable),
_stack(nullptr)
{}
// Noncopyable
UndoStackFiller(const UndoStackFiller& other) = delete;
UndoStackFiller& operator=(const UndoStackFiller& other) = delete;
void saveState() override
{
// If the stack reference is empty, the associated undoable
// already submitted its state this round
if (_stack == nullptr) return;
// Export the Undoable's memento
_stack->save(_undoable);
// Make sure the stack is dissociated after saving
// to make sure further saveState() calls don't have any effect
_stack = nullptr;
}
IUndoSystem& getUndoSystem() override
{
return _owner;
}
// Assign the stack of this class. This usually happens when starting
// an undo or redo operation.
void setStack(UndoStack* stack)
{
_stack = stack;
}
};
} // namespace undo
|