Why can a member variable be empty in a blueprint event ?

Hi community

When using the “Event On List Item Object Set”, the self referenced variable is empty whilst the reference to the same object given by the event does have the variable set. As you can see in the screenshot below, the variable “Text” is set with a custom “Set Text” event (see first 4 debug prints), but cannot be used directly without using the additional “Cast To …” call on the given “List Item Object” (see last 8 debug prints).

(see screenshot in reply)

Please, note that I print the references and they “look” the same, as I have no idea how to print the memory addresses (aka pointers) yet. It might be different objects deep down, but I do not understand why and wouldn’t that be pure memory overhead/waste ?

As a (native) C++ developer, I set my personal goal to learn Blueprint scripting. However, I got stuck with understanding how to interpret the events in comparison to native Object-Oriented logic.

Full story :
In a simplified project started from 3rd person example, I try to build a simple text list in the HUD. On “Event Begin Play” of the BP_ThirdPersonCharacter, I construct the HUD and add it to the Viewport. The HUD has just 1 List View in a canvas. The constructor of the HUD will create 4 List Items, Set Text of each of them and Add Items to the List View (see screenshot below). A List Item just contains 1 Text Block and has “User Object List Entry” Interface Implemented. The custom Set Text event cannot SetText(Text) of the Text Block as it results in a None object reference (I guess the UI element is not created yet ? Or is this the same issue as the main question here ?). Therefor, I make use of a variable named “Text” which I set, to get later on when it is added to the List View by Event On List Item Object Set.
However, this variable (I would assume a member variable in OOP) is empty in the next event (I would assume like a member function in OOP) as you can see in Sequence 0 in the screenshot above. And to quote Ryan Reynolds meme : but why ?
Nevertheless, the reference to the list item casted to itself does have this variable set with the correct variable as you can see in Sequence 1 (as shown in a tutorial). This raises a lot of questions about the used memory and references. Can someone give me some clarification why this is or am I doing something very bad (like undefined behavior) ?

On a side note, who is keeping track of my constructed memory and who is responsible to clear these ? I only see the typical “constructs” in blueprint, but what about memory management and their “delete” or “free” calls ?

Thank you very much for taking your time to explain me some of the magic :slight_smile:

Sorry, I accidentally posted the same screenshot twice :sweat_smile:
This should have been the first screenshot, but I was unable to edit the post.

image

Can you give a screenshot on how you call that event and also what type of the variable input pin “ListItemObject”.

Casting in bp can be used to check a if it of x class and can also convert one class to another. Like a class of Paper2d can be converted to class of Character such that you can obtain it CharacterMovement for example.

Memory is managed by the garbage collector, each 60s(default project setting) the gc will check if a reference is used or not. For a UI/Widget, if it not stored in a variable/binding or not in viewport, GC will remove it from memory.

2 Likes

OP is using the List View widget which provides a special interface. It’s called when the list view generates entries from data objects.


When using the “Event On List Item Object Set”, the self referenced variable is empty whilst the reference to the same object given by the event does have the variable set.

This is normal and fine, Self is the Widget, your data is in the List View Object. See if this clarifies things a bit.

  • there is a List View widget that holds a bunch of Objects that have your data
  • when the List View instantiates an entry widget, we must pull the data out of the Object via the interface and apply it to widget fields (here, text)
  • in order to get to the data, you must Cast to the correct type to get access (or use another interface which I shamelessly have done in the past… :innocent: )

Also, consider using OnInitialise instead of Construct to add Items. You can also expose variables on the object:

image

So you can more easily pipe the data in:

image

Not really important, but convenient!


On a side note, who is keeping track of my constructed memory and who is responsible to clear these ? I only see the typical “constructs” in blueprint, but what about memory management and their “delete” or “free” calls ?

As mentioned in the previous post, there is no explicit way to release widgets from memory in BPs. The Garbage Collection will take care of it automatically, you can also force it. If you fully dereference the widget that holds onto the ListView, the object (and entry widgets, too!) will be destroyed eventually. It may take a minute since the GC runs a schedule and batch-removes stuff.


And one more thing, this setup does not make much sense from the List View’s use case point of view:

To work with a list view you need:

  • objects with data
  • user widget entries to visualise objects’ data
  • a user widget that holds the list view who then generates the entries

Here’s a minimalistic setup.

2 Likes

@Arodi007 and @Everynone
Million thanks for the clear and precise explanation !
You not only answered my direct and additional question, but also some additional questions I had about the constructor (as if you went through my browsing history).
You have really made my day with putting in all your effort and time to even suggest how to properly use the list view.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.