101 lines
3.3 KiB
C++
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();
|
|
}
|