RealtimeStyleTransferRuntime/Plugins/CommonGame/Source/Private/Actions/AsyncAction_CreateWidgetAsy...

101 lines
3.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Actions/AsyncAction_CreateWidgetAsync.h"
#include "Blueprint/WidgetBlueprintLibrary.h"
#include "CommonUIExtensions.h"
#include "Engine/AssetManager.h"
#include "Engine/Engine.h"
#include "Engine/GameInstance.h"
#include "Engine/StreamableManager.h"
#include "Engine/World.h"
#include "GameFramework/PlayerController.h"
#include "HAL/Platform.h"
#include "Logging/LogVerbosity.h"
#include "Templates/SubclassOf.h"
#include "UObject/Stack.h"
#include "UObject/UnrealNames.h"
#include "UObject/WeakObjectPtr.h"
class UUserWidget;
static const FName InputFilterReason_Template = FName(TEXT("CreatingWidgetAsync"));
UAsyncAction_CreateWidgetAsync::UAsyncAction_CreateWidgetAsync(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, bSuspendInputUntilComplete(true)
{
}
UAsyncAction_CreateWidgetAsync* UAsyncAction_CreateWidgetAsync::CreateWidgetAsync(UObject* InWorldContextObject, TSoftClassPtr<UUserWidget> InUserWidgetSoftClass, APlayerController* InOwningPlayer, bool bSuspendInputUntilComplete)
{
if (InUserWidgetSoftClass.IsNull())
{
FFrame::KismetExecutionMessage(TEXT("CreateWidgetAsync was passed a null UserWidgetSoftClass"), ELogVerbosity::Error);
return nullptr;
}
UWorld* World = GEngine->GetWorldFromContextObject(InWorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
UAsyncAction_CreateWidgetAsync* Action = NewObject<UAsyncAction_CreateWidgetAsync>();
Action->UserWidgetSoftClass = InUserWidgetSoftClass;
Action->OwningPlayer = InOwningPlayer;
Action->World = World;
Action->GameInstance = World->GetGameInstance();
Action->bSuspendInputUntilComplete = bSuspendInputUntilComplete;
Action->RegisterWithGameInstance(World);
return Action;
}
void UAsyncAction_CreateWidgetAsync::Activate()
{
SuspendInputToken = bSuspendInputUntilComplete ? UCommonUIExtensions::SuspendInputForPlayer(OwningPlayer.Get(), InputFilterReason_Template) : NAME_None;
TWeakObjectPtr<UAsyncAction_CreateWidgetAsync> LocalWeakThis(this);
StreamingHandle = UAssetManager::Get().GetStreamableManager().RequestAsyncLoad(
UserWidgetSoftClass.ToSoftObjectPath(),
FStreamableDelegate::CreateUObject(this, &ThisClass::OnWidgetLoaded),
FStreamableManager::AsyncLoadHighPriority
);
// Setup a cancel delegate so that we can resume input if this handler is canceled.
StreamingHandle->BindCancelDelegate(FStreamableDelegate::CreateWeakLambda(this,
[this]()
{
UCommonUIExtensions::ResumeInputForPlayer(OwningPlayer.Get(), SuspendInputToken);
})
);
}
void UAsyncAction_CreateWidgetAsync::Cancel()
{
Super::Cancel();
if (StreamingHandle.IsValid())
{
StreamingHandle->CancelHandle();
StreamingHandle.Reset();
}
}
void UAsyncAction_CreateWidgetAsync::OnWidgetLoaded()
{
if (bSuspendInputUntilComplete)
{
UCommonUIExtensions::ResumeInputForPlayer(OwningPlayer.Get(), SuspendInputToken);
}
// If the load as successful, create it, otherwise don't complete this.
TSubclassOf<UUserWidget> UserWidgetClass = UserWidgetSoftClass.Get();
if (UserWidgetClass)
{
UUserWidget* UserWidget = UWidgetBlueprintLibrary::Create(World.Get(), UserWidgetClass, OwningPlayer.Get());
OnComplete.Broadcast(UserWidget);
}
StreamingHandle.Reset();
SetReadyToDestroy();
}