AttachableList
Last updated
Was this helpful?
Last updated
Was this helpful?
An AttachableList is a list which contains instances to . Instances of added to an AttachableList share a two-way relationship with the AttachableList by default. Common AttachableLists include the and classes.
While this article goes into extensive detail about two-way relationships, this paragraph provides a quick explanation of what it means. In short, a two-way relationship means that IAttachables (this includes such as , , and ) keep track of all that they are a part of. The reason that this relationship exists is so that objects can remove themselves from all that they are a part of automatically when removing them through the engine. Any "Remove" method offered by FlatRedBall managers will remove the argument object from all of its lists - at least for all -inheriting objects. A simple code example shows this functionality:
Remove the Sprite from the engine
Remove the Sprite from bullet list
Methods wich return AttachableLists usually fill them using AddOneWay. The assumption is that these lists will have a short lifespan.
Short-lifespan AttachableLists created outside of the engine should have elements added to them using one-way methods. Any AttachableList which has a lifespan of one frame or less should usually be populated using AddOneWay.
Using a foreach statement on an AttachableList will allocate memory. This is a very common gotcha when working with AttachableLists (and PositionedObjectLists). Consider the following to improve the performance of your application:
A two way relationship is a relationship between an object that implements the interface and a class that inherits from the AttachableList class. Normally when objects are added to lists, the list stores any number of objects, but the objects themselves are not aware of which lists they belong to. These are known as "one-way" relationships: the knowledge of membership only exists in the list object. A two-way relationship, on the other hand, is one where the list stores all of its contained objects, and all of the contained objects are aware of all of the lists they belong to. When an is added to an AttachableList, the following occurs:
The is added to the collection of items that the AttachableList stores.
The adds the AttachableList to its ListsBelongingTo list.
And similarly, when an is removed from an AttachableList, the following occurs:
The AttachableList is removed from the ListsBelongingTo.
The is removed from the AttachableList.
Two way relationships exist to eliminate scope problems when removing an IAttachable completely. The FlatRedBall Engine often uses AttachableLists internally to categorize Sprites. For example, Sprites which belong to the SpriteManager can be either automatically updated or manually updated. Each is stored in a different array. Similarly, it is common practice to create AttachableLists to organize objects by their behavior. Common examples include placing Polygons which represent triggers in a level in a or to organize player bullets and enemies in separate . A bullet and enemy example clearly shows the kind of problems which can occur in the absence of two-way relationships. When a bullet collides with an enemy, it should be completely removed from the game. Not only does it have to be removed from any internal (such as lists in the ), but also from the programmer-created list of bullets that it belongs to. In the absence of a two-way relationship, at least two calls would be required:
This is inconvenient at best. It also requires code to be written in pairs (or more if an object is part of more lists). While the previous example highlights inconveniences, there is another practical reason for having two-way relationships. Sometimes the code that creates a PositionedObject and the code that destroys a PositionedObject may exist in two different areas of your project. The code that destroys a PositionedObject may not have access to all of the PositionedObjectLists that a given PositionedObject is a part of. The automatic removal enabled by two-way relationships enables removal without having to track down all lists. The two-way relationships between and AttachableLists enables any method to remove objects from all lists both engine and user created through the use of globally-visible static managers such as the and . Simply calling Remove on an object's manager automatically removes it from all lists that it shares two-way relationships with. The following code creates a , adds it to the , adds it to a , then removes it from the . Next the is checked to see if it still has a reference to the . If it does, the application exits. Since it does not, your application will not exit.
can also be added to AttachableLists creating one-way relationships using the AddOneWay method. In a one-way relationship, the AttachableList knows about its contained , but the do not know about their list. This is similar to how normal Arrays and Lists work. Usually one way relationships are useful when the scope of an AttachableList is brief - usually one frame or non-Main method. There are two common situations in which one-way AttachableLists are used:
The reason for two-way relationships is to remove unused from all AttachableLists which reference them. However, if an AttachableList has a short lifespan, then it will likely fall out of scope before any that it references are removed. One reason to use one-way relationships for short-lifespan AttachableLists is to reduce the overhead of creating and managing two-way relationships. The Add method is slightly slower than AddOneWay as two-way relationships require two Add calls to internal List<> objects. Another reason is that additional references reduce the efficiency of the garbage collector. A third reason to avoid two-way relationships for short-lifespan AttachableLists is exemplified by the following code. First, consider what occurs when the following code is executed.
Now, consider the result of using AddOneWay instead of Add:
There are times when an AttachableList should be converted between a two-way and one-way AttachableList. One common scenario is when a one-way AttachableList returned from a method is going to be used for longer than one frame. In this example, all Sprites with the word "collision" in the first are added to the second. Since FindSpritesWithNameContaining returns a one-way , two-way relationships are created for all in the the second .
Similarly, all AttachableLists have a MakeOneWay method which makes the relationship with all contained one-way.
Did this article leave any questions unanswered? Post any question in our for a rapid response.