// Copyright Epic Games, Inc. All Rights Reserved. #include "Actions/AsyncAction_PushContentToLayerForPlayer.h" #include "CommonActivatableWidget.h" #include "Engine/Engine.h" #include "Engine/StreamableManager.h" #include "Engine/World.h" #include "GameFramework/PlayerController.h" #include "HAL/Platform.h" #include "Logging/LogVerbosity.h" #include "PrimaryGameLayout.h" #include "Templates/Casts.h" #include "UObject/Stack.h" #include "UObject/WeakObjectPtr.h" #include "Widgets/CommonActivatableWidgetContainer.h" UAsyncAction_PushContentToLayerForPlayer::UAsyncAction_PushContentToLayerForPlayer(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } UAsyncAction_PushContentToLayerForPlayer* UAsyncAction_PushContentToLayerForPlayer::PushContentToLayerForPlayer(APlayerController* InOwningPlayer, TSoftClassPtr InWidgetClass, FGameplayTag InLayerName, bool bSuspendInputUntilComplete) { if (InWidgetClass.IsNull()) { FFrame::KismetExecutionMessage(TEXT("PushContentToLayerForPlayer was passed a null WidgetClass"), ELogVerbosity::Error); return nullptr; } if (UWorld* World = GEngine->GetWorldFromContextObject(InOwningPlayer, EGetWorldErrorMode::LogAndReturnNull)) { UAsyncAction_PushContentToLayerForPlayer* Action = NewObject(); Action->WidgetClass = InWidgetClass; Action->OwningPlayerPtr = InOwningPlayer; Action->LayerName = InLayerName; Action->bSuspendInputUntilComplete = bSuspendInputUntilComplete; Action->RegisterWithGameInstance(World); return Action; } return nullptr; } void UAsyncAction_PushContentToLayerForPlayer::Cancel() { Super::Cancel(); if (StreamingHandle.IsValid()) { StreamingHandle->CancelHandle(); StreamingHandle.Reset(); } } void UAsyncAction_PushContentToLayerForPlayer::Activate() { if (UPrimaryGameLayout* RootLayout = UPrimaryGameLayout::GetPrimaryGameLayout(OwningPlayerPtr.Get())) { TWeakObjectPtr WeakThis = this; StreamingHandle = RootLayout->PushWidgetToLayerStackAsync(LayerName, bSuspendInputUntilComplete, WidgetClass, [this, WeakThis](EAsyncWidgetLayerState State, UCommonActivatableWidget* Widget) { if (WeakThis.IsValid()) { switch (State) { case EAsyncWidgetLayerState::Initialize: BeforePush.Broadcast(Widget); break; case EAsyncWidgetLayerState::AfterPush: AfterPush.Broadcast(Widget); SetReadyToDestroy(); break; case EAsyncWidgetLayerState::Canceled: SetReadyToDestroy(); break; } } SetReadyToDestroy(); }); } else { SetReadyToDestroy(); } }