From 52115a496245256f27e8095e578b1783ab63d6c6 Mon Sep 17 00:00:00 2001 From: Moon Bus Studio <131509330+moonbusstudio@users.noreply.github.com> Date: Wed, 8 Jan 2025 21:14:41 -0600 Subject: [PATCH 1/2] Fix null reference in the editor Check validity of TargetScriptArray[0] before dereferencing it in FLGUICanvasCustomization::GetDrawcallInfo. Also check world. --- .../LGUICanvasCustomization.cpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/Source/LGUIEditor/Private/DetailCustomization/LGUICanvasCustomization.cpp b/Source/LGUIEditor/Private/DetailCustomization/LGUICanvasCustomization.cpp index 87a2e2300..097b1e768 100644 --- a/Source/LGUIEditor/Private/DetailCustomization/LGUICanvasCustomization.cpp +++ b/Source/LGUIEditor/Private/DetailCustomization/LGUICanvasCustomization.cpp @@ -493,26 +493,31 @@ FText FLGUICanvasCustomization::GetSortOrderInfo(TWeakObjectPtr Tar FText FLGUICanvasCustomization::GetDrawcallInfo()const { - auto LGUIManager = ULGUIManagerWorldSubsystem::GetInstance(TargetScriptArray[0]->GetWorld()); - if (TargetScriptArray.Num() > 0 && TargetScriptArray[0].IsValid() && LGUIManager) + if (TargetScriptArray.Num() > 0 && TargetScriptArray[0].IsValid()) { - auto& allCanvas = LGUIManager->GetCanvasArray(TargetScriptArray[0]->GetRenderMode()); - int allDrawcallCount = 0; - for (auto& canvasItem : allCanvas) + if (auto World = TargetScriptArray[0]->GetWorld()) { - if (TargetScriptArray[0]->GetActualRenderMode() == ELGUIRenderMode::RenderTarget) + if (auto LGUIManager = ULGUIManagerWorldSubsystem::GetInstance(World)) { - if (TargetScriptArray[0]->renderTarget == canvasItem->renderTarget && IsValid(canvasItem->renderTarget)) + auto& allCanvas = LGUIManager->GetCanvasArray(TargetScriptArray[0]->GetRenderMode()); + int allDrawcallCount = 0; + for (auto& canvasItem : allCanvas) { - allDrawcallCount += canvasItem->GetDrawcallCount(); + if (TargetScriptArray[0]->GetActualRenderMode() == ELGUIRenderMode::RenderTarget) + { + if (TargetScriptArray[0]->renderTarget == canvasItem->renderTarget && IsValid(canvasItem->renderTarget)) + { + allDrawcallCount += canvasItem->GetDrawcallCount(); + } + } + else + { + allDrawcallCount += canvasItem->GetDrawcallCount(); + } } - } - else - { - allDrawcallCount += canvasItem->GetDrawcallCount(); + return FText::FromString(FString::Printf(TEXT("%d/%d"), TargetScriptArray[0]->GetDrawcallCount(), allDrawcallCount)); } } - return FText::FromString(FString::Printf(TEXT("%d/%d"), TargetScriptArray[0]->GetDrawcallCount(), allDrawcallCount)); } return FText::FromString(FString::Printf(TEXT("0/0"))); } From 9d323551623cab8fc33bff70bedfb30b68efb20f Mon Sep 17 00:00:00 2001 From: Moon Bus Studio <131509330+moonbusstudio@users.noreply.github.com> Date: Wed, 8 Jan 2025 21:21:02 -0600 Subject: [PATCH 2/2] Fix Tickable Subsystem ensure firing when exiting the editor Fix the following ensure firing when exiting the editor: Ensure condition failed: !bInitialized [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Subsystems\WorldSubsystem.cpp] [Line: 115] Tickable subsystem LGUIManagerWorldSubsystem None.LGUIPrefabManagerObject_0:LGUI_PreviewWorldForPrefabPackage_0.None was destroyed while still initialized! Check for missing Super call Don't create the preview world for prefab package from calls to GetPreviewWorldForPrefabPackage that are just checking UWorld equality in order to skip the preview world. Also don't create the FLGUIObjectCreateDeleteListener, since it has no purpose with ULGUIPrefabHelperObject::OnComponentCreateDelete disabled (not related to the ensure). Also don't override ULGUIPrefabWorldSubsystem::Initialize and ULGUIPrefabWorldSubsystem::Deinitialize without calling Super (also not related to the ensure, but seems unwise). --- .../LGUI/Private/Core/LGUILifeCycleBehaviour.cpp | 2 +- .../PrefabSystem/ActorSerializer7_Deserialize.cpp | 2 +- .../PrefabSystem/ActorSerializer8_Deserialize.cpp | 2 +- .../Private/PrefabSystem/LGUIPrefabManager.cpp | 14 +++++++++++++- .../LGUI/Public/PrefabSystem/LGUIPrefabManager.h | 4 +--- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Source/LGUI/Private/Core/LGUILifeCycleBehaviour.cpp b/Source/LGUI/Private/Core/LGUILifeCycleBehaviour.cpp index 566364aeb..522c04797 100644 --- a/Source/LGUI/Private/Core/LGUILifeCycleBehaviour.cpp +++ b/Source/LGUI/Private/Core/LGUILifeCycleBehaviour.cpp @@ -76,7 +76,7 @@ void ULGUILifeCycleBehaviour::OnRegister() #if WITH_EDITOR if (GetWorld() && !GetWorld()->IsGameWorld()) { - if (GetWorld() != ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage())//skip preview world + if (GetWorld() != ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage(false))//skip preview world { //Only allow Editor world, skip EditorPreview (Thumbnail) world if (GetWorld()->WorldType == EWorldType::Editor) diff --git a/Source/LGUI/Private/PrefabSystem/ActorSerializer7_Deserialize.cpp b/Source/LGUI/Private/PrefabSystem/ActorSerializer7_Deserialize.cpp index d4f246c07..bfbd1897e 100644 --- a/Source/LGUI/Private/PrefabSystem/ActorSerializer7_Deserialize.cpp +++ b/Source/LGUI/Private/PrefabSystem/ActorSerializer7_Deserialize.cpp @@ -271,7 +271,7 @@ namespace LGUIPrefabSystem7 if (!ParentComp) { #if WITH_EDITOR - if (TargetWorld != ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage())//skip preview world, only show this in PrefabEditor or LevelEditor + if (TargetWorld != ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage(false))//skip preview world, only show this in PrefabEditor or LevelEditor { auto MissingParentMsg = FText::Format(LOCTEXT("MissingParentMsg", "Prefab '{0}' fail to find parent for component '{1}.{2}', do you delete it? The component will attach to root") , FText::FromString(PrefabAssetPath), FText::FromString(SceneComp->GetOwner()->GetActorLabel()), FText::FromString(SceneComp->GetName())); diff --git a/Source/LGUI/Private/PrefabSystem/ActorSerializer8_Deserialize.cpp b/Source/LGUI/Private/PrefabSystem/ActorSerializer8_Deserialize.cpp index 94be399ef..768547ca6 100644 --- a/Source/LGUI/Private/PrefabSystem/ActorSerializer8_Deserialize.cpp +++ b/Source/LGUI/Private/PrefabSystem/ActorSerializer8_Deserialize.cpp @@ -268,7 +268,7 @@ namespace LGUIPrefabSystem8 if (!ParentComp) { #if WITH_EDITOR - if (TargetWorld != ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage())//skip preview world, only show this in PrefabEditor or LevelEditor + if (TargetWorld != ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage(false))//skip preview world, only show this in PrefabEditor or LevelEditor { auto MissingParentMsg = FText::Format(LOCTEXT("MissingParentMsg", "Prefab '{0}' fail to find parent for component '{1}.{2}', do you delete it? The component will attach to root") , FText::FromString(PrefabAssetPath), FText::FromString(SceneComp->GetOwner()->GetActorLabel()), FText::FromString(SceneComp->GetName())); diff --git a/Source/LGUI/Private/PrefabSystem/LGUIPrefabManager.cpp b/Source/LGUI/Private/PrefabSystem/LGUIPrefabManager.cpp index 373683cb6..fd8357a11 100644 --- a/Source/LGUI/Private/PrefabSystem/LGUIPrefabManager.cpp +++ b/Source/LGUI/Private/PrefabSystem/LGUIPrefabManager.cpp @@ -210,7 +210,9 @@ bool ULGUIPrefabManagerObject::InitCheck() Instance->OnBlueprintPreCompileDelegateHandle = GEditor->OnBlueprintPreCompile().AddUObject(Instance, &ULGUIPrefabManagerObject::OnBlueprintPreCompile); Instance->OnBlueprintCompiledDelegateHandle = GEditor->OnBlueprintCompiled().AddUObject(Instance, &ULGUIPrefabManagerObject::OnBlueprintCompiled); } +#if 0 // only used for ULGUIPrefabHelperObject::OnComponentCreateDelete but that function is disabled, so this listener doesn't need to be created Instance->ObjectCreateDeleteListener = new FLGUIObjectCreateDeleteListener(Instance); +#endif } return true; } @@ -256,8 +258,18 @@ void ULGUIPrefabManagerObject::OnPackageReloaded(EPackageReloadPhase Phase, FPac } } -UWorld* ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage() +UWorld* ULGUIPrefabManagerObject::GetPreviewWorldForPrefabPackage(bool bCreate) { + if (Instance && Instance->PreviewWorldForPrefabPackage) + { + return Instance->PreviewWorldForPrefabPackage; + } + + if (!bCreate) + { + return nullptr; + } + InitCheck(); auto& PreviewWorldForPrefabPackage = Instance->PreviewWorldForPrefabPackage; if (PreviewWorldForPrefabPackage == nullptr) diff --git a/Source/LGUI/Public/PrefabSystem/LGUIPrefabManager.h b/Source/LGUI/Public/PrefabSystem/LGUIPrefabManager.h index 08aa25ac9..cd674ece3 100644 --- a/Source/LGUI/Public/PrefabSystem/LGUIPrefabManager.h +++ b/Source/LGUI/Public/PrefabSystem/LGUIPrefabManager.h @@ -57,7 +57,7 @@ class LGUI_API ULGUIPrefabManagerObject :public UObject, public FTickableGameObj static ULGUIPrefabManagerObject* GetInstance(bool CreateIfNotValid = false); static bool IsSelected(AActor* InObject); static bool AnySelectedIsChildOf(AActor* InObject); - static UWorld* GetPreviewWorldForPrefabPackage(); + static UWorld* GetPreviewWorldForPrefabPackage(bool bCreate = true); static bool GetIsBlueprintCompiling(); static bool GetIsProcessingDelete(); private: @@ -111,8 +111,6 @@ class LGUI_API ULGUIPrefabWorldSubsystem : public UWorldSubsystem GENERATED_BODY() public: virtual bool ShouldCreateSubsystem(UObject* Outer) const override { return true; } - virtual void Initialize(FSubsystemCollectionBase& Collection)override {}; - virtual void Deinitialize()override {}; static ULGUIPrefabWorldSubsystem* GetInstance(UWorld* World); DECLARE_EVENT_OneParam(ULGUIPrefabWorldSubsystem, FDeserializeSession, const FGuid&);