From d0410bddcd7ea43c51b6bf2442a99e58710e70eb Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Mon, 27 Feb 2023 19:42:48 -0500 Subject: four duplicate layer types! --- src/createcalls.cpp | 86 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 32 deletions(-) (limited to 'src/createcalls.cpp') diff --git a/src/createcalls.cpp b/src/createcalls.cpp index d7fb4b7..ffb4c0f 100644 --- a/src/createcalls.cpp +++ b/src/createcalls.cpp @@ -788,32 +788,10 @@ Property_IsGraphSelected(memory *Memory, uint16 *Block_Bezier_Index, uint16 *Arr return 0; } -// TODO(fox): It seems like duping many layers at once causes this to take up -// exponentially more data on the undo tree than it should. Rewrite the loop to -// change the offsets before duping, taking into account all dupes, like what -// the sorting code does. -// TODO(fox): Add different modes (all dupes on top, each dupe above its layer, two for bottom) static void Sort_OffsetDupes(memory *Memory, sorted_layer_array *SortedLayerStart, block_layer *StartLayer, int i, int FauxIncrement, int LayerCount, int Mode) { - block_layer *PrevLayer = StartLayer; - for (int a = i+1; a < LayerCount; a++) { - sorted_layer_array *NextSortEntry = &SortedLayerStart[a]; - uint32 NextIndex_Physical = NextSortEntry->Block_Layer_Index; - block_layer *NextLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, NextIndex_Physical); - if (NextLayer->Vertical_Offset == PrevLayer->Vertical_Offset) { - if (Mode == 0 && !NextSortEntry->IsFake) { - History_Action_Swap(Memory, F_Layers, sizeof(NextLayer->Vertical_Offset), &NextLayer->Vertical_Offset); - NextLayer->Vertical_Offset -= 1; - } else { - NextSortEntry->SortedOffset -= 1; - } - } else { - break; - } - PrevLayer = NextLayer; - } } // NOTE(fox): PrecompLayer is assumed to be untouched from the layer it was duplicated from! @@ -867,21 +845,27 @@ Layer_Precomp_CopyContents(project_data *File, project_state *State, memory *Mem static void Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory, - sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 FakeOnly, bool32 NewPrecomp) + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 NewPrecomp) { for (int c = 0; c < File->Comp_Count; c++) { sorted_comp_array SortedCompStart = SortedCompArray[c]; sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, c); int LayerCount = SortedCompStart.LayerCount + SortedCompStart.FakeLayerCount; - for (int i = 0; i < LayerCount; i++) + int FirstDupe = -1; + int DupeCount = 0; + int Direction = (State->DuplicateMode & sortflag_up) ? 1 : -1; + if (State->DuplicateMode & sortflag_furthest && !(State->DuplicateMode & sortflag_up)) + Direction *= -1; + int i = (Direction > 0) ? 0 : LayerCount - 1; + for (;;) { - sorted_layer_array SortEntry = SortedLayerStart[i]; - uint32 Index_Physical = SortEntry.Block_Layer_Index; + sorted_layer_array *SortEntry = &SortedLayerStart[i]; + uint32 Index_Physical = SortEntry->Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if ((FakeOnly && SortEntry.IsFake) || (!FakeOnly && (Layer->IsSelected & 0x01))) + if (SortEntry->IsFake) { - if (!FakeOnly) - Layer->IsSelected = 0x00; + if (FirstDupe == -1) + FirstDupe = i; block_layer *NewLayer = (block_layer *)Memory_Block_AllocateAddress(Memory, F_Layers); History_Action_Block_Swap(Memory, F_Layers, NewLayer); @@ -894,11 +878,12 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory // TODO(fox): Effect duplication Assert(Layer->Block_Effect_Count == 0); + int NewIdx = Memory_Block_LazyIndexAtAddress(Memory, F_Layers, NewLayer); Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, NewLayer)); - NewLayer->Vertical_Offset--; + // NOTE(fox): Sort entry being modified outside initial sort + // call to make undo tree more efficient! + SortEntry->Block_Layer_Index = NewIdx; - Sort_OffsetDupes(Memory, SortedLayerStart, NewLayer, i, 0, LayerCount, 0); - Assert(!NewLayer->x.Keyframe_Count); Assert(!NewLayer->y.Keyframe_Count); NewLayer->x.CurrentValue += Offset.x; @@ -916,6 +901,43 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory } else { Layer->IsSelected = 0x00; } + if ((Direction > 0) ? !(i < LayerCount) : (i <= 0)) + break; + i += Direction; + } + if (FirstDupe > -1) { + int FauxIncrement = 0; + int FurthestMark = -1; + { + sorted_layer_array SortEntry = SortedLayerStart[FirstDupe]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + FurthestMark = Layer->Vertical_Offset; + } + if (State->DuplicateMode & sortflag_furthest && !(State->DuplicateMode & sortflag_up)) + { + FauxIncrement = -SortedCompStart.FakeLayerCount; + } + int i = (Direction > 0) ? 0 : LayerCount - 1; + for (;;) + { + sorted_layer_array SortEntry = SortedLayerStart[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + History_Action_Swap(Memory, F_Layers, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); + if (Layer->IsSelected) { + if (State->DuplicateMode & sortflag_furthest) + Layer->Vertical_Offset = FurthestMark; + FauxIncrement += Direction; + if (State->DuplicateMode & sortflag_furthest && !(State->DuplicateMode & sortflag_up)) + Layer->Vertical_Offset += 1; + } + Layer->Vertical_Offset -= FauxIncrement; + int a = 0; + if ((Direction > 0) ? !(i < LayerCount) : (i <= 0)) + break; + i += Direction; + } } } } -- cgit v1.2.3