// Copyright Epic Games, Inc. All Rights Reserved. #include "MuR/Parameters.h" #include "HAL/LowLevelMemTracker.h" #include "HAL/PlatformMath.h" #include "HAL/UnrealMemory.h" #include "Misc/AssertionMacros.h" #include "MuR/Model.h" #include "MuR/ModelPrivate.h" #include "MuR/ParametersPrivate.h" #include "MuR/Serialisation.h" #include "MuR/SerialisationPrivate.h" #include "MuR/System.h" namespace mu { MUTABLE_IMPLEMENT_ENUM_SERIALISABLE(EParameterType) MUTABLE_IMPLEMENT_ENUM_SERIALISABLE(EProjectorType) FParameters::FParameters() { m_pD = new Private(); } FParameters::~FParameters() { check( m_pD ); delete m_pD; m_pD = 0; } void FParameters::Serialise( const FParameters* p, FOutputArchive& arch ) { arch << *p->m_pD; } TSharedPtr FParameters::StaticUnserialise( FInputArchive& arch ) { LLM_SCOPE_BYNAME(TEXT("MutableRuntime")); TSharedPtr pResult = MakeShared(); arch >> *pResult->m_pD; return pResult; } FParameters::Private* FParameters::GetPrivate() const { return m_pD; } TSharedPtr FParameters::Clone() const { LLM_SCOPE_BYNAME(TEXT("MutableRuntime")); TSharedPtr pRes = MakeShared(); pRes->m_pD->Model = m_pD->Model; pRes->m_pD->Values = m_pD->Values; pRes->m_pD->MultiValues = m_pD->MultiValues; return pRes; } int32 FParameters::GetCount() const { return (int32)m_pD->Values.Num(); } const FString& FParameters::GetName( int32 Index ) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check( Index>=0 && Index<(int32)Program.Parameters.Num() ); return Program.Parameters[Index].Name; } const FGuid& FParameters::GetUid( int32 Index ) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check( Index>=0 && IndexFind( strName ); } EParameterType FParameters::GetType( int32 Index ) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check( Index>=0 && Index FParameters::NewRangeIndex( int32 ParamIndex ) const { LLM_SCOPE_BYNAME(TEXT("MutableRuntime")); const FProgram& Program = m_pD->Model->GetPrivate()->Program; check( ParamIndex>=0 && ParamIndex Range; if ( ParamIndex>=0 && ParamIndex0 ) { Range = MakeShared(); Range->Parameters = this->AsShared(); Range->Parameter = ParamIndex; Range->Values.SetNumZeroed(RangeCount); } } return Range; } int32 FParameters::GetValueCount( int32 ParamIndex ) const { if (ParamIndex<0 || ParamIndex >= int32(m_pD->MultiValues.Num()) ) { return 0; } return int32( m_pD->MultiValues[ParamIndex].Num() ); } TSharedPtr FParameters::GetValueIndex( int32 ParamIndex, int32 ValueIndex ) const { if (ParamIndex<0 || ParamIndex >= m_pD->MultiValues.Num() ) { return nullptr; } if (ValueIndex <0 || ValueIndex >= int32(m_pD->MultiValues[ParamIndex].Num()) ) { return nullptr; } TMap< TArray, FParameterValue >::TRangedForIterator it = m_pD->MultiValues[ParamIndex].begin(); for ( int32 i=0; i< ValueIndex; ++i ) { ++it; } TSharedPtr result = NewRangeIndex( ParamIndex ); result->Values = it->Key; return result; } void FParameters::ClearAllValues( int32 ParamIndex ) { if (ParamIndex<0 || ParamIndex >= int32(m_pD->MultiValues.Num()) ) { return; } m_pD->MultiValues[ParamIndex].Empty(); } bool FParameters::GetBoolValue( int32 Index, const FRangeIndex* Pos ) const { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)==EParameterType::Bool ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Bool ) { return false; } // Single value case if (!Pos) { // Return the single value return m_pD->Values[Index].Get(); } // Multivalue case check( Pos->Parameter==Index ); if ( IndexMultiValues.Num())) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find(Pos->Values); if (it) { return it->Get(); } } // Multivalue parameter, but no multivalue set. Return single value. return m_pD->Values[Index].Get(); } void FParameters::SetBoolValue( int32 Index, bool value, const FRangeIndex* Pos ) { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)== EParameterType::Bool ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Bool ) { return; } // Single value case if (!Pos) { // Clear multivalue, if set. if (IndexMultiValues.Num())) { m_pD->MultiValues[Index].Empty(); } m_pD->Values[Index].Set(value); } // Multivalue case else { check( Pos->Parameter==Index ); if ( Index>=int32(m_pD->MultiValues.Num())) { m_pD->MultiValues.SetNum(Index+1); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd(Pos->Values); it.Set(value); } } int32 FParameters::GetIntPossibleValueCount( int32 ParamIndex ) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check( ParamIndex>=0 && ParamIndex<(int32)Program.Parameters.Num() ); return (int32)Program.Parameters[ParamIndex].PossibleValues.Num(); } int32 FParameters::GetIntPossibleValue( int32 ParamIndex, int32 valueIndex ) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check( ParamIndex>=0 && ParamIndex<(int32)Program.Parameters.Num() ); check( valueIndex>=0 && valueIndex<(int32)Program.Parameters[ParamIndex].PossibleValues.Num() ); return (int32)Program.Parameters[ParamIndex].PossibleValues[valueIndex].Value; } int32 FParameters::GetIntValueIndex(int32 ParamIndex, const FString& ValueName) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check(ParamIndex >= 0 && ParamIndex < (int32)Program.Parameters.Num()); int32 result = -1; for (size_t v = 0; v < Program.Parameters[ParamIndex].PossibleValues.Num(); ++v) { if (Program.Parameters[ParamIndex].PossibleValues[v].Name == ValueName) { result = (int32)v; break; } } return result; } int32 FParameters::GetIntValueIndex(int32 ParamIndex, int32 Value) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check(ParamIndex >= 0 && ParamIndex < (int32)Program.Parameters.Num()); for (size_t v = 0; v < Program.Parameters[ParamIndex].PossibleValues.Num(); ++v) { if (Program.Parameters[ParamIndex].PossibleValues[v].Value == Value) { return (int32)v; } } return -1; } const FString& FParameters::GetIntPossibleValueName( int32 ParamIndex, int32 valueIndex ) const { const FProgram& Program = m_pD->Model->GetPrivate()->Program; check( ParamIndex>=0 && ParamIndex<(int32)Program.Parameters.Num() ); check( valueIndex>=0 && valueIndex<(int32)Program.Parameters[ParamIndex].PossibleValues.Num() ); return Program.Parameters[ParamIndex].PossibleValues[valueIndex].Name; } int32 FParameters::GetIntValue( int32 Index, const FRangeIndex* Pos ) const { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)== EParameterType::Int ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Int ) { return 0; } // Single value case if (!Pos) { // Return the single value return m_pD->Values[Index].Get(); } // Multivalue case check( Pos->Parameter==Index ); if ( IndexMultiValues.Num())) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find(Pos->Values); if (it) { return it->Get(); } } // Multivalue parameter, but no multivalue set. Return single value. return m_pD->Values[Index].Get(); } void FParameters::SetIntValue( int32 Index, int32 value, const FRangeIndex* Pos ) { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)== EParameterType::Int ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Int ) { return; } // Single value case if (!Pos) { // Clear multivalue, if set. if (IndexMultiValues.Num())) { m_pD->MultiValues[Index].Empty(); } m_pD->Values[Index].Set(value); } // Multivalue case else { check( Pos->Parameter==Index ); if ( Index>=int32(m_pD->MultiValues.Num())) { m_pD->MultiValues.SetNum(Index+1); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd(Pos->Values); it.Set(value); } } float FParameters::GetFloatValue( int32 Index, const FRangeIndex* Pos ) const { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)== EParameterType::Float ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Float ) { return 0.0f; } // Single value case if (!Pos) { // Return the single value return m_pD->Values[Index].Get(); } // Multivalue case check( Pos->Parameter==Index ); if ( IndexMultiValues.Num())) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find(Pos->Values); if (it) { return it->Get(); } } // Multivalue parameter, but no multivalue set. Return single value. return m_pD->Values[Index].Get(); } void FParameters::SetFloatValue( int32 Index, float value, const FRangeIndex* Pos ) { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)== EParameterType::Float ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Float ) { return; } // Single value case if (!Pos) { // Clear multivalue, if set. if (IndexMultiValues.Num())) { m_pD->MultiValues[Index].Empty(); } m_pD->Values[Index].Set(value); } // Multivalue case else { check( Pos->Parameter==Index ); if ( Index>=int32(m_pD->MultiValues.Num())) { m_pD->MultiValues.SetNum(Index+1); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd(Pos->Values); it.Set(value); } } void FParameters::GetColourValue( int32 Index, FVector4f& OutValue, const FRangeIndex* Pos ) const { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)== EParameterType::Color ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Color ) { return; } // Single value case if (!Pos) { OutValue = m_pD->Values[Index].Get(); return; } // Multivalue case check( Pos->Parameter==Index ); if ( IndexMultiValues.Num())) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find(Pos->Values); if (it) { OutValue = it->Get(); return; } } // Multivalue parameter, but no multivalue set. Return single value. OutValue = m_pD->Values[Index].Get(); return; } void FParameters::SetColourValue( int32 Index, FVector4f InValue, const FRangeIndex* Pos ) { check( Index>=0 && Index<(int32)m_pD->Values.Num() ); check( GetType(Index)== EParameterType::Color ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Color ) { return; } // Single value case if (!Pos) { // Clear multivalue, if set. if (IndexMultiValues.Num())) { m_pD->MultiValues[Index].Empty(); } m_pD->Values[Index].Set(InValue); } // Multivalue case else { check( Pos->Parameter==Index ); if ( Index>=int32(m_pD->MultiValues.Num())) { m_pD->MultiValues.SetNum(Index+1); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd(Pos->Values); it.Set(InValue); } } USkeletalMesh* FParameters::GetMeshValue(int32 Index, const FRangeIndex* Pos) const { check(Index >= 0 && Index < (int32)m_pD->Values.Num()); check(GetType(Index) == EParameterType::Mesh); // Early out in case of invalid parameters if (Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Mesh) { return {}; } // Single value case if (!Pos) { return m_pD->Values[Index].Get().Get(); } // Multivalue case check(Pos->Parameter == Index); if (Index < int32(m_pD->MultiValues.Num())) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find(Pos->Values); if (it) { return it->Get().Get(); } } // Multivalue parameter, but no multivalue set. Return single value. return m_pD->Values[Index].Get().Get(); } void FParameters::SetMeshValue(int32 Index, USkeletalMesh* Value, const FRangeIndex* Pos) { check(Index >= 0 && Index < (int32)m_pD->Values.Num()); check(GetType(Index) == EParameterType::Mesh); // Single value case if (!Pos) { m_pD->Values[Index].Set(TStrongObjectPtr(Value)); } // Multivalue case else { check(Pos->Parameter == Index); if (Index >= int32(m_pD->MultiValues.Num())) { m_pD->MultiValues.SetNum(Index + 1); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd(Pos->Values); it.Set(TStrongObjectPtr(Value)); } } UTexture* FParameters::GetImageValue( int32 Index, const FRangeIndex* Pos ) const { check( Index >= 0 && Index < (int32)m_pD->Values.Num() ); check( GetType( Index ) == EParameterType::Image ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType(Index) != EParameterType::Image ) { return {}; } // Single value case if (!Pos) { return m_pD->Values[Index].Get().Get(); } // Multivalue case check(Pos->Parameter == Index); if (Index < int32(m_pD->MultiValues.Num())) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find(Pos->Values); if (it) { return it->Get().Get(); } } // Multivalue parameter, but no multivalue set. Return single value. return m_pD->Values[Index].Get().Get(); } void FParameters::SetImageValue( int32 Index, UTexture* Value, const FRangeIndex* Pos ) { check( Index >= 0 && Index < (int32)m_pD->Values.Num() ); check( GetType( Index ) == EParameterType::Image ); // Single value case if (!Pos) { m_pD->Values[Index].Set(TStrongObjectPtr(Value)); } // Multivalue case else { check(Pos->Parameter == Index); if (Index >= int32(m_pD->MultiValues.Num())) { m_pD->MultiValues.SetNum(Index + 1); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd(Pos->Values); it.Set(TStrongObjectPtr(Value)); } } void FParameters::GetStringValue( int32 Index, FString& OutValue, const FRangeIndex* Pos ) const { check( Index >= 0 && Index < (int32)m_pD->Values.Num() ); check( GetType( Index ) == EParameterType::String ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType( Index ) != EParameterType::String ) { OutValue = TEXT(""); return; } // Single value case if ( !Pos ) { // Return the single value OutValue = m_pD->Values[Index].Get(); return; } // Multivalue case check( Pos->Parameter == Index ); if ( Index < int32( m_pD->MultiValues.Num() ) ) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find( Pos->Values ); if ( it ) { OutValue = it->Get(); return; } } // Multivalue parameter, but no multivalue set. Return single value. OutValue = m_pD->Values[Index].Get(); return; } void FParameters::SetStringValue( int32 Index, const FString& Value, const FRangeIndex* Pos ) { LLM_SCOPE_BYNAME(TEXT("MutableRuntime")); check( Index >= 0 && Index < (int32)m_pD->Values.Num() ); check( GetType( Index ) == EParameterType::Float ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType( Index ) != EParameterType::Float ) { return; } // Single value case if ( !Pos ) { // Clear multivalue, if set. if ( Index < int32( m_pD->MultiValues.Num() ) ) { m_pD->MultiValues[Index].Empty(); } m_pD->Values[Index].Set(Value); } // Multivalue case else { check( Pos->Parameter == Index ); if ( Index >= int32( m_pD->MultiValues.Num() ) ) { m_pD->MultiValues.SetNum( Index + 1 ); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd( Pos->Values ); it.Set(Value); } } void FParameters::GetMatrixValue(int32 Index, FMatrix44f& OutValue, const FRangeIndex* Pos) const { check( Index >= 0 && Index < (int32)m_pD->Values.Num() ); check( GetType( Index ) == EParameterType::Matrix ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType( Index ) != EParameterType::Matrix ) { OutValue = FMatrix44f::Identity; return; } // Single value case if ( !Pos ) { // Return the single value OutValue = m_pD->Values[Index].Get(); return; } // Multivalue case check( Pos->Parameter == Index ); if ( Index < int32( m_pD->MultiValues.Num() ) ) { const TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; const FParameterValue* it = m.Find( Pos->Values ); if ( it ) { OutValue = it->Get(); return; } } // Multivalue parameter, but no multivalue set. Return single value. OutValue = m_pD->Values[Index].Get(); } void FParameters::SetMatrixValue(int32 Index, const FMatrix44f& Value, const FRangeIndex* Pos) { LLM_SCOPE_BYNAME(TEXT("MutableRuntime")); check( Index >= 0 && Index < (int32)m_pD->Values.Num() ); check( GetType( Index ) == EParameterType::Matrix ); // Early out in case of invalid parameters if ( Index < 0 || Index >= (int32)m_pD->Values.Num() || GetType( Index ) != EParameterType::Matrix ) { return; } // Single value case if ( !Pos ) { // Clear multivalue, if set. if ( Index < int32( m_pD->MultiValues.Num() ) ) { m_pD->MultiValues[Index].Empty(); } m_pD->Values[Index].Set(Value); } // Multivalue case else { check( Pos->Parameter == Index ); if ( Index >= int32( m_pD->MultiValues.Num() ) ) { m_pD->MultiValues.SetNum( Index + 1 ); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[Index]; FParameterValue& it = m.FindOrAdd( Pos->Values ); it.Set(Value); } } FProjector FParameters::Private::GetProjectorValue( int32 Index, const FRangeIndex* Pos ) const { const FProgram& Program = Model->GetPrivate()->Program; // Early out in case of invalid parameters if ( Index < 0 || Index >= Values.Num() || Index >= Program.Parameters.Num() || Program.Parameters[Index].Type != EParameterType::Projector ) { check(false); return FProjector(); } // Single value case if (!Pos) { // Return the single value return Values[Index].Get(); } const FProjector* Result = nullptr; // Multivalue case check( Pos->Parameter==Index ); if ( IndexValues); if (it) { return it->Get(); } } // Multivalue parameter, but no multivalue set. Return single value. return Values[Index].Get(); } void FParameters::GetProjectorValue( int32 ParameterIndex, EProjectorType* OutType, FVector3f* OutPos, FVector3f* OutDir, FVector3f* OutUp, FVector3f* OutScale, float* OutProjectionAngle, const FRangeIndex* Pos ) const { check(ParameterIndex >=0 && ParameterIndex Values.Num() ); check( GetType(ParameterIndex)== EParameterType::Projector ); // Early out in case of invalid parameters if (ParameterIndex < 0 || ParameterIndex >= m_pD->Values.Num() || GetType(ParameterIndex) != EParameterType::Projector ) { return; } FProjector result = m_pD->GetProjectorValue(ParameterIndex, Pos ); // Copy results if (OutType) *OutType = result.type; if (OutPos) *OutPos = result.position; if (OutDir) *OutDir = result.direction; if (OutUp) *OutUp = result.up; if (OutScale) *OutScale = result.scale; if (OutProjectionAngle) *OutProjectionAngle = result.projectionAngle; } void FParameters::SetProjectorValue( int32 ParameterIndex, const FVector3f& Pos, const FVector3f& dir, const FVector3f& up, const FVector3f& scale, float projectionAngle, const FRangeIndex* RangePosition) { check(ParameterIndex >=0 && ParameterIndex Values.Num() ); check( GetType(ParameterIndex)== EParameterType::Projector ); // Early out in case of invalid parameters if (ParameterIndex < 0 || ParameterIndex >= m_pD->Values.Num() || GetType(ParameterIndex) != EParameterType::Projector ) { return; } // FParameters cannot change the projector type anymore FProjector Value; Value.type = EProjectorType::Count; if (m_pD->Model) { const FProgram& Program = m_pD->Model->GetPrivate()->Program; const FProjector& Projector = Program.Parameters[ParameterIndex].DefaultValue.Get(); Value.type = Projector.type; } Value.position = Pos; Value.direction = dir; Value.up = up; Value.scale = scale; Value.projectionAngle = projectionAngle; // Single value case if (!RangePosition) { // Clear multivalue, if set. if (ParameterIndexMultiValues.Num()) { m_pD->MultiValues[ParameterIndex].Empty(); } m_pD->Values[ParameterIndex].Set(Value); } // Multivalue case else { check(RangePosition->Parameter== ParameterIndex); if (ParameterIndex >=m_pD->MultiValues.Num()) { m_pD->MultiValues.SetNum(ParameterIndex+1); } TMap< TArray, FParameterValue >& m = m_pD->MultiValues[ParameterIndex]; FParameterValue& it = m.FindOrAdd(RangePosition->Values); it.Set(Value); } } bool FParameters::HasSameValue( int32 thisParamIndex, const TSharedPtr& other, int32 otherParamIndex ) const { if ( GetType(thisParamIndex) != other->GetType(otherParamIndex) ) { return false; } if ( !(m_pD->Values[thisParamIndex]==other->m_pD->Values[otherParamIndex] ) ) { return false; } size_t thisNumMultiValues = 0; bool thisHasMultiValues = int32(m_pD->MultiValues.Num()) > thisParamIndex; if (thisHasMultiValues) { thisNumMultiValues = m_pD->MultiValues[thisParamIndex].Num(); } size_t otherNumMultiValues = 0; bool otherHasMultiValues = int32(other->m_pD->MultiValues.Num()) > otherParamIndex; if (otherHasMultiValues) { otherNumMultiValues = other->m_pD->MultiValues[otherParamIndex].Num(); } if ( thisNumMultiValues != otherNumMultiValues ) { return false; } if ( thisHasMultiValues && otherHasMultiValues && !(m_pD->MultiValues[thisParamIndex]==other->m_pD->MultiValues[otherParamIndex] )) { return false; } return true; } int32 FParameters::Private::Find( const FString& Name ) const { const FProgram& Program = Model->GetPrivate()->Program; int32 result = -1; for( int32 i=0; result<0 && i<(int32)Program.Parameters.Num(); ++i ) { const FParameterDesc& p = Program.Parameters[i]; if (p.Name == Name) { result = i; } } return result; } //--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- int32 FRangeIndex::GetRangeCount() const { return int32( Values.Num() ); } const FString& FRangeIndex::GetRangeName( int32 Index ) const { check( Index >= 0 && Index < GetRangeCount() ); check( Index < int32(Parameters->GetPrivate()->Values.Num()) ); TSharedPtr Model = Parameters->GetPrivate()->Model; check(Model); check( Index < int32(Model->GetPrivate()->Program.Ranges.Num()) ); return Model->GetPrivate()->Program.Ranges[Index].Name; } const FString& FRangeIndex::GetRangeUid( int32 Index ) const { check( Index >= 0 && Index < GetRangeCount() ); check( Index < int32(Parameters->GetPrivate()->Values.Num()) ); TSharedPtr Model = Parameters->GetPrivate()->Model; check(Model); check( Index < int32(Model->GetPrivate()->Program.Ranges.Num()) ); return Model->GetPrivate()->Program.Ranges[Index].UID; } void FRangeIndex::SetPosition( int32 Index, int32 Position ) { check( Index >= 0 && Index < GetRangeCount() ); if ( Index >= 0 && Index < GetRangeCount() ) { Values[Index] = Position; } } int32 FRangeIndex::GetPosition( int32 Index ) const { check( Index >= 0 && Index < GetRangeCount() ); if ( Index >= 0 && Index < GetRangeCount() ) { return Values[Index]; } return 0; } }