RealtimeStyleTransferRuntime/Source/LyraGame/GameFeatures/GameFeatureAction_AddWidget...

172 lines
5.6 KiB
C++
Raw Normal View History

2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "GameFeatureAction_AddWidget.h"
#include "Components/GameFrameworkComponentManager.h"
#include "GameFeaturesSubsystemSettings.h"
#include "Engine/AssetManager.h"
#include "CommonUIExtensions.h"
#include "Engine/Engine.h"
#define LOCTEXT_NAMESPACE "LyraGameFeatures"
//////////////////////////////////////////////////////////////////////
// UGameFeatureAction_AddWidgets
void UGameFeatureAction_AddWidgets::OnGameFeatureDeactivating(FGameFeatureDeactivatingContext& Context)
{
Super::OnGameFeatureDeactivating(Context);
FPerContextData* ActiveData = ContextData.Find(Context);
if ensure(ActiveData)
{
Reset(*ActiveData);
}
}
#if WITH_EDITORONLY_DATA
void UGameFeatureAction_AddWidgets::AddAdditionalAssetBundleData(FAssetBundleData& AssetBundleData)
{
for (const FLyraHUDElementEntry& Entry : Widgets)
{
2022-09-13 07:18:28 +00:00
AssetBundleData.AddBundleAsset(UGameFeaturesSubsystemSettings::LoadStateClient, Entry.WidgetClass.ToSoftObjectPath().GetAssetPath());
2022-05-23 18:41:30 +00:00
}
}
#endif
#if WITH_EDITOR
EDataValidationResult UGameFeatureAction_AddWidgets::IsDataValid(TArray<FText>& ValidationErrors)
{
EDataValidationResult Result = CombineDataValidationResults(Super::IsDataValid(ValidationErrors), EDataValidationResult::Valid);
{
int32 EntryIndex = 0;
for (const FLyraHUDLayoutRequest& Entry : Layout)
{
if (Entry.LayoutClass.IsNull())
{
Result = EDataValidationResult::Invalid;
ValidationErrors.Add(FText::Format(LOCTEXT("LayoutHasNullClass", "Null WidgetClass at index {0} in Layout"), FText::AsNumber(EntryIndex)));
}
if (!Entry.LayerID.IsValid())
{
Result = EDataValidationResult::Invalid;
ValidationErrors.Add(FText::Format(LOCTEXT("LayoutHasNoTag", "LayerID is not set at index {0} in Widgets"), FText::AsNumber(EntryIndex)));
}
++EntryIndex;
}
}
{
int32 EntryIndex = 0;
for (const FLyraHUDElementEntry& Entry : Widgets)
{
if (Entry.WidgetClass.IsNull())
{
Result = EDataValidationResult::Invalid;
ValidationErrors.Add(FText::Format(LOCTEXT("EntryHasNullClass", "Null WidgetClass at index {0} in Widgets"), FText::AsNumber(EntryIndex)));
}
if (!Entry.SlotID.IsValid())
{
Result = EDataValidationResult::Invalid;
ValidationErrors.Add(FText::Format(LOCTEXT("EntryHasNoTag", "SlotID is not set at index {0} in Widgets"), FText::AsNumber(EntryIndex)));
}
++EntryIndex;
}
}
return Result;
}
#endif
void UGameFeatureAction_AddWidgets::AddToWorld(const FWorldContext& WorldContext, const FGameFeatureStateChangeContext& ChangeContext)
{
UWorld* World = WorldContext.World();
UGameInstance* GameInstance = WorldContext.OwningGameInstance;
FPerContextData& ActiveData = ContextData.FindOrAdd(ChangeContext);
if ((GameInstance != nullptr) && (World != nullptr) && World->IsGameWorld())
{
if (UGameFrameworkComponentManager* ComponentManager = UGameInstance::GetSubsystem<UGameFrameworkComponentManager>(GameInstance))
{
TSoftClassPtr<AActor> HUDActorClass = ALyraHUD::StaticClass();
TSharedPtr<FComponentRequestHandle> ExtensionRequestHandle = ComponentManager->AddExtensionHandler(
HUDActorClass,
UGameFrameworkComponentManager::FExtensionHandlerDelegate::CreateUObject(this, &ThisClass::HandleActorExtension, ChangeContext));
ActiveData.ComponentRequests.Add(ExtensionRequestHandle);
}
}
}
void UGameFeatureAction_AddWidgets::Reset(FPerContextData& ActiveData)
{
ActiveData.ComponentRequests.Empty();
ActiveData.LayoutsAdded.Empty();
for (FUIExtensionHandle& Handle : ActiveData.ExtensionHandles)
{
Handle.Unregister();
}
ActiveData.ExtensionHandles.Reset();
}
void UGameFeatureAction_AddWidgets::HandleActorExtension(AActor* Actor, FName EventName, FGameFeatureStateChangeContext ChangeContext)
{
FPerContextData& ActiveData = ContextData.FindOrAdd(ChangeContext);
if ((EventName == UGameFrameworkComponentManager::NAME_ExtensionRemoved) || (EventName == UGameFrameworkComponentManager::NAME_ReceiverRemoved))
{
RemoveWidgets(Actor, ActiveData);
}
else if ((EventName == UGameFrameworkComponentManager::NAME_ExtensionAdded) || (EventName == UGameFrameworkComponentManager::NAME_GameActorReady))
{
AddWidgets(Actor, ActiveData);
}
}
void UGameFeatureAction_AddWidgets::AddWidgets(AActor* Actor, FPerContextData& ActiveData)
{
ALyraHUD* HUD = CastChecked<ALyraHUD>(Actor);
if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(HUD->GetOwningPlayerController()->Player))
{
for (const FLyraHUDLayoutRequest& Entry : Layout)
{
if (TSubclassOf<UCommonActivatableWidget> ConcreteWidgetClass = Entry.LayoutClass.Get())
{
ActiveData.LayoutsAdded.Add(UCommonUIExtensions::PushContentToLayer_ForPlayer(LocalPlayer, Entry.LayerID, ConcreteWidgetClass));
}
}
UUIExtensionSubsystem* ExtensionSubsystem = HUD->GetWorld()->GetSubsystem<UUIExtensionSubsystem>();
for (const FLyraHUDElementEntry& Entry : Widgets)
{
ActiveData.ExtensionHandles.Add(ExtensionSubsystem->RegisterExtensionAsWidgetForContext(Entry.SlotID, LocalPlayer, Entry.WidgetClass.Get(), -1));
}
}
}
void UGameFeatureAction_AddWidgets::RemoveWidgets(AActor* Actor, FPerContextData& ActiveData)
{
ALyraHUD* HUD = CastChecked<ALyraHUD>(Actor);
for (TWeakObjectPtr<UCommonActivatableWidget>& AddedLayout : ActiveData.LayoutsAdded)
{
if (AddedLayout.IsValid())
{
AddedLayout->DeactivateWidget();
}
}
ActiveData.LayoutsAdded.Reset();
for (FUIExtensionHandle& Handle : ActiveData.ExtensionHandles)
{
Handle.Unregister();
}
ActiveData.ExtensionHandles.Reset();
}
#undef LOCTEXT_NAMESPACE