2019-12-26 15:33:43 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2018-11-14 19:05:13 -05:00
# include "SequencerKeyStructGenerator.h"
# include "Channels/MovieSceneChannelData.h"
2019-12-13 11:07:03 -05:00
# include "UObject/CoreObjectVersion.h"
2018-11-14 19:05:13 -05:00
UMovieSceneKeyStructType : : UMovieSceneKeyStructType ( const FObjectInitializer & ObjInit )
: Super ( ObjInit )
{
SourceValuesProperty = nullptr ;
SourceTimesProperty = nullptr ;
DestValueProperty = nullptr ;
DestTimeProperty = nullptr ;
}
FSequencerKeyStructGenerator & FSequencerKeyStructGenerator : : Get ( )
{
static FSequencerKeyStructGenerator Instance ;
return Instance ;
}
UMovieSceneKeyStructType * FSequencerKeyStructGenerator : : AllocateNewKeyStruct ( )
{
UMovieSceneKeyStructType * NewStruct = NewObject < UMovieSceneKeyStructType > ( GetTransientPackage ( ) , NAME_None , RF_Public | RF_Standalone ) ;
NewStruct - > SetSuperStruct ( FGeneratedMovieSceneKeyStruct : : StaticStruct ( ) ) ;
return NewStruct ;
}
UMovieSceneKeyStructType * FSequencerKeyStructGenerator : : AllocateNewKeyStruct ( UScriptStruct * ChannelType )
{
static const FName TimesMetaDataTag ( " KeyTimes " ) ;
static const FName ValuesMetaDataTag ( " KeyValues " ) ;
2019-12-13 11:07:03 -05:00
FArrayProperty * SourceTimes = FindArrayPropertyWithTag ( ChannelType , TimesMetaDataTag ) ;
FArrayProperty * SourceValues = FindArrayPropertyWithTag ( ChannelType , ValuesMetaDataTag ) ;
2018-11-14 19:05:13 -05:00
if ( ! ensureMsgf ( SourceTimes , TEXT ( " No times property could be found for channel type %s. Please add KeyTimes meta data to the array containing the channel's key time. " ) , * ChannelType - > GetName ( ) ) )
{
return nullptr ;
}
else if ( ! ensureMsgf ( SourceValues , TEXT ( " No value property could be found for channel type %s. Please add KeyValues meta data to the array containing the channel's key values. " ) , * ChannelType - > GetName ( ) ) )
{
return nullptr ;
}
UMovieSceneKeyStructType * NewStruct = AllocateNewKeyStruct ( ) ;
NewStruct - > SourceTimesProperty = SourceTimes ;
NewStruct - > SourceValuesProperty = SourceValues ;
return NewStruct ;
}
UMovieSceneKeyStructType * FSequencerKeyStructGenerator : : DefaultInstanceGeneratedStruct ( UScriptStruct * ChannelType )
{
UMovieSceneKeyStructType * Existing = FindGeneratedStruct ( ChannelType - > GetFName ( ) ) ;
if ( Existing )
{
return Existing ;
}
else
{
UMovieSceneKeyStructType * NewStruct = FSequencerKeyStructGenerator : : AllocateNewKeyStruct ( ChannelType ) ;
if ( ! NewStruct )
{
return nullptr ;
}
2019-12-13 11:07:03 -05:00
FProperty * NewValueProperty = CastField < FProperty > ( FField : : Duplicate ( NewStruct - > SourceValuesProperty - > Inner , NewStruct , " Value " ) ) ;
2018-11-14 19:05:13 -05:00
NewValueProperty - > SetPropertyFlags ( CPF_Edit ) ;
NewValueProperty - > SetMetaData ( " Category " , TEXT ( " Key " ) ) ;
NewValueProperty - > SetMetaData ( " ShowOnlyInnerProperties " , TEXT ( " true " ) ) ;
NewValueProperty - > ArrayDim = 1 ;
NewStruct - > AddCppProperty ( NewValueProperty ) ;
NewStruct - > DestValueProperty = NewValueProperty ;
FSequencerKeyStructGenerator : : FinalizeNewKeyStruct ( NewStruct ) ;
AddGeneratedStruct ( ChannelType - > GetFName ( ) , NewStruct ) ;
return NewStruct ;
}
}
void FSequencerKeyStructGenerator : : FinalizeNewKeyStruct ( UMovieSceneKeyStructType * InStruct )
{
check ( InStruct ) ;
// Add the time property to the head of the property linked list (so it shows first)
2019-12-13 11:07:03 -05:00
FStructProperty * NewTimeProperty = new FStructProperty ( InStruct , " Time " , RF_NoFlags ) ;
2018-11-14 19:05:13 -05:00
NewTimeProperty - > SetPropertyFlags ( CPF_Edit ) ;
NewTimeProperty - > SetMetaData ( " Category " , TEXT ( " Key " ) ) ;
NewTimeProperty - > ArrayDim = 1 ;
NewTimeProperty - > Struct = TBaseStructure < FFrameNumber > : : Get ( ) ;
InStruct - > AddCppProperty ( NewTimeProperty ) ;
InStruct - > DestTimeProperty = NewTimeProperty ;
// Finalize the struct
InStruct - > Bind ( ) ;
InStruct - > StaticLink ( true ) ;
UMovieSceneKeyStructType : : DeferCppStructOps ( InStruct - > GetFName ( ) , new UScriptStruct : : TCppStructOps < FGeneratedMovieSceneKeyStruct > ) ;
check ( InStruct - > IsComplete ( ) ) ;
}
void FSequencerKeyStructGenerator : : AddReferencedObjects ( FReferenceCollector & Collector )
{
Collector . AddReferencedObjects ( InstanceNameToGeneratedStruct ) ;
}
void FSequencerKeyStructGenerator : : AddGeneratedStruct ( FName InstancedStructName , UMovieSceneKeyStructType * Struct )
{
check ( ! InstanceNameToGeneratedStruct . Contains ( InstancedStructName ) ) ;
InstanceNameToGeneratedStruct . Add ( InstancedStructName , Struct ) ;
}
UMovieSceneKeyStructType * FSequencerKeyStructGenerator : : FindGeneratedStruct ( FName InstancedStructName )
{
return InstanceNameToGeneratedStruct . FindRef ( InstancedStructName ) ;
}
2019-12-13 11:07:03 -05:00
FArrayProperty * FSequencerKeyStructGenerator : : FindArrayPropertyWithTag ( UScriptStruct * ChannelStruct , FName MetaDataTag )
2018-11-14 19:05:13 -05:00
{
2019-12-13 11:07:03 -05:00
for ( FArrayProperty * ArrayProperty : TFieldRange < FArrayProperty > ( ChannelStruct ) )
2018-11-14 19:05:13 -05:00
{
if ( ArrayProperty - > HasMetaData ( MetaDataTag ) )
{
return ArrayProperty ;
}
}
return nullptr ;
}
TSharedPtr < FStructOnScope > FSequencerKeyStructGenerator : : CreateInitialStructInstance ( const void * SourceChannel , UMovieSceneKeyStructType * GeneratedStructType , int32 InitialKeyIndex )
{
check ( InitialKeyIndex ! = INDEX_NONE ) ;
TSharedPtr < FStructOnScope > Struct = MakeShared < FStructOnScope > ( GeneratedStructType ) ;
FGeneratedMovieSceneKeyStruct * StructPtr = reinterpret_cast < FGeneratedMovieSceneKeyStruct * > ( Struct - > GetStructMemory ( ) ) ;
// Copy the initial time into the struct
{
const uint8 * SrcTimeData = GeneratedStructType - > SourceTimesProperty - > ContainerPtrToValuePtr < uint8 > ( SourceChannel ) ;
uint8 * DestTimeData = GeneratedStructType - > DestTimeProperty - > ContainerPtrToValuePtr < uint8 > ( StructPtr ) ;
2019-12-13 11:07:03 -05:00
FScriptArrayHelper SourceTimesArray ( GeneratedStructType - > SourceTimesProperty . Get ( ) , SrcTimeData ) ;
2018-11-14 19:05:13 -05:00
GeneratedStructType - > SourceTimesProperty - > Inner - > CopyCompleteValue ( DestTimeData , SourceTimesArray . GetRawPtr ( InitialKeyIndex ) ) ;
}
// Copy the initial value into the struct
{
const uint8 * SrcValueData = GeneratedStructType - > SourceValuesProperty - > ContainerPtrToValuePtr < uint8 > ( SourceChannel ) ;
uint8 * DestValueData = GeneratedStructType - > DestValueProperty - > ContainerPtrToValuePtr < uint8 > ( StructPtr ) ;
2019-12-13 11:07:03 -05:00
FScriptArrayHelper SourceValuesArray ( GeneratedStructType - > SourceValuesProperty . Get ( ) , SrcValueData ) ;
2018-11-14 19:05:13 -05:00
GeneratedStructType - > SourceValuesProperty - > Inner - > CopyCompleteValue ( DestValueData , SourceValuesArray . GetRawPtr ( InitialKeyIndex ) ) ;
}
return Struct ;
}