summaryrefslogtreecommitdiff
path: root/undo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'undo.cpp')
-rw-r--r--undo.cpp315
1 files changed, 196 insertions, 119 deletions
diff --git a/undo.cpp b/undo.cpp
index 82a37ea..6ebdfca 100644
--- a/undo.cpp
+++ b/undo.cpp
@@ -11,107 +11,177 @@
// 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
-// we're undoing or redoing.
+// These get four things pushed together: what type the data is, address, the
+// original data, and the type again. The type is encoded twice so we always
+// know how big the data is whether we're undoing or redoing.
// We need to encode data that's able to go from A -> B as well as B -> A. Thus
// for the ints I encode the difference instead of just whatever the last value
// was. Strings currently just stores both.
-void Action_Change_Commit(memory *Memory, void *DataAddress, void *OriginalData, void *NewData, action_change_type ActionChange)
+void History_Action_Change(memory *Memory, void *DataAddress, void *OriginalData, void *NewData, action_type ActionChange)
{
Memory->Action.Entry[Memory->Action.Index].NumberOfActions++;
- void *UndoEntry = AllocateMemory(Memory, sizeof(void *), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer);
+ *(action_type *)Data = ActionChange;
+ void *UndoEntry = Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
*(ptrsize *)UndoEntry = (ptrsize)DataAddress;
- void *Data = AllocateMemory(Memory, sizeof(action_change_type), P_UndoBuffer);
- *(action_change_type *)Data = ActionChange;
switch (ActionChange)
{
- case action_change_u16:
+ case action_type_change_u16:
{
uint16 OriginalValue = *(uint16 *)OriginalData;
uint16 NewValue = *(uint16 *)NewData;
uint16 Difference = NewValue - OriginalValue;
- void *Data = AllocateMemory(Memory, sizeof(uint16), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(uint16), P_UndoBuffer);
*(uint16 *)Data = Difference;
*(uint16 *)DataAddress = *(uint16 *)NewData;
} break;
- case action_change_i16:
+ case action_type_change_i16:
{
int16 OriginalValue = *(int16 *)OriginalData;
int16 NewValue = *(int16 *)NewData;
int16 Difference = NewValue - OriginalValue;
- void *Data = AllocateMemory(Memory, sizeof(int16), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer);
*(int16 *)Data = Difference;
*(int16 *)DataAddress = *(int16 *)NewData;
} break;
- case action_change_u32:
+ case action_type_change_u32:
{
uint32 OriginalValue = *(uint32 *)OriginalData;
uint32 NewValue = *(uint32 *)NewData;
uint32 Difference = NewValue - OriginalValue;
- void *Data = AllocateMemory(Memory, sizeof(uint32), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(uint32), P_UndoBuffer);
*(uint32 *)Data = Difference;
*(uint32 *)DataAddress = *(uint32 *)NewData;
} break;
- case action_change_i32:
+ case action_type_change_i32:
{
int32 OriginalValue = *(int32 *)OriginalData;
int32 NewValue = *(int32 *)NewData;
int32 Difference = NewValue - OriginalValue;
- void *Data = AllocateMemory(Memory, sizeof(int32), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(int32), P_UndoBuffer);
*(int32 *)Data = Difference;
*(int32 *)DataAddress = *(int32 *)NewData;
} break;
- case action_change_r32:
+ case action_type_change_r32:
{
real32 OriginalValue = *(real32 *)OriginalData;
real32 NewValue = *(real32 *)NewData;
real32 Difference = NewValue - OriginalValue;
- void *Data = AllocateMemory(Memory, sizeof(real32), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(real32), P_UndoBuffer);
*(real32 *)Data = Difference;
*(real32 *)DataAddress = *(real32 *)NewData;
} break;
- case action_change_u64:
+ case action_type_change_u64:
{
uint64 OriginalValue = *(uint64 *)OriginalData;
uint64 NewValue = *(uint64 *)NewData;
uint64 Difference = NewValue - OriginalValue;
- void *Data = AllocateMemory(Memory, sizeof(uint64), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(uint64), P_UndoBuffer);
*(uint64 *)Data = Difference;
*(uint64 *)DataAddress = *(uint64 *)NewData;
} break;
- case action_change_ptr:
+ case action_type_change_ptr:
{
ptrsize OriginalValue = *(ptrsize *)OriginalData;
ptrsize NewValue = *(ptrsize *)NewData;
ptrsize Difference = NewValue - OriginalValue;
- void *Data = AllocateMemory(Memory, sizeof(ptrsize), P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, sizeof(ptrsize), P_UndoBuffer);
*(ptrsize *)Data = Difference;
*(ptrsize *)DataAddress = *(ptrsize *)NewData;
} break;
- case action_change_string:
+ case action_type_change_string:
{
- void *Data = AllocateMemory(Memory, STRING_SIZE, P_UndoBuffer);
+ void *Data = Memory_Advance(Memory, STRING_SIZE, P_UndoBuffer);
CopyStrings(Data, OriginalData);
- Data = AllocateMemory(Memory, STRING_SIZE, P_UndoBuffer);
+ Data = Memory_Advance(Memory, STRING_SIZE, P_UndoBuffer);
CopyStrings(Data, NewData);
CopyStrings(DataAddress, NewData);
} break;
+ default:
+ {
+ Assert(0);
+ }
+
}
- Data = AllocateMemory(Memory, sizeof(action_change_type), P_UndoBuffer);
- *(action_change_type *)Data = ActionChange;
+ Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer);
+ *(action_type *)Data = ActionChange;
}
// Helper functions for common types of data changes.
-void Action_Change_Commit_SwapBool(memory *Memory, bool32 *Bool)
+void History_Action_Change_SwapBool(memory *Memory, bool32 *Bool)
{
bool32 OppositeBool = *Bool ^ 1;
- Action_Change_Commit(Memory, Bool, Bool, &OppositeBool, action_change_i32);
+ History_Action_Change(Memory, Bool, Bool, &OppositeBool, action_type_change_i32);
+}
+
+void History_Action_Change_Increment(memory *Memory, void *Data, action_type ActionChange)
+{
+ switch (ActionChange)
+ {
+ case action_type_change_u16:
+ {
+ uint16 DataPlusOne = (*(uint16 *)Data) + 1;
+ History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange);
+ } break;
+ case action_type_change_i16:
+ {
+ int16 DataPlusOne = (*(int16 *)Data) + 1;
+ History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange);
+ } break;
+ case action_type_change_u32:
+ {
+ uint32 DataPlusOne = (*(uint32 *)Data) + 1;
+ History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange);
+ } break;
+ case action_type_change_i32:
+ {
+ int32 DataPlusOne = (*(int32 *)Data) + 1;
+ History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange);
+ } break;
+ case action_type_change_r32:
+ {
+ real32 DataPlusOne = (*(real32 *)Data) + 1;
+ History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange);
+ } break;
+ case action_type_change_u64:
+ {
+ uint64 DataPlusOne = (*(uint64 *)Data) + 1;
+ History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange);
+ } break;
+ default:
+ {
+ Assert(0);
+ }
+ }
+}
+
+void History_Action_Shift(memory *Memory, action_type ActionChange, void *DataAddress, int16 Direction, int16 Index)
+{
+ Memory->Action.Entry[Memory->Action.Index].NumberOfActions++;
+ void *Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer);
+ *(action_type *)Data = ActionChange;
+ switch (ActionChange)
+ {
+ case action_type_shift_keyframe:
+ {
+ void *DataPropertyAddress = Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ *(ptrsize *)DataPropertyAddress = (ptrsize)DataAddress;
+ void *DataDirection = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer);
+ *(ptrsize *)DataDirection = (ptrsize)Direction;
+ void *DataIndex = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer);
+ *(ptrsize *)DataIndex = (ptrsize)Index;
+ } break;
+ default:
+ {
+ Assert(0);
+ } break;
+ }
+ Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer);
+ *(action_type *)Data = ActionChange;
}
// 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)
+void History_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] = {};
@@ -125,147 +195,154 @@ void Action_Entry_Commit(memory *Memory, action_entry_type Type, char *Name)
}
}
-void Action_Entry_SetPointer(memory *Memory, void *Data)
+void History_Entry_SetPointer(memory *Memory, void *Data)
{
Memory->Action.Entry[Memory->Action.Index].ExtraPointer = Data;
}
-void Action_Entry_End(memory *Memory)
+void History_Entry_End(memory *Memory)
{
Memory->Action.Index++;
Memory->Action.NumberOfEntries++;
}
-// TODO(fox): Maybe take the extra lines to separate the incrementing of the
-// address from the variable assignment to improve legibility.
-
// The pointer is unwinded.
-void Action_Change_Undo(memory *Memory) {
- memory_table *Table = &Memory->Slot[P_UndoBuffer];
- uint8 *LastPos = (uint8 *)Table->Address + Table->CurrentPosition;
- action_change_type *ActionType = (action_change_type *)LastPos - 1;
- uint8 *TableAddress;
+void History_Action_Undo(memory *Memory) {
+ void *LastPos = Memory_Rewind(Memory, sizeof(action_type), P_UndoBuffer);
+ action_type *ActionType = (action_type *)LastPos;
+
switch (*ActionType)
{
- case action_change_u16:
+ case action_type_change_u16:
+ {
+ uint16 *Difference = (uint16 *)Memory_Rewind(Memory, sizeof(uint16), P_UndoBuffer);
+ void **Address = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ *(uint16 *)*Address -= *Difference;
+ } break;
+ case action_type_change_i16:
{
- uint16 *Difference = (uint16 *)ActionType - 1;
- TableAddress = (uint8 *)Difference - sizeof(ptrsize) - sizeof(action_change_type);
- void *Address = (void *)*(ptrsize *)TableAddress;
- *(uint16 *)Address -= *Difference;
+ int16 *Difference = (int16 *)Memory_Rewind(Memory, sizeof(int16), P_UndoBuffer);
+ void **Address = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ *(int16 *)*Address -= *Difference;
} break;
- case action_change_i16:
+ case action_type_change_u32:
{
- int16 *Difference = (int16 *)ActionType - 1;
- TableAddress = (uint8 *)Difference - sizeof(ptrsize) - sizeof(action_change_type);
- void *Address = (void *)*(ptrsize *)TableAddress;
- *(int16 *)Address -= *Difference;
+ uint32 *Difference = (uint32 *)Memory_Rewind(Memory, sizeof(uint32), P_UndoBuffer);
+ void **Address = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ *(uint32 *)*Address -= *Difference;
} break;
- case action_change_u32:
+ case action_type_change_i32:
{
- uint32 *Difference = (uint32 *)ActionType - 1;
- TableAddress = (uint8 *)Difference - sizeof(ptrsize) - sizeof(action_change_type);
- void *Address = (void *)*(ptrsize *)TableAddress;
- *(uint32 *)Address -= *Difference;
+ int32 *Difference = (int32 *)Memory_Rewind(Memory, sizeof(int32), P_UndoBuffer);
+ void **Address = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ *(int32 *)*Address -= *Difference;
} break;
- case action_change_i32:
+ case action_type_change_r32:
{
- int32 *Difference = (int32 *)ActionType - 1;
- TableAddress = (uint8 *)Difference - sizeof(ptrsize) - sizeof(action_change_type);
- void *Address = (void *)*(ptrsize *)TableAddress;
- *(int32 *)Address -= *Difference;
+ real32 *Difference = (real32 *)Memory_Rewind(Memory, sizeof(real32), P_UndoBuffer);
+ void **Address = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ *(real32 *)*Address -= *Difference;
} break;
- case action_change_r32:
+ case action_type_change_u64:
{
- real32 *Difference = (real32 *)ActionType - 1;
- TableAddress = (uint8 *)Difference - sizeof(ptrsize) - sizeof(action_change_type);
- void *Address = (void *)*(ptrsize *)TableAddress;
- *(real32 *)Address -= *Difference;
+ uint64 *Difference = (uint64 *)Memory_Rewind(Memory, sizeof(uint64), P_UndoBuffer);
+ void **Address = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ *(uint64 *)*Address -= *Difference;
} break;
- case action_change_u64:
+ case action_type_change_ptr:
{
- uint64 *Difference = (uint64 *)ActionType - 1;
- TableAddress = (uint8 *)Difference - sizeof(ptrsize) - sizeof(action_change_type);
- void *Address = (void *)*(ptrsize *)TableAddress;
- *(uint64 *)Address -= *Difference;
+ ptrsize *Difference = (ptrsize *)Memory_Rewind(Memory, sizeof(ptrsize), P_UndoBuffer);
+ void **Address = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ *(ptrsize *)*Address -= *Difference;
+ } break;
+ case action_type_change_string:
+ {
+ Assert(0);
} break;
- case action_change_ptr:
+ case action_type_shift_keyframe:
{
- ptrsize *Difference = (ptrsize *)ActionType - 1;
- TableAddress = (uint8 *)Difference - sizeof(ptrsize) - sizeof(action_change_type);
- void *Address = (void *)*(ptrsize *)TableAddress;
- *(ptrsize *)Address -= *Difference;
+ void *DataIndex = Memory_Rewind(Memory, sizeof(int16), P_UndoBuffer);
+ void *DataDirection = Memory_Rewind(Memory, sizeof(int16), P_UndoBuffer);
+ void **DataPropertyAddress = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer);
+ ShiftKeyframes((property_channel *)*DataPropertyAddress, *(int16 *)DataDirection * -1, *(int16 *)DataIndex);
} break;
- case action_change_string:
+ default:
{
- TableAddress = 0x0;
Assert(0);
} break;
}
- Table->CurrentPosition = (TableAddress - (uint8 *)Table->Address);
+ void *EndPos = Memory_Rewind(Memory, sizeof(action_type), P_UndoBuffer);
}
// The pointer is rewinded.
-void Action_Change_Redo(memory *Memory) {
- memory_table *Table = &Memory->Slot[P_UndoBuffer];
- uint8 *LastPos = (uint8 *)Table->Address + Table->CurrentPosition;
- void *Address = (void *)*(ptrsize *)LastPos;
- action_change_type *ActionType = (action_change_type *)(LastPos + sizeof(void *));
- uint8 *TableAddress;
+void History_Action_Redo(memory *Memory) {
+ void *LastPos = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer);
+ action_type *ActionType = (action_type *)LastPos;
+
switch (*ActionType)
{
- case action_change_u16:
+ case action_type_change_u16:
+ {
+ void **Address = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ uint16 *Difference = (uint16 *)Memory_Advance(Memory, sizeof(uint16), P_UndoBuffer);
+ *(uint16 *)*Address += *Difference;
+ } break;
+ case action_type_change_i16:
{
- uint16 *Difference = (uint16 *)(ActionType + 1);
- TableAddress = (uint8 *)Difference + sizeof(uint16) + sizeof(action_change_type);
- *(uint16 *)Address += *Difference;
+ void **Address = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ int16 *Difference = (int16 *)Memory_Advance(Memory, sizeof(int16), P_UndoBuffer);
+ *(int16 *)*Address += *Difference;
} break;
- case action_change_i16:
+ case action_type_change_u32:
{
- int16 *Difference = (int16 *)(ActionType + 1);
- TableAddress = (uint8 *)Difference + sizeof(int16) + sizeof(action_change_type);
- *(int16 *)Address += *Difference;
+ void **Address = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ uint32 *Difference = (uint32 *)Memory_Advance(Memory, sizeof(uint32), P_UndoBuffer);
+ *(uint32 *)*Address += *Difference;
} break;
- case action_change_u32:
+ case action_type_change_i32:
{
- uint32 *Difference = (uint32 *)(ActionType + 1);
- TableAddress = (uint8 *)Difference + sizeof(uint32) + sizeof(action_change_type);
- *(uint32 *)Address += *Difference;
+ void **Address = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ int32 *Difference = (int32 *)Memory_Advance(Memory, sizeof(int32), P_UndoBuffer);
+ *(int32 *)*Address += *Difference;
} break;
- case action_change_i32:
+ case action_type_change_r32:
{
- int32 *Difference = (int32 *)(ActionType + 1);
- TableAddress = (uint8 *)Difference + sizeof(int32) + sizeof(action_change_type);
- *(int32 *)Address += *Difference;
+ void **Address = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ real32 *Difference = (real32 *)Memory_Advance(Memory, sizeof(real32), P_UndoBuffer);
+ *(real32 *)*Address += *Difference;
} break;
- case action_change_r32:
+ case action_type_change_u64:
{
- real32 *Difference = (real32 *)(ActionType + 1);
- TableAddress = (uint8 *)Difference + sizeof(real32) + sizeof(action_change_type);
- *(real32 *)Address += *Difference;
+ void **Address = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ uint64 *Difference = (uint64 *)Memory_Advance(Memory, sizeof(uint64), P_UndoBuffer);
+ *(uint64 *)*Address += *Difference;
} break;
- case action_change_u64:
+ case action_type_change_ptr:
{
- uint64 *Difference = (uint64 *)(ActionType + 1);
- TableAddress = (uint8 *)Difference + sizeof(uint64) + sizeof(action_change_type);
- *(uint64 *)Address += *Difference;
+ void **Address = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ ptrsize *Difference = (ptrsize *)Memory_Advance(Memory, sizeof(ptrsize), P_UndoBuffer);
+ *(ptrsize *)*Address += *Difference;
+ } break;
+ case action_type_change_string:
+ {
+ Assert(0);
} break;
- case action_change_ptr:
+ case action_type_shift_keyframe:
{
- ptrsize *Difference = (ptrsize *)(ActionType + 1);
- TableAddress = (uint8 *)Difference + sizeof(ptrsize) + sizeof(action_change_type);
- *(ptrsize *)Address += *Difference;
+ void **DataPropertyAddress = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer);
+ void *DataDirection = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer);
+ void *DataIndex = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer);
+ ShiftKeyframes((property_channel *)*DataPropertyAddress, *(int16 *)DataDirection, *(int16 *)DataIndex);
} break;
- case action_change_string:
+ default:
{
- TableAddress = 0x0;
Assert(0);
} break;
}
- Table->CurrentPosition = (TableAddress - (uint8 *)Table->Address);
+ void *EndPos = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer);
}
-void Action_Undo(memory *Memory) {
+void History_Undo(memory *Memory) {
if (Memory->Action.Index != 0) {
Memory->Action.Index--;
action_entry Entry = Memory->Action.Entry[Memory->Action.Index];
@@ -281,11 +358,11 @@ void Action_Undo(memory *Memory) {
} break;
}
for (int i = 0; i < Entry.NumberOfActions; i++)
- Action_Change_Undo(Memory);
+ History_Action_Undo(Memory);
}
}
-void Action_Redo(memory *Memory) {
+void History_Redo(memory *Memory) {
if (Memory->Action.Index != Memory->Action.NumberOfEntries) {
action_entry Entry = Memory->Action.Entry[Memory->Action.Index];
switch (Entry.Type)
@@ -298,7 +375,7 @@ void Action_Redo(memory *Memory) {
} break;
}
for (int i = 0; i < Entry.NumberOfActions; i++)
- Action_Change_Redo(Memory);
+ History_Action_Redo(Memory);
Memory->Action.Index++;
}
}