From 9062e0aae9f2f576b7a237c28028aa6b09feee5e Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Wed, 17 Aug 2022 23:41:08 -0400 Subject: undo and pen development --- undo.cpp | 82 ++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 33 deletions(-) (limited to 'undo.cpp') 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++; } -- cgit v1.2.3