diff --git a/CHANGES.md b/CHANGES.md index 5f2d6ec..e60e0fe 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ Change History Version: 1.22 (2021/04) - Fixed potential for initialization fiasco when using delegates container. - Fixed bug in code protecting redirecting handles from self-referencing. +- Fixed cached resource handles getting invalid after reloading texture resources. Version: 1.21 (2020/07-09) Improving stability diff --git a/Source/ImGui/Private/TextureManager.cpp b/Source/ImGui/Private/TextureManager.cpp index 0a334eb..aca56b7 100644 --- a/Source/ImGui/Private/TextureManager.cpp +++ b/Source/ImGui/Private/TextureManager.cpp @@ -125,7 +125,7 @@ FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* I // Create brush and resource handle for input texture. Brush.SetResourceObject(InTexture); - ResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush); + CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush); } FTextureManager::FTextureEntry::~FTextureEntry() @@ -142,7 +142,7 @@ FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextu Name = MoveTemp(Other.Name); Texture = MoveTemp(Other.Texture); Brush = MoveTemp(Other.Brush); - ResourceHandle = MoveTemp(Other.ResourceHandle); + CachedResourceHandle = MoveTemp(Other.CachedResourceHandle); // Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks // of ownership and mark it as empty/reusable. @@ -151,6 +151,15 @@ FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextu return *this; } +const FSlateResourceHandle& FTextureManager::FTextureEntry::GetResourceHandle() const +{ + if (!CachedResourceHandle.IsValid() && Brush.HasUObject()) + { + CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush); + } + return CachedResourceHandle; +} + void FTextureManager::FTextureEntry::Reset(bool bReleaseResources) { if (bReleaseResources) @@ -175,5 +184,5 @@ void FTextureManager::FTextureEntry::Reset(bool bReleaseResources) // Clean fields to make sure that we don't reference released or moved resources. Texture.Reset(); Brush = FSlateNoResource(); - ResourceHandle = FSlateResourceHandle(); + CachedResourceHandle = FSlateResourceHandle(); } diff --git a/Source/ImGui/Private/TextureManager.h b/Source/ImGui/Private/TextureManager.h index cb560a6..4456c79 100644 --- a/Source/ImGui/Private/TextureManager.h +++ b/Source/ImGui/Private/TextureManager.h @@ -41,7 +41,7 @@ public: // @returns The index of a texture with given name or INDEX_NONE if there is no such texture TextureIndex FindTextureIndex(const FName& Name) const { - return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.Name == Name; }); + return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.GetName() == Name; }); } // Get the name of a texture at given index. Returns NAME_None, if index is out of range. @@ -49,7 +49,7 @@ public: // @returns The name of a texture at given index or NAME_None if index is out of range. FName GetTextureName(TextureIndex Index) const { - return IsInRange(Index) ? TextureResources[Index].Name : NAME_None; + return IsInRange(Index) ? TextureResources[Index].GetName() : NAME_None; } // Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid @@ -59,7 +59,7 @@ public: // found at given index const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const { - return IsValidTexture(Index) ? TextureResources[Index].ResourceHandle : ErrorTexture.ResourceHandle; + return IsValidTexture(Index) ? TextureResources[Index].GetResourceHandle() : ErrorTexture.GetResourceHandle(); } // Create a texture from raw data. @@ -118,7 +118,7 @@ private: // Check whether index is in range and whether texture resources are valid (using NAME_None sentinel). FORCEINLINE bool IsValidTexture(TextureIndex Index) const { - return IsInRange(Index) && TextureResources[Index].Name != NAME_None; + return IsInRange(Index) && TextureResources[Index].GetName() != NAME_None; } // Entry for texture resources. Only supports explicit construction. @@ -137,14 +137,17 @@ private: // ... but we need move assignment to support reusing entries. FTextureEntry& operator=(FTextureEntry&& Other); - FName Name = NAME_None; - TWeakObjectPtr Texture; - FSlateBrush Brush; - FSlateResourceHandle ResourceHandle; + const FName& GetName() const { return Name; } + const FSlateResourceHandle& GetResourceHandle() const; private: void Reset(bool bReleaseResources); + + FName Name = NAME_None; + mutable FSlateResourceHandle CachedResourceHandle; + TWeakObjectPtr Texture; + FSlateBrush Brush; }; TArray TextureResources;