28 static std::unique_ptr<UndoAction>
create(
29 std::string action_name,
30 std::function<
void()> undo,
31 std::function<
void()> redo)
33 auto a = std::make_unique<UndoAction>();
34 a->name = std::move(action_name);
35 a->undo_fn = std::move(undo);
36 a->redo_fn = std::move(redo);
44 std::vector<std::unique_ptr<UndoAction>>
actions;
80 void perform(std::unique_ptr<UndoAction> action) {
81 if (action->redo_fn) action->redo_fn();
83 if (in_transaction_) {
84 current_transaction_->actions.push_back(std::move(action));
88 const auto now = Clock::now();
89 if (coalesce_window_.count() > 0 && !undo_stack_.empty() &&
90 (now - last_perform_time_) <= coalesce_window_) {
95 undo_stack_.back().actions.push_back(std::move(action));
96 last_perform_time_ = now;
102 tx.
name = action->name;
103 tx.
actions.push_back(std::move(action));
104 push_undo(std::move(tx));
105 last_perform_time_ = now;
111 if (in_transaction_) {
112 current_transaction_->actions.push_back(std::move(action));
115 tx.
name = action->name;
116 tx.
actions.push_back(std::move(action));
117 push_undo(std::move(tx));
123 current_transaction_ = std::make_unique<UndoTransaction>();
124 current_transaction_->name = name;
125 in_transaction_ =
true;
130 if (in_transaction_ && current_transaction_ && !current_transaction_->actions.empty()) {
131 push_undo(std::move(*current_transaction_));
133 current_transaction_.reset();
134 in_transaction_ =
false;
140 if (in_transaction_ && current_transaction_) {
141 for (
auto it = current_transaction_->actions.rbegin();
142 it != current_transaction_->actions.rend(); ++it) {
143 if ((*it)->undo_fn) (*it)->undo_fn();
146 current_transaction_.reset();
147 in_transaction_ =
false;
152 if (undo_stack_.empty())
return false;
154 auto tx = std::move(undo_stack_.back());
155 undo_stack_.pop_back();
158 for (
auto it = tx.actions.rbegin(); it != tx.actions.rend(); ++it) {
159 if ((*it)->undo_fn) (*it)->undo_fn();
162 redo_stack_.push_back(std::move(tx));
166 last_perform_time_ = Clock::time_point{};
173 if (redo_stack_.empty())
return false;
175 auto tx = std::move(redo_stack_.back());
176 redo_stack_.pop_back();
179 for (
auto& action : tx.actions) {
180 if (action->redo_fn) action->redo_fn();
183 undo_stack_.push_back(std::move(tx));
184 last_perform_time_ = Clock::time_point{};
190 bool can_undo()
const {
return !undo_stack_.empty(); }
193 bool can_redo()
const {
return !redo_stack_.empty(); }
197 return undo_stack_.empty() ?
"" : undo_stack_.back().name;
202 return redo_stack_.empty() ?
"" : redo_stack_.back().name;
206 int undo_count()
const {
return static_cast<int>(undo_stack_.size()); }
209 int redo_count()
const {
return static_cast<int>(redo_stack_.size()); }
220 max_history_ = max < 0 ? 0 : max;
221 trim_to_max_history();
234 coalesce_window_ = window;
239 using Clock = std::chrono::steady_clock;
241 std::vector<UndoTransaction> undo_stack_;
242 std::vector<UndoTransaction> redo_stack_;
243 int max_history_ = 100;
244 bool in_transaction_ =
false;
245 std::unique_ptr<UndoTransaction> current_transaction_;
246 std::chrono::milliseconds coalesce_window_{0};
247 Clock::time_point last_perform_time_{};
249 void push_undo(UndoTransaction tx) {
251 undo_stack_.push_back(std::move(tx));
252 trim_to_max_history();
256 void trim_to_max_history() {
257 while (
static_cast<int>(undo_stack_.size()) > max_history_) {
258 undo_stack_.erase(undo_stack_.begin());
Manages undo/redo history with configurable depth.
Definition undo_manager.hpp:70
std::string redo_name() const
Get the name of the next redo action.
Definition undo_manager.hpp:201
std::function< void()> on_state_changed
Called whenever the undo/redo state changes.
Definition undo_manager.hpp:226
int max_history() const
Definition undo_manager.hpp:223
void add_without_executing(std::unique_ptr< UndoAction > action)
Perform an action without immediately executing it.
Definition undo_manager.hpp:110
std::chrono::milliseconds coalesce_window() const
Definition undo_manager.hpp:236
void set_coalesce_window(std::chrono::milliseconds window)
Time-window coalescing.
Definition undo_manager.hpp:233
void cancel_transaction()
Cancel the current transaction (discard without pushing).
Definition undo_manager.hpp:138
void end_transaction()
End the current transaction and push it to the undo stack.
Definition undo_manager.hpp:129
bool redo()
Redo the most recently undone action/transaction.
Definition undo_manager.hpp:172
void begin_transaction(const std::string &name)
Begin a transaction — all subsequent perform() calls are grouped.
Definition undo_manager.hpp:122
std::string undo_name() const
Get the name of the next undo action (for menu display).
Definition undo_manager.hpp:196
int redo_count() const
Number of redo steps available.
Definition undo_manager.hpp:209
void perform(std::unique_ptr< UndoAction > action)
Perform an action and add it to the undo history.
Definition undo_manager.hpp:80
void set_max_history(int max)
Set maximum undo history depth. Oldest entries are discarded.
Definition undo_manager.hpp:219
void clear()
Clear all undo/redo history.
Definition undo_manager.hpp:212
bool undo()
Undo the most recent action/transaction.
Definition undo_manager.hpp:151
bool can_undo() const
Check if undo is available.
Definition undo_manager.hpp:190
bool can_redo() const
Check if redo is available.
Definition undo_manager.hpp:193
int undo_count() const
Number of undo steps available.
Definition undo_manager.hpp:206
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
A single undoable action with undo and redo functions.
Definition undo_manager.hpp:23
std::string name
Definition undo_manager.hpp:24
static std::unique_ptr< UndoAction > create(std::string action_name, std::function< void()> undo, std::function< void()> redo)
Definition undo_manager.hpp:28
std::function< void()> undo_fn
Definition undo_manager.hpp:25
std::function< void()> redo_fn
Definition undo_manager.hpp:26
A group of actions that undo/redo together as one step.
Definition undo_manager.hpp:42
std::vector< std::unique_ptr< UndoAction > > actions
Definition undo_manager.hpp:44
std::string name
Definition undo_manager.hpp:43