UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MovieSceneChannelData.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "Containers/Array.h"
8#include "CoreTypes.h"
9#include "Curves/KeyHandle.h"
10#include "Math/Range.h"
11#include "Math/RangeBound.h"
13#include "Misc/FrameNumber.h"
14#include "Misc/FrameTime.h"
17#include "UObject/Class.h"
20#include "Algo/RemoveIf.h"
21
22#include "MovieSceneChannelData.generated.h"
23
24struct FFrameRate;
26
27namespace UE::MovieScene
28{
29 template<typename ValueType>
30 void OnRemapChannelKeyTime(const FMovieSceneChannel* Channel, const IRetimingInterface& Retimer, FFrameNumber PreviousTime, FFrameNumber CurrentTime, ValueType& InOutValue)
31 {}
32}
33
35USTRUCT()
49
50template<>
60
61namespace UE
62{
63namespace MovieScene
64{
74
75
86
87
99
100} // namespace MovieScene
101} // namespace UE
102
103
109{
114 {
115 return *Times;
116 }
117
123 {
124 return *Times;
125 }
126
134
142
151
162
169
176 UE_DEPRECATED(5.6, "Please use RemapTimes")
177 MOVIESCENE_API void ChangeFrameResolution(FFrameRate SourceRate, FFrameRate DestinationRate);
178
187
195
201 MOVIESCENE_API void Offset(FFrameNumber DeltaTime);
202
204
213
214 UE_DEPRECATED(5.5, "Constructor that takes an optional FMovieSceneChannel is now deprecated. FMovieSceneChannel is now required.")
216
223
230
238
240
243
246
249
250};
251
257template<typename ValueType>
259{
261
262
271 UE_DEPRECATED(5.5, "Constructor that takes an optional FMovieSceneChannel is now deprecated. FMovieSceneChannel is now required.")
277
278
292
293
301
306 {
307 return *Values;
308 }
309
314 {
315 return *Values;
316 }
317
326 {
327 int32 KeyIndex = AddKeyInternal(InTime);
328 Values->Insert(InValue, KeyIndex);
329 if (OwningChannel && OwningChannel->OnKeyAddedEvent().IsBound())
330 {
332 Items.Add(FKeyAddOrDeleteEventItem(KeyIndex, InTime));
333 OwningChannel->OnKeyAddedEvent().Broadcast(OwningChannel, Items);
334
335 }
336 return KeyIndex;
337 }
338
347 int32 MoveKey(int32 KeyIndex, FFrameNumber NewTime, bool bRemoveDuplicateKeys = false)
348 {
349 return MoveKey(KeyIndex, NewTime, bRemoveDuplicateKeys, [](const FKeyHandle& KeyHandle){ return true; });
350 }
351
352 template<typename TCanRemove> requires std::is_invocable_r_v<bool, TCanRemove, const FKeyHandle&>
354 {
356 {
357 FKeyHandle KeyHandle = GetHandle(KeyIndex);
358
362 KeysToRemove.Remove(KeyHandle);
364
365 if (KeysToRemove.Num() > 0)
366 {
367 DeleteKeys(KeysToRemove);
368 }
369
370 KeyIndex = GetIndex(KeyHandle);
371 }
372
373 if (KeyIndex == INDEX_NONE)
374 {
375 return KeyIndex;
376 }
377
378 int32 NewIndex = MoveKeyInternal(KeyIndex, NewTime);
379 if (NewIndex != KeyIndex)
380 {
381 // We have to remove the key and re-add it in the right place
382 // This could probably be done better by just shuffling up/down the items that need to move, without ever changing the size of the array
383 ValueType OldValue = (*Values)[KeyIndex];
384 Values->RemoveAt(KeyIndex, EAllowShrinking::No);
385 Values->Insert(OldValue, NewIndex);
386 }
387
388 return NewIndex;
389 }
390
399 {
400 return MoveKey(KeyIndex, InNewTime);
401 }
402
403
404
411 {
412 using namespace UE::MovieScene;
413
414 const int32 Num = Times->Num();
415 if (Num == 0)
416 {
417 return;
418 }
419
420 bool bIsSorted = true;
421 {
422 int32 Index = 0;
423
424 // Remap the first time
425 {
426 FFrameNumber& NewTime = (*Times)[Index];
427 FFrameNumber OldTime = NewTime;
428
429 NewTime = Retimer.RemapTime(OldTime);
430 OnRemapChannelKeyTime(OwningChannel, Retimer, OldTime, NewTime, (*Values)[Index]);
431 }
432 ++Index;
433
434 // Remap others keeping track of whether we need resorting
435 for ( ; Index < Num; ++Index)
436 {
437 FFrameNumber& NewTime = (*Times)[Index];
438 FFrameNumber OldTime = NewTime;
439 FFrameNumber Previous = (*Times)[Index-1];
440
441 NewTime = Retimer.RemapTime(OldTime);
442 bIsSorted &= NewTime >= Previous;
443
444 OnRemapChannelKeyTime(OwningChannel, Retimer, OldTime, NewTime, (*Values)[Index]);
445 }
446 }
447
448 if (!bIsSorted)
449 {
450 // Have to re-sort all the keys...
452 for (int32 Index = 0; Index < Num; ++Index)
453 {
454 Indices.Add(Index);
455 }
456
457 Algo::Sort(Indices, [this](int32 A, int32 B){
458 return (*Times)[A] < (*Times)[B];
459 });
460
461 for (int32 Index = 0; Index < Num; ++Index)
462 {
463 KeyHandles->MoveHandle(Index, Indices[Index]);
464 }
465
466 // Move all the keys by repeatedly swapping until we get the correct index
467 for (int32 Index = 0; Index < Num; ++Index)
468 {
469 while (Indices[Index] != Index)
470 {
471 const int32 DestIndex = Indices[Index];
472 Swap((*Times)[Index], (*Times)[DestIndex]);
473 Swap((*Values)[Index], (*Values)[DestIndex]);
474 Swap(Indices[Index], Indices[DestIndex]);
475 }
476 }
477 }
478 }
479
487 {
488 ReplaceKeyHandles(TConstArrayView<int32>(&KeyIndex, 1), TConstArrayView<FKeyHandle>(&NewHandle, 1));
489 }
500
506 void RemoveKey(int32 KeyIndex)
507 {
508 check(Times->IsValidIndex(KeyIndex));
510 {
511 const FFrameNumber Time = (*Times)[KeyIndex];
513 Items.Add(FKeyAddOrDeleteEventItem(KeyIndex, Time));
514 OwningChannel->OnKeyDeletedEvent().Broadcast(OwningChannel, Items);
515 }
517 Values->RemoveAt(KeyIndex, EAllowShrinking::No);
518
519 if (KeyHandles)
520 {
521 KeyHandles->DeallocateHandle(KeyIndex);
522 }
523 }
524
533 {
535 if (ExistingKey != INDEX_NONE)
536 {
537 (*Values)[ExistingKey] = InValue;
538 }
539 else
540 {
541 ExistingKey = AddKey(InTime, InValue);
542 }
543
544 return GetHandle(ExistingKey);
545 }
546
555 {
556 check(InTimes.Num() == InValues.Num());
557 const int32 UpdateNum = InTimes.Num();
558 int32 CurrIdx = 0;
559 int32 UpdateIdx = 0;
560
561 while (true)
562 {
563 if (UpdateIdx == UpdateNum)
564 {
565 // No more keys to insert
566 break;
567 }
568
569 if (CurrIdx == Times->Num())
570 {
571 // Append the rest of the keys to the end
572 Times->Append(InTimes.RightChop(UpdateIdx));
573 Values->Append(InValues.RightChop(UpdateIdx));
574 break;
575 }
576 if ((*Times)[CurrIdx] == InTimes[UpdateIdx])
577 {
578 // Replace value at the associated time
579 (*Values)[CurrIdx] = InValues[UpdateIdx];
580 CurrIdx++;
581 UpdateIdx++;
582 continue;
583 }
584 if ((*Times)[CurrIdx] > InTimes[UpdateIdx])
585 {
586 // Insert new time value pair
588 Values->Insert(InValues[UpdateIdx], CurrIdx);
589 CurrIdx++;
590 UpdateIdx++;
591 continue;
592 }
593 if ((*Times)[CurrIdx] < InTimes[UpdateIdx])
594 {
595 // Not found insertion slot yet
596 CurrIdx++;
597 continue;
598 }
599 }
600 KeyHandles->Reset();
601 for (int32 Index = 0; Index < Times->Num(); ++Index)
602 {
604 }
605 }
606
614 {
615 check(InHandles.Num() == InKeyTimes.Num());
616
617 for (int32 Index = 0; Index < InHandles.Num(); ++Index)
618 {
619 const int32 KeyIndex = GetIndex(InHandles[Index]);
620 if (KeyIndex != INDEX_NONE)
621 {
622 MoveKey(KeyIndex, InKeyTimes[Index]);
623 }
624 }
625 }
626
634 {
635 for (int32 Index = 0; Index < InHandles.Num(); ++Index)
636 {
637 const int32 KeyIndex = GetIndex(InHandles[Index]);
638 if (KeyIndex == INDEX_NONE)
639 {
640 // we must add a handle even if the supplied handle does not relate to a key in this channel
642 }
643 else
644 {
645 // Do not cache value and time arrays since they can be reallocated during this loop
646 auto KeyCopy = (*Values)[KeyIndex];
647 int32 NewKeyIndex = AddKey((*Times)[KeyIndex], MoveTemp(KeyCopy));
649 }
650 }
651 }
652
659 {
660 for (int32 Index = 0; Index < InHandles.Num(); ++Index)
661 {
662 const int32 KeyIndex = GetIndex(InHandles[Index]);
663 if (KeyIndex != INDEX_NONE)
664 {
665 RemoveKey(KeyIndex);
666 }
667 }
668 }
669
670
678 {
682
684 for (int32 Index = 0; Index < OutKeyTimes.Num(); ++Index)
685 {
687 {
688 if (OutKeyTimes[Index] < InTime)
689 {
691 }
692 }
693 else
694 {
695 if (OutKeyTimes[Index] > InTime)
696 {
698 }
699 }
700 }
701
702 DeleteKeys(KeysToRemove);
703 }
704
708 void Reset()
709 {
711 {
713 for (int32 Index = 0; Index < Times->Num(); ++Index)
714 {
715 const FFrameNumber Time = (*Times)[Index];
717 }
718 OwningChannel->OnKeyDeletedEvent().Broadcast(OwningChannel, Items);
719 }
720 Times->Reset();
721 Values->Reset();
722 if (KeyHandles)
723 {
724 KeyHandles->Reset();
725 }
726 }
727
728private:
729
731 TArray<ValueType>* Values;
732
733};
734
735
739template<typename ValueType>
740struct TMovieSceneChannelData<const ValueType>
741{
743
744
753 : Times(InTimes), Values(InValues)
754 {
755 check(Times && Values);
756 }
757
762 {
763 return *Times;
764 }
765
770 {
771 return *Values;
772 }
773
782 {
783 int32 MinIndex = 0, MaxIndex = 0;
784 UE::MovieScene::FindRange(*Times, InTime, InTolerance, 1, MinIndex, MaxIndex);
785 return MinIndex;
786 }
787
801
808 {
809 return Times->Num() ? TRange<FFrameNumber>((*Times)[0], TRangeBound<FFrameNumber>::Inclusive((*Times)[Times->Num()-1])) : TRange<FFrameNumber>::Empty();
810 }
811
812private:
813
815 const TArray<FFrameNumber>* Times;
816
818 const TArray<ValueType>* Values;
819};
#define check(expr)
Definition AssertionMacros.h:314
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
@ Num
Definition MetalRHIPrivate.h:234
#define GENERATED_BODY(...)
Definition ObjectMacros.h:765
#define USTRUCT(...)
Definition ObjectMacros.h:746
EPropertyObjectReferenceType
Definition ObjectMacros.h:533
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Offset
Definition VulkanMemory.cpp:4033
Definition MovieScene.Build.cs:6
Definition ArrayView.h:139
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void RemoveAt(SizeType Index, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2083
void Reset(SizeType NewSize=0)
Definition Array.h:2246
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
UE_NODEBUG UE_FORCEINLINE_HINT bool IsValidIndex(SizeType Index) const
Definition Array.h:1122
void Append(const TArray< OtherElementType, OtherAllocatorType > &Source)
Definition Array.h:2412
SizeType Insert(std::initializer_list< ElementType > InitList, const SizeType InIndex)
Definition Array.h:1875
Definition RangeBound.h:36
Definition Range.h:50
static UE_FORCEINLINE_HINT TRange Empty()
Definition Range.h:671
UE_REWRITE void Sort(RangeType &&Range)
Definition Sort.h:16
int32 RemoveIf(RangeType &Range, Predicate Pred)
Definition RemoveIf.h:21
Definition ConstraintsManager.h:14
void EvaluateTime(TArrayView< const FFrameNumber > InTimes, FFrameTime InTime, int32 &OutIndex1, int32 &OutIndex2)
Definition MovieSceneChannelData.cpp:13
void OnRemapChannelKeyTime(const FMovieSceneChannel *Channel, const IRetimingInterface &Retimer, FFrameNumber PreviousTime, FFrameNumber CurrentTime, FMovieSceneDoubleValue &InOutValue)
Definition MovieSceneDoubleChannel.cpp:26
void FindRange(TArrayView< const FFrameNumber > InTimes, FFrameNumber PredicateTime, FFrameNumber InTolerance, int32 MaxNum, int32 &OutMin, int32 &OutMax)
Definition MovieSceneChannelData.cpp:44
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71
Definition FrameNumber.h:18
Definition FrameRate.h:21
Definition FrameTime.h:16
Definition MovieSceneChannel.h:35
Definition MovieSceneChannelTraits.h:20
Definition KeyHandle.h:138
ENGINE_API void Reset()
Definition KeyHandle.cpp:266
ENGINE_API void DeallocateHandle(int32 Index)
Definition KeyHandle.cpp:244
ENGINE_API void MoveHandle(int32 OldIndex, int32 NewIndex)
Definition KeyHandle.cpp:209
ENGINE_API FKeyHandle AllocateHandle(int32 Index)
Definition KeyHandle.cpp:229
Definition KeyHandle.h:15
static ENGINE_API FKeyHandle Invalid()
Definition KeyHandle.cpp:37
Definition MovieSceneChannelData.h:109
MOVIESCENE_API TRange< FFrameNumber > GetTotalRange() const
Definition MovieSceneChannelData.cpp:201
FMovieSceneChannel * OwningChannel
Definition MovieSceneChannelData.h:248
MOVIESCENE_API int32 AddKeyInternal(FFrameNumber InTime)
Definition MovieSceneChannelData.cpp:133
MOVIESCENE_API void GetKeyTimes(TArrayView< const FKeyHandle > InHandles, TArrayView< FFrameNumber > OutKeyTimes)
Definition MovieSceneChannelData.cpp:245
MOVIESCENE_API int32 FindKey(FFrameNumber InTime, FFrameNumber InTolerance=0)
Definition MovieSceneChannelData.cpp:116
MOVIESCENE_API void GetKeys(const TRange< FFrameNumber > &WithinRange, TArray< FFrameNumber > *OutKeyTimes, TArray< FKeyHandle > *OutKeyHandles)
Definition MovieSceneChannelData.cpp:214
TArrayView< FFrameNumber > GetTimes()
Definition MovieSceneChannelData.h:122
TArray< FFrameNumber > * Times
Definition MovieSceneChannelData.h:242
TArrayView< const FFrameNumber > GetTimes() const
Definition MovieSceneChannelData.h:113
MOVIESCENE_API int32 MoveKeyInternal(int32 KeyIndex, FFrameNumber InNewTime)
Definition MovieSceneChannelData.cpp:157
FKeyHandleLookupTable * KeyHandles
Definition MovieSceneChannelData.h:245
MOVIESCENE_API void ReplaceKeyHandlesInternal(TConstArrayView< int32 > KeyIndices, TConstArrayView< FKeyHandle > NewHandles)
Definition MovieSceneChannelData.cpp:145
MOVIESCENE_API int32 GetIndex(FKeyHandle Handle)
Definition MovieSceneChannelData.cpp:110
MOVIESCENE_API void ChangeFrameResolution(FFrameRate SourceRate, FFrameRate DestinationRate)
Definition MovieSceneChannelData.cpp:206
MOVIESCENE_API FKeyHandle GetHandle(int32 Index)
Definition MovieSceneChannelData.cpp:103
MOVIESCENE_API void FindKeys(FFrameNumber InTime, int32 MaxNum, int32 &OutMinIndex, int32 &OutMaxIndex, int32 InTolerance)
Definition MovieSceneChannelData.cpp:128
Definition MovieSceneChannel.h:112
FMovieSceneChannelDataKeyAddedEvent & OnKeyAddedEvent()
Definition MovieSceneChannel.h:286
FMovieSceneChannelDataKeyDeletedEvent & OnKeyDeletedEvent()
Definition MovieSceneChannel.h:291
Definition MovieSceneChannelData.h:37
FMovieSceneKeyHandleMap(const FMovieSceneKeyHandleMap &RHS)
Definition MovieSceneChannelData.h:42
FMovieSceneKeyHandleMap & operator=(const FMovieSceneKeyHandleMap &RHS)
Definition MovieSceneChannelData.h:43
FMovieSceneKeyHandleMap()=default
TCallTraitsParamTypeHelper< T, PassByValue >::ParamType ParamType
Definition UnrealTypeTraits.h:275
void FindKeys(FFrameNumber InTime, int32 MaxNum, int32 &OutMinIndex, int32 &OutMaxIndex, FFrameNumber InTolerance) const
Definition MovieSceneChannelData.h:797
int32 FindKey(FFrameNumber InTime, FFrameNumber InTolerance=0) const
Definition MovieSceneChannelData.h:781
TArrayView< const FFrameNumber > GetTimes() const
Definition MovieSceneChannelData.h:761
TCallTraits< ValueType >::ParamType ParamType
Definition MovieSceneChannelData.h:742
TArrayView< const ValueType > GetValues() const
Definition MovieSceneChannelData.h:769
TMovieSceneChannelData(const TArray< FFrameNumber > *InTimes, const TArray< ValueType > *InValues)
Definition MovieSceneChannelData.h:752
TRange< FFrameNumber > GetTotalRange() const
Definition MovieSceneChannelData.h:807
Definition MovieSceneChannelData.h:259
void ReplaceKeyHandle(int32 KeyIndex, FKeyHandle NewHandle)
Definition MovieSceneChannelData.h:486
void DuplicateKeys(TArrayView< const FKeyHandle > InHandles, TArrayView< FKeyHandle > OutNewHandles)
Definition MovieSceneChannelData.h:633
int32 SetKeyTime(int32 KeyIndex, FFrameNumber InNewTime)
Definition MovieSceneChannelData.h:398
void ReplaceKeyHandles(TConstArrayView< int32 > KeyIndices, TConstArrayView< FKeyHandle > NewHandles)
Definition MovieSceneChannelData.h:496
int32 MoveKey(int32 KeyIndex, FFrameNumber NewTime, bool bRemoveDuplicateKeys, TCanRemove &&CanRemove)
Definition MovieSceneChannelData.h:353
void RemapTimes(const UE::MovieScene::IRetimingInterface &Retimer)
Definition MovieSceneChannelData.h:410
int32 AddKey(FFrameNumber InTime, ParamType InValue)
Definition MovieSceneChannelData.h:325
FKeyHandle UpdateOrAddKey(FFrameNumber InTime, ParamType InValue)
Definition MovieSceneChannelData.h:532
TCallTraits< ValueType >::ParamType ParamType
Definition MovieSceneChannelData.h:260
void RemoveKey(int32 KeyIndex)
Definition MovieSceneChannelData.h:506
TMovieSceneChannelData(TArray< FFrameNumber > *InTimes, TArray< ValueType > *InValues, FMovieSceneChannel *InChannel, FKeyHandleLookupTable *InKeyHandles)
Definition MovieSceneChannelData.h:287
TArrayView< const ValueType > GetValues() const
Definition MovieSceneChannelData.h:305
TArrayView< ValueType > GetValues()
Definition MovieSceneChannelData.h:313
void Reset()
Definition MovieSceneChannelData.h:708
void SetKeyTimes(TArrayView< const FKeyHandle > InHandles, TArrayView< const FFrameNumber > InKeyTimes)
Definition MovieSceneChannelData.h:613
void DeleteKeys(TArrayView< const FKeyHandle > InHandles)
Definition MovieSceneChannelData.h:658
void UpdateOrAddKeys(const TArrayView< const FFrameNumber > InTimes, const TArrayView< ValueType > InValues)
Definition MovieSceneChannelData.h:554
void DeleteKeysFrom(FFrameNumber InTime, bool bDeleteKeysBefore)
Definition MovieSceneChannelData.h:677
int32 MoveKey(int32 KeyIndex, FFrameNumber NewTime, bool bRemoveDuplicateKeys=false)
Definition MovieSceneChannelData.h:347
Definition StructOpsTypeTraits.h:11
@ WithSerializer
Definition StructOpsTypeTraits.h:23
static constexpr EPropertyObjectReferenceType WithSerializerObjectReferences
Definition StructOpsTypeTraits.h:41
Definition StructOpsTypeTraits.h:46
Definition IMovieSceneRetimingInterface.h:18