summaryrefslogtreecommitdiff
path: root/undo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'undo.cpp')
-rw-r--r--undo.cpp82
1 files changed, 49 insertions, 33 deletions
diff --git a/undo.cpp b/undo.cpp
index 3d70d49..e288784 100644
--- a/undo.cpp
+++ b/undo.cpp
@@ -1,5 +1,16 @@
// get ready for some MLG...
+// The undo system currently works in two layers: a lower-level structless
+// stack that records "actions" and a higher-level array of "entries" that
+// bundle actions together. An action can either record a single change to a
+// specific memory address or a shift of pointers. Entries are what the user
+// sees and can contain multiple actions (i.e. adding a source changes the
+// value of the string and the increment of how many sources there are).
+// Entries are allowed to call functions in case there's something that can't
+// be incorporated into this memory model (i.e. deallocating libav contexts
+// when a layer's creation is undone), though they should be used only
+// when necessary.
+
// These get four things pushed together: the address of what's being
// changed, what type the data is, the original data, and the type again.
// The type is encoded twice so we always know how big the data is whether
@@ -92,18 +103,19 @@ void Action_Change_Commit(memory *Memory, void *DataAddress, void *OriginalData,
*(action_change_type *)Data = ActionChange;
}
-void Action_Entry_Begin(memory *Memory, action_entry_type Type, char *Name)
-{
- Memory->Action.Entry[Memory->Action.Index].Name = Name;
- Memory->Action.Entry[Memory->Action.Index].Type = Type;
-}
-
-void Action_Entry_Begin2(memory *Memory, action_entry_type Type, char *Name, char *Name2)
+// This is only called when we're certain the action is going to be taken.
+void Action_Entry_Commit(memory *Memory, action_entry_type Type, char *Name)
{
+ // We need to at least clear NumberOfActions in case this index is being reused.
+ Memory->Action.Entry[Memory->Action.Index] = {};
Memory->Action.Entry[Memory->Action.Index].Name = Name;
Memory->Action.Entry[Memory->Action.Index].Type = Type;
- Memory->Action.Entry[Memory->Action.Index + 1].Name = Name2;
- Memory->Action.Entry[Memory->Action.Index + 1].Type = Type;
+ // Effectively deletes entries in front if we're beginning out of an undo.
+ // It wouldn't be all that much more difficult to support branched undoing
+ // now that I think about it... (would anyone use it though?)
+ if (Memory->Action.Index != Memory->Action.NumberOfEntries) {
+ Memory->Action.NumberOfEntries = Memory->Action.Index;
+ }
}
void Action_Entry_SetPointer(memory *Memory, void *Data)
@@ -247,35 +259,39 @@ void Action_Change_Redo(memory *Memory) {
}
void Action_Undo(memory *Memory) {
- Memory->Action.Index--;
- action_entry Entry = Memory->Action.Entry[Memory->Action.Index];
- switch (Entry.Type)
- {
- case action_entry_layerinit:
+ if (Memory->Action.Index != 0) {
+ Memory->Action.Index--;
+ action_entry Entry = Memory->Action.Entry[Memory->Action.Index];
+ switch (Entry.Type)
{
- AV_Dealloc((av_info *)*(ptrsize *)Entry.ExtraPointer);
- *(ptrsize *)Entry.ExtraPointer = 0x0; // what actually dereferences the pointer
- } break;
- case action_entry_default:
- {
- } break;
+ case action_entry_layerinit:
+ {
+ AV_Dealloc((av_info *)*(ptrsize *)Entry.ExtraPointer);
+ *(ptrsize *)Entry.ExtraPointer = 0x0; // what actually dereferences the pointer
+ } break;
+ case action_entry_default:
+ {
+ } break;
+ }
+ for (int i = 0; i < Entry.NumberOfActions; i++)
+ Action_Change_Undo(Memory);
}
- for (int i = 0; i < Entry.NumberOfActions; i++)
- Action_Change_Undo(Memory);
}
void Action_Redo(memory *Memory) {
- action_entry Entry = Memory->Action.Entry[Memory->Action.Index];
- switch (Entry.Type)
- {
- case action_entry_layerinit:
+ if (Memory->Action.Index != Memory->Action.NumberOfEntries) {
+ action_entry Entry = Memory->Action.Entry[Memory->Action.Index];
+ switch (Entry.Type)
{
- } break;
- case action_entry_default:
- {
- } break;
+ case action_entry_layerinit:
+ {
+ } break;
+ case action_entry_default:
+ {
+ } break;
+ }
+ for (int i = 0; i < Entry.NumberOfActions; i++)
+ Action_Change_Redo(Memory);
+ Memory->Action.Index++;
}
- for (int i = 0; i < Entry.NumberOfActions; i++)
- Action_Change_Redo(Memory);
- Memory->Action.Index++;
}