├── .gitignore ├── AsyncFuncCaller.uplugin ├── Content ├── AsyncBPFuncTest_BP.uasset ├── PrimeNumCalculator.uasset ├── TestThread_Wdb.uasset └── ThreadWorker.uasset ├── README.md ├── Resources ├── Icon128.png └── imgs │ ├── asb(1).jpg │ ├── asb(1).png │ ├── asb.png │ ├── asb2.png │ ├── m1_1.png │ ├── m1_2.png │ ├── m2_1.png │ ├── m3_1.png │ ├── m3_2.png │ ├── m3_3.png │ ├── wxss_20191129134839.png │ ├── wxss_20191129134949.png │ ├── wxss_20191129135000.png │ ├── wxss_20191129154636.png │ ├── wxss_20191201162131.png │ ├── wxss_20191201162218.png │ ├── wxss_20191201162544.png │ └── wxss_20191201162600.png └── Source └── AsyncFuncCaller ├── AsyncFuncCaller.Build.cs ├── Private ├── AsyncBpLibrary.cpp ├── AsyncFuncCaller.cpp ├── AsyncLoopEventManager.cpp ├── FuncCaller.cpp ├── FuncCallerWorker.cpp └── RunnableThreadWorker.cpp └── Public ├── AsyncBpLibrary.h ├── AsyncFuncCaller.h ├── AsyncLoopEventManager.h ├── FuncCaller.h ├── FuncCallerWorker.h └── RunnableThreadWorker.h /.gitignore: -------------------------------------------------------------------------------- 1 | /Binaries/ 2 | /Intermediate/ -------------------------------------------------------------------------------- /AsyncFuncCaller.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "AsyncFuncCaller", 6 | "Description": "", 7 | "Category": "Other", 8 | "CreatedBy": "", 9 | "CreatedByURL": "", 10 | "DocsURL": "", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/275ea814e498453b8532dc63a7cec86e", 12 | "SupportURL": "", 13 | "EngineVersion": "4.26.0", 14 | "CanContainContent": true, 15 | "IsBetaVersion": false, 16 | "Installed": false, 17 | "Modules": [ 18 | { 19 | "Name": "AsyncFuncCaller", 20 | "Type": "Runtime", 21 | "LoadingPhase": "Default", 22 | "WhitelistPlatforms": [ 23 | "Win64" 24 | ] 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /Content/AsyncBPFuncTest_BP.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Content/AsyncBPFuncTest_BP.uasset -------------------------------------------------------------------------------- /Content/PrimeNumCalculator.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Content/PrimeNumCalculator.uasset -------------------------------------------------------------------------------- /Content/TestThread_Wdb.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Content/TestThread_Wdb.uasset -------------------------------------------------------------------------------- /Content/ThreadWorker.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Content/ThreadWorker.uasset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AsyncFuncCaller 2 | 3 | branch 4.18 has been Tested on Win64 VS15 UE4.18 4 | 5 | # AsyncFuncCaller 2.0(In developping) 6 | branch 4.23 has been Tested on Win64 VS17 UE4.23 7 | 8 | branch 4.26 has been Tested on Win64 VS19 UE4.26 9 | 10 | how to use:https://github.com/npcbx/AsyncFuncCaller/wiki/How-to-Use 11 | -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/Icon128.png -------------------------------------------------------------------------------- /Resources/imgs/asb(1).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/asb(1).jpg -------------------------------------------------------------------------------- /Resources/imgs/asb(1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/asb(1).png -------------------------------------------------------------------------------- /Resources/imgs/asb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/asb.png -------------------------------------------------------------------------------- /Resources/imgs/asb2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/asb2.png -------------------------------------------------------------------------------- /Resources/imgs/m1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/m1_1.png -------------------------------------------------------------------------------- /Resources/imgs/m1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/m1_2.png -------------------------------------------------------------------------------- /Resources/imgs/m2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/m2_1.png -------------------------------------------------------------------------------- /Resources/imgs/m3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/m3_1.png -------------------------------------------------------------------------------- /Resources/imgs/m3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/m3_2.png -------------------------------------------------------------------------------- /Resources/imgs/m3_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/m3_3.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191129134839.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191129134839.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191129134949.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191129134949.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191129135000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191129135000.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191129154636.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191129154636.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191201162131.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191201162131.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191201162218.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191201162218.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191201162544.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191201162544.png -------------------------------------------------------------------------------- /Resources/imgs/wxss_20191201162600.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npcbx/AsyncFuncCaller/040764e723675d5bf4b5acdaf47d17d9cb6c39dc/Resources/imgs/wxss_20191201162600.png -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/AsyncFuncCaller.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Hujiachuan. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class AsyncFuncCaller : ModuleRules 6 | { 7 | public AsyncFuncCaller(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | // ... add other public dependencies that you statically link with here ... 30 | } 31 | ); 32 | 33 | 34 | PrivateDependencyModuleNames.AddRange( 35 | new string[] 36 | { 37 | "CoreUObject", 38 | "Engine", 39 | "Slate", 40 | "SlateCore", 41 | // ... add private dependencies that you statically link with here ... 42 | } 43 | ); 44 | 45 | 46 | DynamicallyLoadedModuleNames.AddRange( 47 | new string[] 48 | { 49 | // ... add any modules that your module loads dynamically here ... 50 | } 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Private/AsyncBpLibrary.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "AsyncBpLibrary.h" 5 | //#include 6 | #include "RunnableThreadWorker.h" 7 | 8 | #include 9 | #include 10 | 11 | #include "Windows/AllowWindowsPlatformTypes.h" 12 | #include "windows.h" 13 | #include "Windows/HideWindowsPlatformTypes.h" 14 | 15 | 16 | UAsyncFuncWorker* UAsyncBpLibrary::StartAsyncFuncWithOption(const FAsyncFuncOption& _option) 17 | { 18 | UAsyncFuncWorker * asyncBpWorker = NewObject(); 19 | asyncBpWorker->option = _option; 20 | asyncBpWorker->AddToRoot(); 21 | asyncBpWorker->DoThread(); 22 | 23 | return asyncBpWorker; 24 | } 25 | 26 | //URunnableThreadCaller* UAsyncBpLibrary::StartRunnableThreadWithOption(const FRunnableThreadOption& _option) 27 | //{ 28 | // 29 | // //URunnableThreadCaller * loader = NewObject(); 30 | // 31 | // FString ThreadName = FString::Printf(TEXT("AsyncRunnableThread:")); 32 | // ThreadName.AppendInt(FAsyncThreadIndex::GetNext()); 33 | // 34 | // URunnableThreadCaller * caller = NewObject(); 35 | // caller->ThreadRunner = new FRunnableThreadWorker(_option); 36 | // caller->RunningThread = FRunnableThread::Create(caller->ThreadRunner, *ThreadName); 37 | // return caller; 38 | //} 39 | 40 | int32 UAsyncBpLibrary::GetNowThreadId() 41 | { 42 | return GetCurrentThreadId(); 43 | } 44 | 45 | int32 UAsyncBpLibrary::GetHardWareConcurrencyNum() 46 | { 47 | return std::thread::hardware_concurrency(); 48 | } 49 | 50 | void UAsyncBpLibrary::MakeCurrentThreadSleep(float seconds) 51 | { 52 | FPlatformProcess::Sleep(seconds); 53 | } 54 | 55 | void UAsyncBpLibrary::HoldUObject(UObject* obj) 56 | { 57 | if (obj && obj->IsValidLowLevel()) 58 | { 59 | obj->AddToRoot(); 60 | } 61 | 62 | } 63 | 64 | void UAsyncBpLibrary::ReleaseUObject(UObject* obj) 65 | { 66 | if (obj && obj->IsValidLowLevel()) 67 | { 68 | obj->RemoveFromRoot(); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Private/AsyncFuncCaller.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Hujiachuan. All Rights Reserved. 2 | 3 | #include "AsyncFuncCaller.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FAsyncFuncCallerModule" 6 | 7 | void FAsyncFuncCallerModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | } 11 | 12 | void FAsyncFuncCallerModule::ShutdownModule() 13 | { 14 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 15 | // we call this function before unloading the module. 16 | } 17 | 18 | #undef LOCTEXT_NAMESPACE 19 | 20 | IMPLEMENT_MODULE(FAsyncFuncCallerModule, AsyncFuncCaller) -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Private/AsyncLoopEventManager.cpp: -------------------------------------------------------------------------------- 1 | #include "AsyncLoopEventManager.h" 2 | 3 | 4 | 5 | 6 | void URunnableThreadCaller::PauseThread() 7 | { 8 | 9 | FRunnableThreadWorker * threadWorker = (FRunnableThreadWorker*)ThreadRunner; 10 | if (threadWorker) 11 | { 12 | threadWorker->PauseWork(); 13 | } 14 | 15 | } 16 | 17 | void URunnableThreadCaller::ResumeThread() 18 | { 19 | FRunnableThreadWorker * threadWorker = (FRunnableThreadWorker*)ThreadRunner; 20 | if (threadWorker) 21 | { 22 | threadWorker->ResumeWork(); 23 | } 24 | 25 | } 26 | 27 | void URunnableThreadCaller::EndThread() 28 | { 29 | 30 | FRunnableThreadWorker * threadWorker = (FRunnableThreadWorker*)ThreadRunner; 31 | if (threadWorker) 32 | { 33 | threadWorker->EndWork(); 34 | } 35 | } 36 | 37 | 38 | //void URunnableThreadCaller::ExecuteGameThreadEvent(const FRunnabelCommonDataType& data) 39 | void URunnableThreadCaller::ExecuteGameThreadEvent(const TArray& intArray, const TArray& floatArray, const TArray& StringArray) 40 | { 41 | //UE_LOG(LogTemp, Log, TEXT("URunnableThreadCaller::ExecuteGameThreadEvent,int arr:%d, float arr:%d, string arr:%d, "), intArray.Num(), floatArray.Num(), StringArray.Num()); 42 | FRunnableThreadWorker * threadWorker = (FRunnableThreadWorker*)ThreadRunner; 43 | if (threadWorker) 44 | { 45 | threadWorker->RunEventOnGameThread(intArray, floatArray, StringArray); 46 | } 47 | } 48 | 49 | 50 | void URunnableThreadCaller::ExecuteCriticalEvent() 51 | { 52 | FRunnableThreadWorker * threadWorker = (FRunnableThreadWorker*)ThreadRunner; 53 | 54 | if (threadWorker) 55 | { 56 | threadWorker->RunCiticalEvent(); 57 | } 58 | } 59 | 60 | 61 | UAsyncLoopEventManager* UAsyncLoopEventManager::CreateAAsyncLoopEventManager() 62 | { 63 | UAsyncLoopEventManager* manager = NewObject(); 64 | manager->AddToRoot(); 65 | return manager; 66 | } 67 | URunnableThreadCaller* UAsyncLoopEventManager::StartAsyncLoopEvent(const FRunnableThreadOption& _option) 68 | { 69 | FString ThreadName = FString::Printf(TEXT("AsyncLoopEventThread:")); 70 | ThreadName.AppendInt(FAsyncThreadIndex::GetNext()); 71 | 72 | URunnableThreadCaller * caller = NewObject(); 73 | caller->ThreadRunner = new FRunnableThreadWorker(_option, this); 74 | caller->RunningThread = FRunnableThread::Create(caller->ThreadRunner, *ThreadName); 75 | return caller; 76 | } 77 | 78 | 79 | // 80 | //void UTextureLoader::OnFinishCallback(UTexture2D* tex, bool Result, FString FilePath, FString Guid) { 81 | // if (Result) 82 | // { 83 | // if (TextureLoaderSingleton::getInstance()) { 84 | // TextureLoaderSingleton::getInstance()->TextureInfoMap.Add(tex, FTextureLoaderInfo(FilePath, Guid)); 85 | // TextureLoaderSingleton::getInstance()->PathTextureMap.Add(FilePath, tex); 86 | // } 87 | // OnComplete.Broadcast(tex); 88 | // } 89 | // else { 90 | // OnFail.Broadcast(); 91 | // } 92 | //} 93 | 94 | -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Private/FuncCaller.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | // Copyright 2019 Hujiachuan. All Rights Reserved. 3 | 4 | #include "FuncCaller.h" 5 | #include "FuncCallerWorker.h" 6 | 7 | UFuncCaller* UFuncCaller::StartAsyncFuncByFuncName(FString FuncName, UObject* Target) { 8 | UFuncCaller * loader = NewObject(); 9 | 10 | FString ThreadName = FString::Printf(TEXT("FuncCallerThreadWorkder Thread:")); 11 | ThreadName.AppendInt(FAsyncThreadIndex::GetNext()); 12 | 13 | FuncCallFinishDelegate LoadFinishHandler; 14 | LoadFinishHandler.BindUObject(loader, &UFuncCaller::OnFinishCallback); 15 | 16 | 17 | FRunnableThread::Create(new FFuncCallerThreadWorker(FuncName, Target, LoadFinishHandler), *ThreadName); 18 | 19 | return loader; 20 | } 21 | 22 | void UFuncCaller::OnFinishCallback(UObject* obj, bool Result) { 23 | if (Result) 24 | { 25 | OnComplete.Broadcast(obj); 26 | } 27 | else { 28 | OnFail.Broadcast(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Private/FuncCallerWorker.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | // Copyright 2019 Hujiachuan. All Rights Reserved. 3 | 4 | 5 | #include "FuncCallerWorker.h" 6 | #include "FuncCaller.h" 7 | 8 | //Init 9 | bool FFuncCallerThreadWorker::Init() 10 | { 11 | return true; 12 | } 13 | //Run 14 | uint32 FFuncCallerThreadWorker::Run() { 15 | if (Target) 16 | { 17 | FOutputDeviceNull DymmyOutputDevice; 18 | Target->CallFunctionByNameWithArguments(*FuncName, DymmyOutputDevice, Target, true); 19 | } 20 | else { 21 | CallResult = false; 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | void FFuncCallerThreadWorker::Exit() 28 | { 29 | FuncCallFinishDelegate Handler = FuncCallFinishHandler; 30 | UObject * outPut = Target; 31 | bool Result = CallResult; 32 | 33 | AsyncTask(ENamedThreads::GameThread, [Handler, outPut, Result]() { 34 | // code to execute on game thread here 35 | Handler.ExecuteIfBound(outPut, Result); 36 | }); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Private/RunnableThreadWorker.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | // Copyright 2019 Hujiachuan. All Rights Reserved. 3 | 4 | 5 | #include "RunnableThreadWorker.h" 6 | #include "Async/Async.h" 7 | #include "AsyncLoopEventManager.h" 8 | //#include 9 | //std::timed_mutex data_tmutex; 10 | //Init 11 | bool FRunnableThreadWorker::Init() 12 | { 13 | UE_LOG(LogTemp, Log, TEXT("FRunnableThreadWorker::Init ")); 14 | return true; 15 | } 16 | //Run 17 | uint32 FRunnableThreadWorker::Run() { 18 | 19 | while (!IfEndWork.load()) { 20 | //UE_LOG(LogTemp, Log, TEXT("FRunnableThreadWorker::run step2, thread:%d "), GetCurrentThreadId()); 21 | //if (AsyncFuncCallerOption.IfNeedPrepare) 22 | //{ 23 | // std::lock_guard lockg(data_tmutex); 24 | // AsyncFuncCallerOption.UpdatePrepareEvent.ExecuteIfBound(AsyncFuncCallerOption.objs); 25 | //} 26 | if (IfPauseWork.load()) 27 | { 28 | FPlatformProcess::Sleep(0.1f); 29 | continue; 30 | } 31 | AsyncFuncCallerOption.AsyncEvent.ExecuteIfBound(AsyncFuncCallerOption.objs); 32 | //FPlatformProcess::Sleep(0.02f); 33 | } 34 | return 0; 35 | } 36 | 37 | void FRunnableThreadWorker::Exit() 38 | { 39 | //FuncCallFinishDelegate Handler = FuncCallFinishHandler; 40 | //UObject * outPut = Target; 41 | //bool Result = CallResult; 42 | // 43 | AsyncTask(ENamedThreads::GameThread, [=]() { 44 | //AsyncFuncCallerOption..ExecuteIfBound(AsyncFuncCallerOption.objs); 45 | AsyncFuncCallerOption.FinishEvent.ExecuteIfBound(AsyncFuncCallerOption.objs); 46 | }); 47 | } 48 | 49 | void FRunnableThreadWorker::RunCiticalEvent() 50 | { 51 | //UAsyncLoopEventManager * _manager = (UAsyncLoopEventManager*)(Manager); 52 | if (Manager) 53 | { 54 | std::lock_guard lockg(Manager->data_mutex); 55 | AsyncFuncCallerOption.CriticalEvent.ExecuteIfBound(AsyncFuncCallerOption.objs); 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Public/AsyncBpLibrary.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Kismet/BlueprintFunctionLibrary.h" 7 | #include 8 | #include "HAL/Runnable.h" 9 | //#include 10 | #include "AsyncBpLibrary.generated.h" 11 | 12 | /** 13 | * 14 | */ 15 | 16 | DECLARE_DYNAMIC_DELEGATE_OneParam(FAsyncFuncCallback, const TArray&, objs); 17 | //DECLARE_DYNAMIC_DELEGATE(FAsyncFuncCallback); 18 | 19 | //USTRUCT(BlueprintType) 20 | //struct FRunnabelCommonDataType 21 | //{ 22 | // GENERATED_BODY() 23 | //public: 24 | // UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncWithOption") 25 | // TArray ints = {}; 26 | // UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncWithOption") 27 | // TArray floats = {}; 28 | // UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncWithOption") 29 | // TArray strings = {}; 30 | //}; 31 | 32 | DECLARE_DYNAMIC_DELEGATE_ThreeParams(FGameThreadEvtCallback, const TArray&, intArray, const TArray&, floatArray, const TArray&, StringArray); 33 | //DECLARE_DYNAMIC_DELEGATE(FGameThreadEvtCallback); 34 | 35 | 36 | 37 | USTRUCT(BlueprintType) 38 | struct FAsyncFuncOption 39 | { 40 | GENERATED_BODY() 41 | public: 42 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncWithOption") 43 | TArray objs = {}; 44 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncWithOption") 45 | FAsyncFuncCallback AsyncEvent; 46 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncWithOption") 47 | FAsyncFuncCallback GameThreadEvent; 48 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncWithOption") 49 | FAsyncFuncCallback FinishEvent; 50 | }; 51 | 52 | 53 | 54 | UCLASS(Blueprintable) 55 | class UAsyncFuncWorker : public UObject 56 | { 57 | GENERATED_BODY() 58 | public: 59 | UAsyncFuncWorker() { 60 | //promise1 = MakeShared, ESPMode::ThreadSafe>(); 61 | //promise2= MakeShared, ESPMode::ThreadSafe>(); 62 | } 63 | UAsyncFuncWorker(const FAsyncFuncOption& opt) : option(opt) {} 64 | ~UAsyncFuncWorker() { 65 | //if (promise1) 66 | //{ 67 | // promise1->GetFuture().Wait(); 68 | //} 69 | //if (promise2) 70 | //{ 71 | // promise2->GetFuture().Wait(); 72 | //} 73 | 74 | 75 | if (WorkingThread) 76 | { 77 | //std::pthread_cancel(WorkingThread.native_handle()); 78 | //WorkingThread.join(); 79 | 80 | delete WorkingThread; 81 | WorkingThread = nullptr; 82 | } 83 | } 84 | public: 85 | 86 | //TSharedPtr, ESPMode::ThreadSafe> promise1; 87 | //TSharedPtr, ESPMode::ThreadSafe> promise2; 88 | FAsyncFuncOption option; 89 | 90 | std::thread* WorkingThread = nullptr; 91 | //TSharedPtr WorkingThread; 92 | 93 | void DoThread() { 94 | AddToRoot(); 95 | UAsyncFuncWorker* worker = this; 96 | 97 | auto AsyncFunction = [=]() { 98 | option.AsyncEvent.ExecuteIfBound(option.objs); 99 | if (worker && worker->IsValidLowLevel()) 100 | { 101 | AsyncTask(ENamedThreads::GameThread, [=] { 102 | if (worker && worker->IsValidLowLevel()) 103 | { 104 | option.FinishEvent.ExecuteIfBound(option.objs); 105 | worker->RemoveFromRoot(); 106 | } 107 | //promise2->SetValue(); 108 | }); 109 | } 110 | //promise1->SetValue(); 111 | }; 112 | 113 | //WorkingThread = MakeShareable(new std::thread(AsyncFunction)); 114 | WorkingThread = new std::thread(AsyncFunction); 115 | WorkingThread->detach(); 116 | } 117 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncWithOption") 118 | void ExecuteGameThreadEventOnGameThread() 119 | { 120 | UAsyncFuncWorker* worker = this; 121 | if (worker && worker->IsValidLowLevel()) 122 | { 123 | AsyncTask(ENamedThreads::GameThread, [=] { 124 | option.GameThreadEvent.ExecuteIfBound(option.objs); 125 | }); 126 | } 127 | } 128 | 129 | }; 130 | 131 | 132 | 133 | UCLASS() 134 | class UAsyncBpLibrary : public UBlueprintFunctionLibrary 135 | { 136 | GENERATED_BODY() 137 | 138 | public: 139 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncWithOption") 140 | static UAsyncFuncWorker* StartAsyncFuncWithOption(const FAsyncFuncOption& _option); 141 | 142 | //UFUNCTION(BlueprintCallable, Category = "AsyncFuncWithOption") 143 | //static URunnableThreadCaller* StartRunnableThreadWithOption(const FRunnableThreadOption& _option); 144 | 145 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncWithOption") 146 | static int32 GetNowThreadId(); 147 | 148 | UFUNCTION(Blueprintpure, Category = "AsyncFuncWithOption") 149 | static int32 GetHardWareConcurrencyNum(); 150 | 151 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncWithOption") 152 | static void MakeCurrentThreadSleep(float seconds); 153 | 154 | UFUNCTION(BlueprintCallable, Category = "MeshExporter") 155 | static void HoldUObject(UObject* obj); 156 | UFUNCTION(BlueprintCallable, Category = "MeshExporter") 157 | static void ReleaseUObject(UObject* obj); 158 | }; 159 | -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Public/AsyncFuncCaller.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2019 Hujiachuan. All Rights Reserved. 3 | 4 | 5 | #pragma once 6 | 7 | #include "CoreMinimal.h" 8 | #include "Modules/ModuleManager.h" 9 | 10 | class FAsyncFuncCallerModule : public IModuleInterface 11 | { 12 | public: 13 | 14 | /** IModuleInterface implementation */ 15 | virtual void StartupModule() override; 16 | virtual void ShutdownModule() override; 17 | }; 18 | -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Public/AsyncLoopEventManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CoreMinimal.h" 3 | #include "Engine.h" 4 | //#include "Kismet/BlueprintAsyncActionBase.h" 5 | #include 6 | //#include "RunnableThreadWorker.h" 7 | //#include "AsyncBpLibrary.h" 8 | 9 | //#include "Kismet/BlueprintFunctionLibrary.h" 10 | #include "AsyncLoopEventManager.generated.h" 11 | 12 | //DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTextureLoaderDelegate, UTexture2D*, texture); 13 | //DECLARE_DYNAMIC_MULTICAST_DELEGATE(FTextureLoaderFailDelegate); 14 | 15 | //USTRUCT(BlueprintType) 16 | //struct FTextureLoaderInfo 17 | //{ 18 | // GENERATED_BODY() 19 | //public: 20 | // UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "如果爱|FileUtility") 21 | // FString Guid; 22 | // 23 | // UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "如果爱|FileUtility") 24 | // FString FilePath; 25 | // 26 | // FTextureLoaderInfo() { 27 | // Guid = FString(TEXT("")); 28 | // FilePath = FString(TEXT("")); 29 | // } 30 | // FTextureLoaderInfo(FString _path, FString _guid) { 31 | // Guid = _guid; 32 | // FilePath = _path; 33 | // } 34 | //}; 35 | 36 | USTRUCT(BlueprintType) 37 | struct FRunnableThreadOption 38 | { 39 | GENERATED_BODY() 40 | public: 41 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncCallerWithOption") 42 | TArray objs = {}; 43 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncCallerWithOption") 44 | FAsyncFuncCallback CriticalEvent; 45 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncCallerWithOption") 46 | FAsyncFuncCallback AsyncEvent; 47 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncCallerWithOption") 48 | FGameThreadEvtCallback GameThreadEvent; 49 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AsyncFuncCallerWithOption") 50 | FAsyncFuncCallback FinishEvent; 51 | }; 52 | 53 | //static TArray DefaultIntArray = {}; 54 | //TArray DefaultIntArray = {}; 55 | //TArray DefaultIntArray = {}; 56 | 57 | UCLASS(Blueprintable) 58 | class URunnableThreadCaller : public UObject 59 | { 60 | GENERATED_BODY() 61 | public: 62 | URunnableThreadCaller() {} 63 | ~URunnableThreadCaller() { 64 | 65 | if (RunningThread) 66 | { 67 | RunningThread->WaitForCompletion(); 68 | } 69 | if (ThreadRunner) 70 | { 71 | delete ThreadRunner; 72 | ThreadRunner = nullptr; 73 | } 74 | } 75 | 76 | FRunnableThread * RunningThread; 77 | FRunnable * ThreadRunner; 78 | 79 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncCallerWithOption") 80 | void PauseThread(); 81 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncCallerWithOption") 82 | void ResumeThread(); 83 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncCallerWithOption") 84 | void EndThread(); 85 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncWithOption") 86 | //void ExecuteGameThreadEvent(const FRunnabelCommonDataType& data); 87 | void ExecuteGameThreadEvent(const TArray& intArray, const TArray& floatArray, const TArray& StringArray); 88 | UFUNCTION(BlueprintCallable, Category = "AsyncFuncWithOption") 89 | void ExecuteCriticalEvent(); 90 | }; 91 | 92 | 93 | UCLASS(Blueprintable) 94 | class UAsyncLoopEventManager : public UObject 95 | { 96 | GENERATED_BODY() 97 | 98 | public: 99 | 100 | UFUNCTION(BLueprintCallable, Category = "AsyncLoopEventManager") 101 | static UAsyncLoopEventManager* CreateAAsyncLoopEventManager(); 102 | 103 | std::timed_mutex data_mutex; 104 | 105 | UFUNCTION(BlueprintCallable, Category = "AsyncLoopEventManager") 106 | URunnableThreadCaller* StartAsyncLoopEvent(const FRunnableThreadOption& _option); 107 | 108 | //UPROPERTY(BlueprintAssignable) 109 | //FTextureLoaderDelegate OnComplete; 110 | //UPROPERTY(BlueprintAssignable) 111 | //FTextureLoaderFailDelegate OnFail; 112 | 113 | 114 | }; -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Public/FuncCaller.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | // Copyright 2019 Hujiachuan. All Rights Reserved. 3 | 4 | #pragma once 5 | #include "CoreMinimal.h" 6 | #include "Engine.h" 7 | #include "Kismet/BlueprintAsyncActionBase.h" 8 | 9 | #include "FuncCaller.generated.h" 10 | 11 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FFuncCallSuccessDelegate, UObject*, obj); 12 | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FFuncCallFailDelegate); 13 | 14 | 15 | 16 | UCLASS(Blueprintable) 17 | class ASYNCFUNCCALLER_API UFuncCaller : public UBlueprintAsyncActionBase 18 | { 19 | GENERATED_BODY() 20 | 21 | public: 22 | 23 | UFUNCTION(BLueprintCallable, Category = "如果爱|FileUtility", meta = (BlueprintInternalUseOnly = "true")) 24 | static UFuncCaller* StartAsyncFuncByFuncName(FString FuncName, UObject* Target); 25 | 26 | UPROPERTY(BlueprintAssignable) 27 | FFuncCallSuccessDelegate OnComplete; 28 | UPROPERTY(BlueprintAssignable) 29 | FFuncCallFailDelegate OnFail; 30 | 31 | void OnFinishCallback(UObject* obj, bool Result); 32 | }; -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Public/FuncCallerWorker.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | // Copyright 2019 Hujiachuan. All Rights Reserved. 3 | 4 | 5 | #pragma once 6 | 7 | #include "CoreMinimal.h" 8 | 9 | DECLARE_DELEGATE_TwoParams(FuncCallFinishDelegate, UObject*, bool); 10 | 11 | class ASYNCFUNCCALLER_API FFuncCallerThreadWorker : public FRunnable 12 | { 13 | public: 14 | //construct func 15 | FFuncCallerThreadWorker(FString _funcName, UObject* _target, FuncCallFinishDelegate _funcCallFinishHandler): 16 | FuncName(_funcName), Target(_target), FuncCallFinishHandler(_funcCallFinishHandler) 17 | { 18 | 19 | } 20 | 21 | //thread work 22 | virtual bool Init() override; 23 | virtual uint32 Run() override; 24 | virtual void Exit() override; 25 | 26 | private: 27 | FuncCallFinishDelegate FuncCallFinishHandler; 28 | FString FuncName; 29 | UObject * Target; 30 | bool CallResult = true; 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /Source/AsyncFuncCaller/Public/RunnableThreadWorker.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | // Copyright 2019 Hujiachuan. All Rights Reserved. 3 | 4 | 5 | #pragma once 6 | 7 | #include "CoreMinimal.h" 8 | #include "AsyncBpLibrary.h" 9 | #include 10 | #include "AsyncLoopEventManager.h" 11 | 12 | DECLARE_DELEGATE_TwoParams(AsyncFuncCallFinishDelegate, UObject*, bool); 13 | 14 | 15 | class FRunnableThreadWorker : public FRunnable 16 | { 17 | public: 18 | //construct func 19 | FRunnableThreadWorker(const FRunnableThreadOption& _AsyncFuncCallerOption, UAsyncLoopEventManager* _manager): 20 | AsyncFuncCallerOption(_AsyncFuncCallerOption), Manager(_manager) 21 | { 22 | IfPauseWork.store(false); 23 | IfEndWork.store(false); 24 | } 25 | 26 | //thread work 27 | virtual bool Init() override; 28 | virtual uint32 Run() override; 29 | virtual void Exit() override; 30 | 31 | std::atomic IfPauseWork; 32 | std::atomic IfEndWork; 33 | void PauseWork() { 34 | if (!IfPauseWork.load()) { 35 | IfPauseWork.store(true); 36 | } 37 | } 38 | void ResumeWork() 39 | { 40 | if (IfPauseWork.load()) { 41 | IfPauseWork.store(false); 42 | } 43 | } 44 | void EndWork() 45 | { 46 | if (!IfEndWork.load()) { 47 | IfEndWork.store(true); 48 | } 49 | } 50 | //void RunEventOnGameThread(const FRunnabelCommonDataType& data) 51 | void RunEventOnGameThread(const TArray& intArray, const TArray& floatArray, const TArray& StringArray) 52 | { 53 | AsyncTask(ENamedThreads::GameThread, [=] { 54 | //AsyncFuncCallerOption.GameThreadEvent.ExecuteIfBound(data); 55 | AsyncFuncCallerOption.GameThreadEvent.ExecuteIfBound(intArray, floatArray, StringArray); 56 | }); 57 | } 58 | void RunCiticalEvent(); 59 | private: 60 | FRunnableThreadOption AsyncFuncCallerOption; 61 | UAsyncLoopEventManager* Manager; 62 | }; 63 | 64 | --------------------------------------------------------------------------------