161 lines
3.9 KiB
C++
161 lines
3.9 KiB
C++
// Copyright UnexGames 2025. All Rights Reserved.
|
|
#pragma once
|
|
#include "CoreMinimal.h"
|
|
#include "ThreadTaskBase.h"
|
|
#include "HAL/ThreadManager.h"
|
|
#include "ThreadTasks.generated.h"
|
|
|
|
DECLARE_MULTICAST_DELEGATE(FThreadTaskDelegate);
|
|
|
|
UCLASS(HideDropdown, Blueprintable, hidecategories = (Object), meta = (DontUseGenericSpawnObject = "true"))
|
|
class MULTITHREADLIBRARY_API UThreadTasks : public UThreadTaskBase
|
|
{
|
|
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
|
|
virtual bool Start() override;
|
|
|
|
/**
|
|
* Called on Background Thread when the Task is executed.
|
|
*/
|
|
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, meta = (DisplayName = "Task Body"), Category = "MultiThreadLibrary")
|
|
void TaskBody();
|
|
|
|
virtual void TaskBody_Implementation();
|
|
|
|
public:
|
|
FThreadTaskDelegate TaskDelegate;
|
|
|
|
protected:
|
|
|
|
|
|
};
|
|
|
|
|
|
class MULTITHREADLIBRARY_API FThreadTaskOnly : public FTaskActionBase
|
|
{
|
|
ETaskResultBranches& Branches;
|
|
bool bStarted;
|
|
public:
|
|
FThreadTaskOnly(UObject* InObject, ETaskResultBranches& InBranches, const FLatentActionInfo& LatentInfo, TSubclassOf<class UThreadTasks> TaskClass, UThreadBase*& OutTask)
|
|
: FTaskActionBase(InObject, LatentInfo, TaskClass)
|
|
, Branches(InBranches)
|
|
, bStarted(false)
|
|
{
|
|
OutTask = Task;
|
|
|
|
UThreadTasks* LocalTask = Cast<UThreadTasks>(Task);
|
|
if (LocalTask)
|
|
{
|
|
Branches = ETaskResultBranches::OnStart;
|
|
LocalTask->BodyFunction();
|
|
|
|
bStarted = Task->Start();
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
virtual void UpdateOperation(FLatentResponse& Response) override
|
|
{
|
|
if (bStarted)
|
|
{
|
|
if (!IsCanceled())
|
|
{
|
|
if (!IsRunning())
|
|
{
|
|
Branches = ETaskResultBranches::OnCompleted;
|
|
Response.FinishAndTriggerIf(true, ExecutionFunction, OutputLink, CallbackTarget);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Branches = ETaskResultBranches::OnCanceled;
|
|
Response.FinishAndTriggerIf(true, ExecutionFunction, OutputLink, CallbackTarget);
|
|
}
|
|
}
|
|
else {
|
|
//If we reached this point it means the task was unable to start.
|
|
Branches = ETaskResultBranches::OnCompleted;
|
|
Response.FinishAndTriggerIf(true, ExecutionFunction, OutputLink, CallbackTarget);
|
|
}
|
|
}
|
|
};
|
|
|
|
class MULTITHREADLIBRARY_API FThreadTaskWithBody : public FTaskActionBase
|
|
{
|
|
EtaskExecutionBranches& Branches;
|
|
bool bStarted;
|
|
public:
|
|
FThreadTaskWithBody(UObject* InObject, EtaskExecutionBranches& InBranches, const FLatentActionInfo& LatentInfo, TSubclassOf<class UThreadTasks> TaskClass, const ETaskExecutionType& InExecutionType, UThreadBase*& OutTask)
|
|
: FTaskActionBase(InObject, LatentInfo, TaskClass)
|
|
, Branches(InBranches)
|
|
, bStarted(false)
|
|
{
|
|
OutTask = Task;
|
|
|
|
UThreadTasks* LocalTask = Cast<UThreadTasks>(Task);
|
|
if (LocalTask)
|
|
{
|
|
Branches = EtaskExecutionBranches::OnStart;
|
|
LocalTask->BodyFunction();
|
|
|
|
LocalTask->TaskDelegate.AddLambda([LocalTask, &InBranches]
|
|
{
|
|
InBranches = EtaskExecutionBranches::OnTaskBody;
|
|
LocalTask->BodyFunction();
|
|
});
|
|
LocalTask->OnCancelDelegate.AddLambda([LocalTask, &InBranches]
|
|
{
|
|
InBranches = EtaskExecutionBranches::OnCanceled;
|
|
LocalTask->BodyFunction();
|
|
});
|
|
|
|
bStarted = Task->Start();
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
virtual ~FThreadTaskWithBody()
|
|
{
|
|
if (Task != nullptr && Task->IsValidLowLevel() && IsValid(Task) && !Task->IsUnreachable())
|
|
{
|
|
UThreadTasks* LocalTask = Cast<UThreadTasks>(Task);
|
|
if (LocalTask)
|
|
{
|
|
LocalTask->TaskDelegate.RemoveAll(this);
|
|
LocalTask->OnCancelDelegate.RemoveAll(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void UpdateOperation(FLatentResponse& Response) override
|
|
{
|
|
if (bStarted)
|
|
{
|
|
if (!IsCanceled())
|
|
{
|
|
if (!IsRunning())
|
|
{
|
|
Branches = EtaskExecutionBranches::OnCompleted;
|
|
Response.FinishAndTriggerIf(true, ExecutionFunction, OutputLink, CallbackTarget);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Response.DoneIf(true);
|
|
}
|
|
}
|
|
else {
|
|
//If we reached this point it means the task was unable to start.
|
|
Branches = EtaskExecutionBranches::OnCompleted;
|
|
Response.FinishAndTriggerIf(true, ExecutionFunction, OutputLink, CallbackTarget);
|
|
}
|
|
}
|
|
}; |