Files
ProjectEleri/Plugins/DirectiveUtilities/Source/DirectiveUtilitiesRuntime/Private/Libraries/DirectiveUtilArrayFunctionLibrary.cpp
2026-07-15 19:17:47 +02:00

566 lines
12 KiB
C++

// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#include "Libraries/DirectiveUtilArrayFunctionLibrary.h"
int32 UDirectiveUtilArrayFunctionLibrary::Array_NextIndex(const TArray<int32>& TargetArray, const int32 Index, const bool bLoop)
{
checkNoEntry();
return 0;
}
int32 UDirectiveUtilArrayFunctionLibrary::Array_PreviousIndex(
const TArray<int32>& TargetArray,
const int32 Index,
const bool bLoop)
{
checkNoEntry();
return 0;
}
int32 UDirectiveUtilArrayFunctionLibrary::GenericArray_NextIndex(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
const int32 Index,
const bool bLoop)
{
if (!TargetArray || !ArrayProperty)
{
return INDEX_NONE;
}
const FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const int32 NextIndex = Index + 1;
if(ArrayHelper.Num() == 0)
{
return INDEX_NONE;
}
if(NextIndex < 0)
{
return 0;
}
if (NextIndex <= ArrayHelper.Num() - 1)
{
return NextIndex;
}
if (bLoop)
{
return 0;
}
return ArrayHelper.Num() - 1;
}
void UDirectiveUtilArrayFunctionLibrary::Array_RemoveDuplicates(const TArray<int32>& TargetArray)
{
checkNoEntry();
}
void UDirectiveUtilArrayFunctionLibrary::GenericArray_RemoveDuplicates(
void* TargetArray,
const FArrayProperty* ArrayProperty)
{
if (!TargetArray || !ArrayProperty)
{
return;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const FProperty* InnerProp = ArrayProperty->Inner;
for (int32 OuterIndex = ArrayHelper.Num() - 1; OuterIndex > 0; --OuterIndex)
{
for (int32 InnerIndex = 0; InnerIndex < OuterIndex; ++InnerIndex)
{
if (InnerProp->Identical(ArrayHelper.GetElementPtr(OuterIndex), ArrayHelper.GetElementPtr(InnerIndex)))
{
ArrayHelper.RemoveValues(OuterIndex);
break;
}
}
}
}
int32 UDirectiveUtilArrayFunctionLibrary::GenericArray_PreviousIndex(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
const int32 Index,
const bool bLoop)
{
if (!TargetArray || !ArrayProperty)
{
return INDEX_NONE;
}
const FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const int32 PreviousIndex = Index - 1;
if(ArrayHelper.Num() == 0)
{
return INDEX_NONE;
}
if(PreviousIndex > ArrayHelper.Num() - 1)
{
return ArrayHelper.Num() - 1;
}
if (PreviousIndex >= 0)
{
return PreviousIndex;
}
if (bLoop)
{
return ArrayHelper.Num() - 1;
}
return 0;
}
bool UDirectiveUtilArrayFunctionLibrary::Array_GetValidFirstItemCopy(const TArray<int32>& TargetArray, int32& OutItem)
{
checkNoEntry();
return false;
}
bool UDirectiveUtilArrayFunctionLibrary::Array_GetValidLastItemCopy(const TArray<int32>& TargetArray, int32& OutItem)
{
checkNoEntry();
return false;
}
bool UDirectiveUtilArrayFunctionLibrary::Array_GetValidItemFromIndexCopy(const TArray<int32>& TargetArray, const int32 Index, int32& OutItem)
{
checkNoEntry();
return false;
}
bool UDirectiveUtilArrayFunctionLibrary::Array_GetRandomItem(const TArray<int32>& TargetArray, int32& OutItem, int32& OutIndex)
{
checkNoEntry();
return false;
}
void UDirectiveUtilArrayFunctionLibrary::Array_LastValue(const TArray<int32>& TargetArray, int32& OutItem)
{
checkNoEntry();
}
bool UDirectiveUtilArrayFunctionLibrary::Array_Pop(const TArray<int32>& TargetArray, int32& OutItem)
{
checkNoEntry();
return false;
}
bool UDirectiveUtilArrayFunctionLibrary::Array_PopFirst(const TArray<int32>& TargetArray, int32& OutItem)
{
checkNoEntry();
return false;
}
bool UDirectiveUtilArrayFunctionLibrary::Array_RemoveAtSwap(const TArray<int32>& TargetArray, const int32 Index)
{
checkNoEntry();
return false;
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_GetItemAtIndex(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
const int32 Index,
void* OutItemPtr)
{
if (!TargetArray || !ArrayProperty)
{
return false;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const FProperty* InnerProp = ArrayProperty->Inner;
if (!ArrayHelper.IsValidIndex(Index))
{
if (OutItemPtr)
{
InnerProp->ClearValue(OutItemPtr);
}
return false;
}
if (OutItemPtr)
{
InnerProp->CopyCompleteValueFromScriptVM(OutItemPtr, ArrayHelper.GetRawPtr(Index));
}
return true;
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_GetFirstItem(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
void* OutItemPtr)
{
return GenericArray_GetItemAtIndex(TargetArray, ArrayProperty, 0, OutItemPtr);
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_GetLastItem(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
void* OutItemPtr)
{
if (!TargetArray || !ArrayProperty)
{
return false;
}
const FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
return GenericArray_GetItemAtIndex(TargetArray, ArrayProperty, ArrayHelper.Num() - 1, OutItemPtr);
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_GetRandomItem(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
void* OutItemPtr,
int32* OutIndex)
{
if (OutIndex)
{
*OutIndex = INDEX_NONE;
}
if (!TargetArray || !ArrayProperty)
{
return false;
}
const FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const int32 Num = ArrayHelper.Num();
if (Num <= 0)
{
if (OutItemPtr)
{
ArrayProperty->Inner->ClearValue(OutItemPtr);
}
return false;
}
const int32 Index = FMath::RandRange(0, Num - 1);
if (OutIndex)
{
*OutIndex = Index;
}
return GenericArray_GetItemAtIndex(TargetArray, ArrayProperty, Index, OutItemPtr);
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_Pop(
void* TargetArray,
const FArrayProperty* ArrayProperty,
void* OutItemPtr)
{
if (!TargetArray || !ArrayProperty)
{
return false;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const FProperty* InnerProp = ArrayProperty->Inner;
const int32 LastIndex = ArrayHelper.Num() - 1;
if (LastIndex < 0)
{
if (OutItemPtr)
{
InnerProp->ClearValue(OutItemPtr);
}
return false;
}
if (OutItemPtr)
{
InnerProp->CopyCompleteValueFromScriptVM(OutItemPtr, ArrayHelper.GetRawPtr(LastIndex));
}
ArrayHelper.RemoveValues(LastIndex, 1);
return true;
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_PopFirst(
void* TargetArray,
const FArrayProperty* ArrayProperty,
void* OutItemPtr)
{
if (!TargetArray || !ArrayProperty)
{
return false;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const FProperty* InnerProp = ArrayProperty->Inner;
if (ArrayHelper.Num() <= 0)
{
if (OutItemPtr)
{
InnerProp->ClearValue(OutItemPtr);
}
return false;
}
if (OutItemPtr)
{
InnerProp->CopyCompleteValueFromScriptVM(OutItemPtr, ArrayHelper.GetRawPtr(0));
}
ArrayHelper.RemoveValues(0, 1);
return true;
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_RemoveAtSwap(
void* TargetArray,
const FArrayProperty* ArrayProperty,
const int32 Index)
{
if (!TargetArray || !ArrayProperty)
{
return false;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
if (!ArrayHelper.IsValidIndex(Index))
{
return false;
}
const int32 LastIndex = ArrayHelper.Num() - 1;
if (Index != LastIndex)
{
ArrayHelper.SwapValues(Index, LastIndex);
}
ArrayHelper.RemoveValues(LastIndex, 1);
return true;
}
void UDirectiveUtilArrayFunctionLibrary::Array_Slice(const TArray<int32>& TargetArray, const int32 StartIndex, const int32 Count, TArray<int32>& OutArray)
{
checkNoEntry();
}
void UDirectiveUtilArrayFunctionLibrary::Array_Rotate(const TArray<int32>& TargetArray, const int32 Shift)
{
checkNoEntry();
}
void UDirectiveUtilArrayFunctionLibrary::Array_GetDistinct(const TArray<int32>& TargetArray, TArray<int32>& OutArray)
{
checkNoEntry();
}
int32 UDirectiveUtilArrayFunctionLibrary::Array_CountOccurrences(const TArray<int32>& TargetArray, const int32& ItemToCount)
{
checkNoEntry();
return 0;
}
bool UDirectiveUtilArrayFunctionLibrary::Array_GetMostCommon(const TArray<int32>& TargetArray, int32& OutItem, int32& OutCount)
{
checkNoEntry();
return false;
}
void UDirectiveUtilArrayFunctionLibrary::GenericArray_Slice(
const void* TargetArray,
const FArrayProperty* TargetArrayProperty,
const int32 StartIndex,
const int32 Count,
void* OutArray,
const FArrayProperty* OutArrayProperty)
{
if (!TargetArray || !OutArray || !TargetArrayProperty || !OutArrayProperty)
{
return;
}
FScriptArrayHelper SourceHelper(TargetArrayProperty, TargetArray);
FScriptArrayHelper OutHelper(OutArrayProperty, OutArray);
OutHelper.EmptyValues();
const int32 Num = SourceHelper.Num();
if (Num == 0 || Count <= 0)
{
return;
}
const FProperty* InnerProp = TargetArrayProperty->Inner;
const int32 Start = FMath::Clamp(StartIndex, 0, Num);
const int32 NumToCopy = FMath::Min(Count, Num - Start);
for (int32 Offset = 0; Offset < NumToCopy; ++Offset)
{
const int32 OutIndex = OutHelper.AddValue();
InnerProp->CopySingleValueToScriptVM(OutHelper.GetRawPtr(OutIndex), SourceHelper.GetRawPtr(Start + Offset));
}
}
void UDirectiveUtilArrayFunctionLibrary::GenericArray_Rotate(
void* TargetArray,
const FArrayProperty* ArrayProperty,
const int32 Shift)
{
if (!TargetArray || !ArrayProperty)
{
return;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const int32 Num = ArrayHelper.Num();
if (Num <= 1)
{
return;
}
int32 Normalized = Shift % Num;
if (Normalized < 0)
{
Normalized += Num;
}
if (Normalized == 0)
{
return;
}
auto ReverseRange = [&ArrayHelper](int32 Low, int32 High)
{
while (Low < High)
{
ArrayHelper.SwapValues(Low, High);
++Low;
--High;
}
};
ReverseRange(0, Num - 1);
ReverseRange(0, Normalized - 1);
ReverseRange(Normalized, Num - 1);
}
void UDirectiveUtilArrayFunctionLibrary::GenericArray_GetDistinct(
const void* TargetArray,
const FArrayProperty* TargetArrayProperty,
void* OutArray,
const FArrayProperty* OutArrayProperty)
{
if (!TargetArray || !OutArray || !TargetArrayProperty || !OutArrayProperty)
{
return;
}
FScriptArrayHelper SourceHelper(TargetArrayProperty, TargetArray);
FScriptArrayHelper OutHelper(OutArrayProperty, OutArray);
OutHelper.EmptyValues();
const FProperty* InnerProp = TargetArrayProperty->Inner;
const int32 Num = SourceHelper.Num();
for (int32 SourceIndex = 0; SourceIndex < Num; ++SourceIndex)
{
const uint8* SourceElement = SourceHelper.GetRawPtr(SourceIndex);
bool bIsDuplicate = false;
for (int32 ExistingIndex = 0; ExistingIndex < OutHelper.Num(); ++ExistingIndex)
{
if (InnerProp->Identical(SourceElement, OutHelper.GetRawPtr(ExistingIndex)))
{
bIsDuplicate = true;
break;
}
}
if (!bIsDuplicate)
{
const int32 OutIndex = OutHelper.AddValue();
InnerProp->CopySingleValueToScriptVM(OutHelper.GetRawPtr(OutIndex), SourceElement);
}
}
}
int32 UDirectiveUtilArrayFunctionLibrary::GenericArray_CountOccurrences(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
const void* ItemToCount)
{
if (!TargetArray || !ArrayProperty || !ItemToCount)
{
return 0;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const FProperty* InnerProp = ArrayProperty->Inner;
int32 Count = 0;
for (int32 Index = 0; Index < ArrayHelper.Num(); ++Index)
{
if (InnerProp->Identical(ArrayHelper.GetRawPtr(Index), ItemToCount))
{
++Count;
}
}
return Count;
}
bool UDirectiveUtilArrayFunctionLibrary::GenericArray_GetMostCommon(
const void* TargetArray,
const FArrayProperty* ArrayProperty,
void* OutItemPtr,
int32* OutCount)
{
if (OutCount)
{
*OutCount = 0;
}
if (!TargetArray || !ArrayProperty)
{
return false;
}
FScriptArrayHelper ArrayHelper(ArrayProperty, TargetArray);
const FProperty* InnerProp = ArrayProperty->Inner;
const int32 Num = ArrayHelper.Num();
if (Num == 0)
{
if (OutItemPtr)
{
InnerProp->ClearValue(OutItemPtr);
}
return false;
}
int32 BestIndex = 0;
int32 BestCount = 0;
for (int32 Index = 0; Index < Num; ++Index)
{
int32 CurrentCount = 0;
for (int32 CompareIndex = 0; CompareIndex < Num; ++CompareIndex)
{
if (InnerProp->Identical(ArrayHelper.GetRawPtr(Index), ArrayHelper.GetRawPtr(CompareIndex)))
{
++CurrentCount;
}
}
if (CurrentCount > BestCount)
{
BestCount = CurrentCount;
BestIndex = Index;
}
}
if (OutItemPtr)
{
InnerProp->CopyCompleteValueFromScriptVM(OutItemPtr, ArrayHelper.GetRawPtr(BestIndex));
}
if (OutCount)
{
*OutCount = BestCount;
}
return true;
}