Possible NodePool / NodeList bug?

71 views
Skip to first unread message

Drew Martin

unread,
Sep 22, 2014, 2:40:17 PM9/22/14
to ash-fr...@googlegroups.com
So correct me if I'm wrong on any of this, but to my knowledge, this is how Ash handles the removal of nodes:

If an Entity is removed or it loses one/many of its components, each ComponentMatchingFamily will attempt to removeIfMatch() on the Entity to remove it from its NodeList if it no longer meets the proper component requirements. If the Engine is updating - which it in most cases will be - it will cache() the node in the NodePool and then dispose() of all the nodes at the end of the update.

My issue lies in NodePool.cache().

internal function cache( node : Node ) : void
{
 node
.previous = cacheTail;
 cacheTail
= node;
}

Say for example I have an AlphabetSystem, and at the start of that system it sorts the NodeList based on an Alphabet component's place in the alphabet. Now all of the Nodes are sorted A-Z. Say later in the system, I either want to iterate through the NodeList A-Z OR Z-A. That would mean I either do:

for(var node:AlphabetNode = nodeList.head; node; node = node.next)
{
 
//Some kind of code
}

OR

for(var node:AlphabetNode = nodeList.tail; node; node = node.previous)
{
 
//Some other kind of code
}

Wouldn't that break the iteration of the latter example if caching a Node into the NodePool overrides node.previous??

James Wrightson

unread,
Sep 22, 2014, 2:52:07 PM9/22/14
to ash-fr...@googlegroups.com
I don't think sorting the nodes will affect the caching as the instances are the same.

(have no code in front of me so not 100% but if I remember, the "cache" is the "cacheTail" instance, which is separate
from the nodes in the node list ;)

Drew Martin

unread,
Sep 22, 2014, 2:56:38 PM9/22/14
to ash-fr...@googlegroups.com
Sorry. Perhaps I wasn't clear on what the problem was with the iteration. I missed a key point in my original post.

Say in the middle of the Z-A iteration (in the "some other kind of code part"), some Nodes were being removed and thus were going to be cache()'d for removal. Their node.previous would then be overridden by the cacheTail. Which would potentially break your Z-A iteration, no?

James Wrightson

unread,
Sep 23, 2014, 5:20:23 AM9/23/14
to ash-fr...@googlegroups.com
Ah yes that would happen :)

Not a bug though, more of a design choice.

I NEVER remove entities/components when working with order class loops.

I would take a 2 step approach to this issue:

1 - loop over the nodes and record changes to make
2 - loop over again and apply changes to make

Unless you have thousands I would not worry.

On a side note:

I really do not like the idea of using the nodes as some kind of directed graph.

Simply because the graph changes so much, and is really geared towards loop performance,
I would use something else to store sorted data sets.

I used to have a direct draw approach where each frame I would "draw" an entities display data...
...this required me to sort the node list of course for order layering. No issues there.

However, these days I use lower level systems to handle that kinda stuff and just let the entities deal
with core gameplay.

Richard

unread,
Sep 23, 2014, 6:24:16 AM9/23/14
to ash-fr...@googlegroups.com
Hi Drew

Yes, it's fine if you are iterating forwards but will break if you are iterating backwards and remove the current node. It is, as James notes, a design decision - I wanted to avoid the (admittedly minor) impact of using an Array for the nodes that should be disposed of, and I only ever iterate forwards :-).

Unlike James, I do remove nodes when iterating (forwards) and I do use sorted lists occasionally - sorting by z-order for rendering is the obvious example. Whatever makes you comfortable, there's no right or wrong.

If you want, you can replace the ComponentMatchingFamily with another class that implements the IFamily interface and manages node disposal during the update loop differently, just set the familyClass property in the Engine before creating any entities.

Richard

Drew Martin

unread,
Sep 23, 2014, 9:47:02 AM9/23/14
to ash-fr...@googlegroups.com
Ah, okay. Thanks Richard and James! Just wanted to make sure I had my facts straight. Admittedly, I haven't run into cases yet where I've had to remove Entities during a backwards iteration, but I have sorted them before for a reflection system, where drawing Entities to a wall or floor requires the same sorting, only one is traversed in reverse.

I've actually been attempting to write my own Entity/System framework from scratch, taking design cues from Ash, Artemis, and others. To combat the (admittedly rare) possibility of this happening, I'm caching removed Nodes into an Array to avoid modification of the list until the SystemManager - the "Engine" is broken up into modular Managers - is done updating. You never know what a dev's gonna try to pull in a system. ;)
Reply all
Reply to author
Forward
0 new messages