October3d55/M/MultiThread/Source/MultiThreadLibrary/Private/ThreadTasksLoop.cpp

110 lines
2.5 KiB
C++

// Copyright UnexGames 2025. All Rights Reserved.
#include "ThreadTasksLoop.h"
UThreadTasksLoop::UThreadTasksLoop()
{
bIsTickable = true;
}
UThreadTasksLoop::~UThreadTasksLoop()
{
}
bool UThreadTasksLoop::Start()
{
EAsyncExecution AsyncType = EAsyncExecution::TaskGraph;
UThreadTasksLoop* TaskWorker = this;
TFunction<void()> BodyFunc = [TaskWorker]()
{
if (TaskWorker != nullptr && TaskWorker->IsValidLowLevel() && IsValid(TaskWorker) && !TaskWorker->IsUnreachable())
{
TaskWorker->TaskBody(TaskWorker);
if (TaskWorker->TaskDelegate.IsBound())
{
TaskWorker->TaskDelegate.Broadcast();
}
}
};
TFunction<void()> OnCompleteFunc = [TaskWorker]()
{
AsyncTask(ENamedThreads::GameThread, [TaskWorker]()
{
if (TaskWorker != nullptr && TaskWorker->IsValidLowLevel() && IsValid(TaskWorker) && !TaskWorker->IsUnreachable())
{
if (!TaskWorker->IsCanceled())
{
TaskWorker->OnComplete();
}
else
{
TaskWorker->Cancel();
}
}
});
};
Tasks.SetNumZeroed(1);
Tasks[0] = Async(AsyncType, TUniqueFunction<void()>(BodyFunc), TUniqueFunction<void()>(OnCompleteFunc)); // Async functions, it create an new threadpool and execute functions on it.
return (true);
}
bool UThreadTasksLoop::IsRunning()
{
if (!IsCanceled() && bStarted)
{
return true;
}
return false;
}
void UThreadTasksLoop::TaskBody_Implementation(UThreadTasksLoop* WorkerRef)
{
while (RepeatTime < BaseLoopNR)
{
if (WorkerRef != nullptr && WorkerRef->IsValidLowLevel() && IsValid(WorkerRef) && !WorkerRef->IsUnreachable())
{
if (WorkerRef->TaskDelegate.IsBound())
{
WorkerRef->TaskDelegate.Broadcast();
}
}
if (!IsInGameThread())
{
FPlatformProcess::Sleep(BaseLoopInterval);
}
RepeatTime++;
}
if (RepeatTime >= BaseLoopNR)
{
if (WorkerRef != nullptr && WorkerRef->IsValidLowLevel() && IsValid(WorkerRef) && !WorkerRef->IsUnreachable() && !bCanceled)
{
WorkerRef->Cancel();
}
}
}
void UThreadTasksLoop::Cancel_Implementation()
{
RepeatTime = BaseLoopNR;
}