Fix shutdown crash that happens because a widget is destroyed and isnt removed from an invalidation root because the invalidation root been disabled from using the fast path

#ROBOMERGE-SOURCE: CL 7305300 via CL 7305301 via CL 7310315
#ROBOMERGE-BOT: (v371-7306989)

[CL 7317160 by matt kuhlenschmidt in Main branch]
This commit is contained in:
matt kuhlenschmidt
2019-07-15 21:08:31 -04:00
parent fe1b3f61a3
commit 0edbd2bdbf
4 changed files with 26 additions and 18 deletions

View File

@@ -56,6 +56,8 @@ FSlateInvalidationRoot::~FSlateInvalidationRoot()
{
delete CachedElementData;
}
CachedElementData = nullptr;
}
void FSlateInvalidationRoot::AddReferencedObjects(FReferenceCollector& Collector)
@@ -238,6 +240,27 @@ FSlateInvalidationResult FSlateInvalidationRoot::PaintInvalidationRoot(const FSl
return Result;
}
void FSlateInvalidationRoot::OnWidgetDestroyed(const SWidget* Widget)
{
InvalidateChildOrder();
// We need the index even if we've invalidated this root. We need to clear out its proxy regardless
const bool bEvenIfInvalid = true;
const int32 ProxyIndex = Widget->FastPathProxyHandle.GetIndex(bEvenIfInvalid);
if (FastWidgetPathList.IsValidIndex(ProxyIndex) && FastWidgetPathList[ProxyIndex].Widget == Widget)
{
FastWidgetPathList[ProxyIndex].Widget = nullptr;
}
if (Widget->PersistentState.CachedElementListNode)
{
CachedElementData->RemoveCache(Widget->PersistentState.CachedElementListNode);
}
Widget->PersistentState.CachedElementListNode = nullptr;
}
bool FSlateInvalidationRoot::PaintFastPath(const FSlateInvalidationContext& Context)
{
SCOPED_NAMED_EVENT(SWidget_FastPathUpdate, FColor::Green);

View File

@@ -181,25 +181,9 @@ SWidget::~SWidget()
FSlateApplicationBase::Get().UnRegisterActiveTimer(ActiveTimerHandle);
}
if (FastPathProxyHandle.IsValid())
{
FWidgetProxy& Proxy = FastPathProxyHandle.GetProxy();
Proxy.Widget = nullptr;
}
else
{
ensure(FastPathProxyHandle.GetIndex() == INDEX_NONE);
}
if (FSlateInvalidationRoot* Root = FastPathProxyHandle.GetInvalidationRoot())
{
Root->InvalidateChildOrder();
if (PersistentState.CachedElementListNode)
{
Root->GetCachedElements().RemoveCache(PersistentState.CachedElementListNode);
}
Root->OnWidgetDestroyed(this);
}
// Reset handle

View File

@@ -82,6 +82,7 @@ public:
SLATECORE_API FSlateInvalidationResult PaintInvalidationRoot(const FSlateInvalidationContext& Context);
void OnWidgetDestroyed(const SWidget* Widget);
protected:
virtual int32 PaintSlowPath(const FSlateInvalidationContext& Context) = 0;

View File

@@ -204,7 +204,7 @@ public:
FWidgetProxy& GetProxy();
const FWidgetProxy& GetProxy() const;
int32 GetIndex() const { return IsValid() ? MyIndex : INDEX_NONE; }
int32 GetIndex(bool bEvenIfInvalid = false) const { return bEvenIfInvalid || IsValid() ? MyIndex : INDEX_NONE; }
/**
* Marks the widget as updated this frame