// Copyright UnexGames 2025. All Rights Reserved. #pragma once #include "HAL/ThreadSafeBool.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "Delegates/IDelegateInstance.h" #include "ThreadUtility.generated.h" class UThreadBase; UENUM(BlueprintType) enum class EScaleType : uint8 { Uniform, Free, LockXY, LockXZ, LockYZ }; UCLASS() class MULTITHREADLIBRARY_API UThreadUtility : public UBlueprintFunctionLibrary { GENERATED_BODY() UThreadUtility(); ~UThreadUtility(); public: /** * Get World. */ UFUNCTION(BlueprintPure, Category = "MultiThreadLibrary") static UObject* GetContextWorld(UObject* WorldContextObject); /** * Cancel the Task. */ UFUNCTION(BlueprintCallable, meta = (DisplayName = "Cancel Task"), Category = "MultiThreadLibrary") static void CancelTask(UThreadBase* Task); /** * Cancel the Task. */ UFUNCTION(BlueprintCallable, meta = (DisplayName = "Wait To Finish"), Category = "MultiThreadLibrary") static void WaitToFinish(UThreadBase* Task); /** * Check whether the task is in progress. */ UFUNCTION(BlueprintPure, meta = (DisplayName = "IsRunning", CompactNodeTitle = "IsRunning"), Category = "MultiThreadLibrary") static bool IsRunning(UThreadBase* Task); /** * Check whether the task is canceled. */ UFUNCTION(BlueprintPure, meta = (DisplayName = "IsCanceled", CompactNodeTitle = "IsCanceled"), Category = "MultiThreadLibrary") static bool IsCanceled(UThreadBase* Task); UFUNCTION(BlueprintPure, Category = "MultiThreadLibrary") static int32 MixThreeIntegers(int32 Integer1, int32 Integer2, int32 Integer3); UFUNCTION(BlueprintPure, Category = "MultiThreadLibrary") static void GetRandomScale(const FVector& Min, const FVector& Max, EScaleType Type, const FRandomStream& RandomStream, FVector& Scale); /** * Check if can AudioThread be used on this device. */ UFUNCTION(BlueprintPure, meta = (DisplayName = "Can Use Audio Thread"), Category = "MultiThreadLibrary") static bool CanUseAudioThread(); /** * Whether LocalPrint can be called from any thread without overlapping. */ UFUNCTION(BlueprintPure, meta = (DisplayName = "Is Print ThreadSafe"), Category = "MultiThreadLibrary") static bool IsPrintThreadSafe(); /** * Checks if platform wants to use a rendering thread on current device. */ UFUNCTION(BlueprintPure, meta = (DisplayName = "Is Use Render Thread"), Category = "MultiThreadLibrary") static bool IsUseRenderThread(); /** * Remove an object from the Pool Root Set. */ UFUNCTION(BlueprintCallable, meta = (DisplayName = "Remove Pool From Root"), Category = "MultiThreadLibrary") static void RemoveFromRoot(UObject* Object); /** * Add an object to the Pool Root Set. */ UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Pool To Root"), Category = "MultiThreadLibrary") static void AddToRoot(UObject* Object); /** * Checks if Whether filehandles can be opened on one thread and read/written on another thread. */ UFUNCTION(BlueprintPure, meta = (DisplayName = "Can Support Multi Threaded File Handles"), Category = "MultiThreadLibrary") static bool CanSupportMultiThreadedFileHandles(); /** * Checks if system suport MultiThreading. */ UFUNCTION(BlueprintPure, meta = (DisplayName = "Is Supports Multithreading"), Category = "MultiThreadLibrary") static bool IsSupportsMultithreading(); /** * Set Thread Name on threan where is called this function. */ UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Name To Thread"), Category = "MultiThreadLibrary") static void SetNameToThread(FString ThreadName); private: static void OnEndPIE(const bool bIsSimulating); static void OnPreExit(); public: #if WITH_EDITOR static FDelegateHandle EndPIEHandle; #else static FDelegateHandle PreExitHandle; #endif static TArray RootObjects; static int32 TaskIndex; static int32 MutexIndex; static int32 ThreadPoolIndex; };