openblocks/editor/undohistory.h

61 lines
No EOL
1.7 KiB
C++

#pragma once
#include "datatypes/signal.h"
#include "datatypes/variant.h"
#include "objects/base/instance.h"
#include "utils.h"
#include <deque>
#include <memory>
#include <stack>
struct UndoStatePropertyChanged {
std::shared_ptr<Instance> affectedInstance;
std::string property;
Variant oldValue;
Variant newValue;
};
struct UndoStateInstanceCreated {
std::shared_ptr<Instance> instance;
std::shared_ptr<Instance> newParent;
};
struct UndoStateInstanceRemoved {
std::shared_ptr<Instance> instance;
std::shared_ptr<Instance> oldParent;
};
struct UndoStateInstanceReparented {
std::shared_ptr<Instance> instance;
nullable std::shared_ptr<Instance> oldParent;
nullable std::shared_ptr<Instance> newParent;
};
struct UndoStateSelectionChanged {
std::vector<std::shared_ptr<Instance>> oldSelection;
std::vector<std::shared_ptr<Instance>> newSelection;
};
typedef std::variant<UndoStatePropertyChanged, UndoStateInstanceCreated, UndoStateInstanceRemoved, UndoStateInstanceReparented, UndoStateSelectionChanged> UndoStateChange;
typedef std::vector<UndoStateChange> UndoState;
typedef std::function<void()> UndoStateChangedListener;
class UndoHistory {
// Ignore PushState requests
bool processingUndo = false;
std::deque<UndoState> undoHistory;
std::stack<UndoState> redoHistory;
UndoStateChangedListener undoStateListener;
public:
int maxBufferSize = 100;
void PushState(UndoState);
void Undo();
void Redo();
void Reset();
inline bool CanUndo() { return !undoHistory.empty(); }
inline bool CanRedo() { return !redoHistory.empty(); }
void SetUndoStateListener(UndoStateChangedListener listener);
};