Unravel Engine C++ Reference
Loading...
Searching...
No Matches
undo_redo_stack.cpp
Go to the documentation of this file.
1#include "undo_redo_stack.h"
3
4namespace unravel
5{
6
7void undo_redo_stack::push_if_undoable(std::shared_ptr<editing_action_t> action)
8{
9 // Only add to undo stack if the action is undoable
10 if (action && action->is_undoable())
11 {
12 // Remove any actions after current_index (handles branching undo/redo history)
13 if (current_index < actions.size())
14 {
15 actions.resize(current_index);
16 }
17
18 // Check if we can merge with the last action
19 if (!actions.empty() && current_index > 0)
20 {
21 auto& last_action = actions[current_index - 1];
22
23 auto type = action->get_meta_type();
24 auto last_type = last_action->get_meta_type();
25
26 // Common merge checks: same type, valid operation_id, and same operation
27 bool can_merge = last_action &&
28 (type == last_type) &&
29 action->merge_key != 0 &&
30 action->merge_key == last_action->merge_key &&
31 action->is_mergeable(*last_action);
32
33 if (can_merge)
34 {
35 // Merge the new action with the last one
36 action->merge_with(*last_action);
37 // Replace the last action with the merged one
38 actions[current_index - 1] = std::move(action);
39 return; // Don't increment current_index since we replaced, not added
40 }
41 }
42
43 actions.emplace_back(std::move(action));
44 current_index = actions.size(); // Point to the newly added action
45 }
46}
47
48auto undo_redo_stack::can_undo() const -> bool
49{
50 return current_index > 0 && !actions.empty();
51}
52
53auto undo_redo_stack::can_redo() const -> bool
54{
55 return current_index < actions.size();
56}
57
58auto undo_redo_stack::undo() -> std::shared_ptr<editing_action_t>
59{
60 std::shared_ptr<editing_action_t> action = nullptr;
61 if (can_undo())
62 {
63 current_index--;
64 if (current_index < actions.size() && actions[current_index])
65 {
66 action = actions[current_index];
67
68 if(action->is_valid())
69 {
70 action->execution_count++;
71 action->undo_action();
72 last_action_name = action->get_name();
73 last_action_elapsed_time = delta_t::zero();
74 }
75 else
76 {
77 ImGui::PushNotification(ImGuiToast(ImGuiToastType_Warning, 1000,"Unable to Undo.\nMissing references."));
78 }
79
80 }
81 }
82 return action;
83}
84
85auto undo_redo_stack::redo() -> std::shared_ptr<editing_action_t>
86{
87 std::shared_ptr<editing_action_t> action = nullptr;
88 if (can_redo())
89 {
90 if (current_index < actions.size() && actions[current_index])
91 {
92 action = actions[current_index];
93 if(action->is_valid())
94 {
95 action->execution_count++;
96 action->do_action();
97 last_action_name = action->get_name();
98 last_action_elapsed_time = delta_t::zero();
99 }
100 else
101 {
102 ImGui::PushNotification(ImGuiToast( ImGuiToastType_Warning, 1000,"Unable to Redo.\nMissing references."));
103 }
104 }
105 current_index++;
106 }
107 return nullptr;
108}
109
111{
112 actions.clear();
113 current_index = 0;
114 last_action_name.clear();
115 last_action_elapsed_time = delta_t::zero();
116}
117
118} // namespace unravel
@ ImGuiToastType_Warning
std::function< bool()> can_merge
texture_job_type type
NOTIFY_INLINE void PushNotification(const ImGuiToast &toast)
Insert a new toast in the list.
auto redo() -> std::shared_ptr< editing_action_t >
auto undo() -> std::shared_ptr< editing_action_t >
void push_if_undoable(std::shared_ptr< editing_action_t > action)
auto can_undo() const -> bool
auto can_redo() const -> bool
std::vector< std::shared_ptr< editing_action_t > > actions