x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Office Holiday

Epic Games' offices will be on holiday from June 22nd to July 7th. During this period support will be limited. Our offices will reopen on Monday, July 8th. 

FSlateBrush object destroyed in SWidget by the garbadge collector

I have a widget that owns a const FSlateBrush* IconBrush;
I load the brush in the widget constructor

 void SKInventoryListItem::Construct(const FArguments& InArgs)
 {
     UID = InArgs._UID;
 ...
     IconBrush = CreateSlateBrush(UKObjectManager::GetPickupObjectTexture(UID), InArgs._ItemHeight, InArgs._ItemHeight);
 ....

When I need to paint it, the object is invalid.

 int32 SKInventoryListItem::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
 {
     FSlateRect rect = MyClippingRect;
     FVector2D size = rect.GetSize();
 
     LayerId = SButton::OnPaint(Args, AllottedGeometry, rect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
 
     // Draw icon box
     if (IconBrush)
     {


I try to set the IconBrush a UPROPERTY(), but it is still destroyed.

The ObjectManager class takes the texture from a UDataTable.

 UTexture2D* UKObjectManager::GetPickupObjectTexture(FString UID)
 {
     if (ObjectLookupTable)
     {
         const FKObjectDefinitionStruct* Data = ObjectLookupTable->FindRow<FKObjectDefinitionStruct>(*UID, TEXT(""));
         if (Data)
         {
             if (Data->Icon.IsPending())
             {
                 UObject* Asset = Data->Icon.ToStringReference().TryLoad();
                 if (Asset == nullptr)
                 {
                     UE_LOG(LogKSGM, Log, TEXT("UKObjectManager::GetPickupObjectTexture: Still couldn't load Data->Icon"));
                 }
             }
             UTexture2D* obj = Data->Icon.Get();
             return obj;
         }
     }
     // Not found, return the unknown object texture
     return UKObjectManager::GetPickupObjectUnknownTexture();
 }


I've also tried to make a new object returning from the UKObjectManager::GetPickupObject()

 IconBrush = CreateSlateBrush(NewObject<UTexture2D>(UKObjectManager::GetPickupObjectTexture(UID)), InArgs._ItemHeight, InArgs._ItemHeight);

 inline FSlateBrush* CreateSlateBrush(UTexture2D* Texture, const float Width, const float Height, ESlateBrushDrawType::Type ImageType = ESlateBrushDrawType::Image)
 {
     FSlateBrush* ImageIconBrush = new FSlateBrush();
     ImageIconBrush->SetResourceObject(Texture);
     ImageIconBrush->ImageSize.X = Width;
     ImageIconBrush->ImageSize.Y = Height;
     ImageIconBrush->DrawAs = ImageType;
     return ImageIconBrush;
 
 }

But no way, the object in the IconBrush becomes invalid.

What am I doing wrong ?

Txs for your help.
D.

Product Version: UE 4.10
Tags:
more ▼

asked Feb 24 '16 at 06:58 AM in C++ Programming

avatar image

domzorg
714 49 56 126

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Slate widgets aren't UObject types, so aren't part of the GC hierarchy (given this fact, I'm unsure how you managed to make your IconBrush a UPROPERTY without UHT complaining).

The simplest way to resolve this is to derive from FGCObject and override AddReferencedObjects to reference any UObject instances that you need to keep alive. FGCObject is a special class that allows non-UObject types to work with the GC. Note that you'll need to add a reference to the ResourceObject within the FSlateBrush, as FReferenceCollector doesn't understand structs - you can use FSlateBrush::GetResourceObject to get at the object.

more ▼

answered Feb 24 '16 at 02:07 PM

avatar image

Jamie Dale STAFF
7.5k 176 66 304

avatar image domzorg Feb 25 '16 at 06:34 AM

I also have no idea why the UHT didn't complain. The object destroyed is the one coming from the function UTexture2D* UKObjectManager::GetPickupObjectTexture(FString UID). This is a static class helper that lookup at records loaded from a DataTable.

What I did to avoid the problem is to AddToRoot the returned object.

 UTexture2D* UKObjectManager::GetPickupObjectTexture(FString UID)
 {
     if (ObjectLookupTable)
     {
         const FKObjectDefinitionStruct* Data = ObjectLookupTable->FindRow<FKObjectDefinitionStruct>(*UID, TEXT(""));
         if (Data)
         {
             if (Data->Icon.IsPending())
             {
                 UObject* Asset = Data->Icon.ToStringReference().TryLoad();
                 if (Asset == nullptr)
                 {
                     UE_LOG(LogKSGM, Log, TEXT("UKObjectManager::GetPickupObjectTexture: Still couldn't load Data->Icon"));
                 }
             }
             // Add the icon to root to avoid the element from being destroyed by the GC
             if (Data->Icon.IsValid() && !Data->Icon->IsRooted())
                 Data->Icon->AddToRoot();
             return Data->Icon.Get();
         }
     }
     // Not found, return the unknown object texture
     return UKObjectManager::GetPickupObjectUnknownTexture();
 }
 

But I don't think it is very clean since the object wont never be destroyed.

I will check how works the FGCObject.

D.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question