diff options
author | Fox Caminiti <fox@foxcam.net> | 2023-01-20 10:10:54 -0500 |
---|---|---|
committer | Fox Caminiti <fox@foxcam.net> | 2023-01-20 10:10:54 -0500 |
commit | 2f164ae23bcd8a857081529189b484a1515f2834 (patch) | |
tree | c7f5b163f7e1585a8fbdb3b8fb7fb012761ae239 /src/undo.cpp | |
parent | 1d0d8549411e23394059f420f053cc3ee28dacfb (diff) |
youarelazy
Diffstat (limited to 'src/undo.cpp')
-rw-r--r-- | src/undo.cpp | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/src/undo.cpp b/src/undo.cpp index ec85530..38c22ef 100644 --- a/src/undo.cpp +++ b/src/undo.cpp @@ -1,3 +1,7 @@ +#if SPECIAL +#include "main.h" +#endif + struct history_info { uint16 ActionCount_Total; uint16 ActionCount_EndOfPlayhead; @@ -11,7 +15,7 @@ struct history_info { }; static uint64 -History_GetActionSize(history_entry_list *History, int i, uint16 ActionCount_EndOfPlayhead) +History_GetActionSize(history_entry_list *History, int i) { history_action *Action = &History->Action[i]; if (Action->Type == action_type_swap || Action->Type == action_type_swap_bitmap) @@ -44,7 +48,7 @@ History_GetTreeInfo(history_entry_list *History, uint16 SampleIndex) for (int i = 0; i < Info.ActionCount_Total; i++) { - uint64 Size = History_GetActionSize(History, i, Info.ActionCount_EndOfPlayhead); + uint64 Size = History_GetActionSize(History, i); Info.ActionOffset_Total += Size; if (i < Info.ActionCount_EndOfPlayhead) Info.ActionOffset_EndOfPlayhead += Size; @@ -202,6 +206,9 @@ void History_Entry_Commit(memory *Memory, char *Name) history_entry *Entry = &History->Entry[History->EntryPlayhead]; Entry->Name = Name; Entry->NumberOfActions = 0; + if (History->NumberOfEntries > MAX_HISTORY_ENTRIES) { + Assert(0); + } // Effectively deletes entries in front if we're beginning out of an undo. if (History->NumberOfEntries != History->EntryPlayhead) History->NumberOfEntries = History->EntryPlayhead; @@ -223,6 +230,42 @@ void History_Entry_End(memory *Memory) #endif } +static void +History_Purge(memory *Memory, history_entry_list *History, uint64 ActionCount_Total, uint64 ActionOffset_Total, uint64 PurgeSize) +{ + int Size = 0; + int EntryIndex = 0; + int ActionIndex = 0; + int ActionCount = 0; + while (Size < PurgeSize) { + history_entry *Entry = &History->Entry[EntryIndex]; + ActionCount += Entry->NumberOfActions; + while (ActionIndex < ActionCount) { + Size += History_GetActionSize(History, ActionIndex); + ActionIndex++; + } + EntryIndex++; + } + int EntryCount = (EntryIndex + 1); + { + uint8 *Address_Start = (uint8 *)Memory_AddressAtOffset(Memory, P_UndoBuffer, Size); + uint8 *Address_End = (uint8 *)Memory_AddressAtOffset(Memory, P_UndoBuffer, ActionOffset_Total); + Arbitrary_ShiftData(Address_Start, Address_End, Size, -1); + } + { + uint8 *Address_Start = (uint8 *)&History->Entry[EntryCount]; + uint8 *Address_End = (uint8 *)&History->Entry[History->NumberOfEntries]; + Arbitrary_ShiftData(Address_Start, Address_End, sizeof(history_entry) * EntryCount, -1); + } + { + uint8 *Address_Start = (uint8 *)&History->Action[ActionCount]; + uint8 *Address_End = (uint8 *)&History->Action[ActionCount_Total]; + Arbitrary_ShiftData(Address_Start, Address_End, sizeof(history_action) * ActionCount, -1); + } + History->NumberOfEntries -= EntryCount; + History->EntryPlayhead -= EntryCount; +} + // NOTE(fox): Shift is the only action that additionally changes the data after // the info is put on the tree, since it's always the same function used. @@ -233,6 +276,15 @@ static void History_Action_Add(memory *Memory, history_action ActionData, void * history_info Info = History_GetTreeInfo(History, History->EntryPlayhead - 1); + if ((Info.ActionOffset_EndOfPlayhead + ActionData.Size) > Memory->Slot[P_UndoBuffer].Size) { + History_Purge(Memory, History, Info.ActionCount_Total, Info.ActionOffset_Total, ActionData.Size * 4); + Entry = &History->Entry[History->EntryPlayhead - 1]; + Info = History_GetTreeInfo(History, History->EntryPlayhead - 1); + } + if (Info.ActionCount_Total > MAX_HISTORY_ACTIONS) { + Assert(0); + } + history_action *Action = &History->Action[Info.ActionCount_Total]; *Action = ActionData; |