ScriptableTools: Improve deletion handling within the ScriptableTool Mode to prevent crashes when scriptable tool blueprints are deleted.

* Added checks to prevent deletion from happening on any tools or tool builders currently loaded by the mode.

* Added safety checks around groups to prevent weird behavior if null groups are introduced

* Added logging features for scriptable tools to describe failed deletion attempts

#rb semion.piskarev
#jira UE-221693

[CL 36419192 by nathan mitchell in 5.5 branch]
This commit is contained in:
nathan mitchell
2024-09-18 22:07:27 -04:00
parent c0785dbd30
commit b85bd0eac4
13 changed files with 124 additions and 22 deletions
@@ -211,7 +211,9 @@ public:
if (BlueprintObject->GeneratedClass->IsChildOf(UScriptableToolGroupTag::StaticClass()))
{
TSubclassOf<UScriptableToolGroupTag> TagSubclass{ BlueprintObject->GeneratedClass };
ModeSettings->ToolRegistrationFilters.Groups.Add(TagSubclass);
FScriptableToolGroupSet::FGroupSet Groups = ModeSettings->ToolRegistrationFilters.GetGroups();
Groups.Add(TagSubclass);
ModeSettings->ToolRegistrationFilters.SetGroups(Groups);
}
}
ModeSettings->PostEditChange();
@@ -251,7 +253,7 @@ public:
TArray<FText> GroupNames;
for (UClass* GroupClass : ModeSettings->ToolRegistrationFilters.Groups)
for (UClass* GroupClass : ModeSettings->ToolRegistrationFilters.GetGroups())
{
if (GroupClass)
{
@@ -264,19 +266,20 @@ public:
}
}
if (ModeSettings->ToolRegistrationFilters.Groups.Num() == 1)
if (GroupNames.Num() == 0)
{
return LOCTEXT("ScriptableToolsZeroGroupLabel", "Showing tools from no groups");
}
else if (GroupNames.Num() == 1)
{
ensure(GroupNames.IsValidIndex(0));
return FText::Format(LOCTEXT("ScriptableToolsOneGroupLabel", "Showing tools from {0}"), GroupNames[0]);
}
else if (ModeSettings->ToolRegistrationFilters.Groups.Num() == 2)
else if (GroupNames.Num() == 2)
{
ensure(GroupNames.IsValidIndex(1));
return FText::Format(LOCTEXT("ScriptableToolsTwoGroupLabel", "Showing tools from {0} and {1}"), GroupNames[0], GroupNames[1]);
}
else
{
ensure(GroupNames.IsValidIndex(1));
return FText::Format(LOCTEXT("ScriptableToolsManyGroupLabel", "Showing tools from {0}, {1} and more..."), GroupNames[0], GroupNames[1]);
}
}
@@ -13,12 +13,12 @@ UEditableScriptableToolGroupSet::UEditableScriptableToolGroupSet()
void UEditableScriptableToolGroupSet::SetGroups(const FScriptableToolGroupSet::FGroupSet& InGroups)
{
GroupSet.Groups = InGroups;
GroupSet.SetGroups(InGroups);
}
FScriptableToolGroupSet::FGroupSet& UEditableScriptableToolGroupSet::GetGroups()
{
return GroupSet.Groups;
return GroupSet.GetGroups();
}
FString UEditableScriptableToolGroupSet::GetGroupSetExportText()
@@ -168,7 +168,7 @@ FReply SScriptableToolGroupSetCombo::OnClearTagClicked(UClass* InGroup)
}
else if (StructPtr)
{
StructPtr->Groups = HelperGroupSet->GetGroups();
StructPtr->SetGroups(HelperGroupSet->GetGroups());
}
OnChanged.ExecuteIfBound();
@@ -217,7 +217,7 @@ void SScriptableToolGroupSetCombo::RefreshListView()
if(bValidData)
{
FScriptableToolGroupSet& GroupSet = *static_cast<FScriptableToolGroupSet*>(StructPointer);
FScriptableToolGroupSet::FGroupSet& Groups = GroupSet.Groups;
FScriptableToolGroupSet::FGroupSet Groups = GroupSet.GetGroups();
HelperGroupSet->SetGroups(Groups);
@@ -249,7 +249,7 @@ void SScriptableToolGroupSetPicker::PopulateCheckedTags()
if (bValidData)
{
FScriptableToolGroupSet& GroupSet = *static_cast<FScriptableToolGroupSet*>(StructPointer);
FScriptableToolGroupSet::FGroupSet& Groups = GroupSet.Groups;
FScriptableToolGroupSet::FGroupSet Groups = GroupSet.GetGroups();
HelperGroupSet->SetGroups(Groups);
@@ -324,7 +324,7 @@ void SScriptableToolGroupSetPicker::FlushHelperGroupSet() const
}
else if (StructPtr)
{
StructPtr->Groups = HelperGroupSet->GetGroups();
StructPtr->SetGroups(HelperGroupSet->GetGroups());
}
OnChanged.ExecuteIfBound();
@@ -29,6 +29,6 @@ public:
UPROPERTY(config, EditAnywhere, Category = "Scriptable Tools Mode|Tool Registration", meta = (EditCondition = "!bRegisterAllTools"))
FScriptableToolGroupSet ToolRegistrationFilters;
bool RegisterAllTools() const { return ToolRegistrationFilters.Groups.IsEmpty(); }
bool RegisterAllTools() const { return ToolRegistrationFilters.GetGroups().IsEmpty(); }
};