diff options
author | Fox Caminiti <fox@foxcam.net> | 2022-08-17 23:41:08 -0400 |
---|---|---|
committer | Fox Caminiti <fox@foxcam.net> | 2022-08-17 23:41:08 -0400 |
commit | 9062e0aae9f2f576b7a237c28028aa6b09feee5e (patch) | |
tree | 98b37bd442b9b6477f8061690744d73efeaa7d0b /undo.cpp | |
parent | e89dc91182a94e48ca9220a2fe075db680ddff04 (diff) |
undo and pen development
Diffstat (limited to 'undo.cpp')
-rw-r--r-- | undo.cpp | 82 |
1 files changed, 49 insertions, 33 deletions
@@ -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++; } |