@sporkfin
I think your code got mangled. Re-pasting on multi-lines:
local myTable = {} local circle = display.newCircle( 10, 10, 10 ) myTable[#myTable + 1] = circle
While there is nothing wrong with this way of populating tables, I find it very inflexible and painful to operate on.
Why Do We Put Object References In Tables
Before we can have meaningful discussion about this, we need to agree on why we are putting the references in tables in the first place.
I will posit two examples:
-
Targeting - Often, in action games, I keep a table of enemies. Then, if my player is firing a ‘seeking projectile’ I can iterate over the table of ‘targets/enemies’ and select one that meets whatever criteria I need.
- ’ Asteroids’ - Another great example is the game Asteroids. In this game, you progressively have more and more asteroids in the world as the difficulty gets higher. Additionally, your implementation of the game may need to test for a minimum count to advance the difficulty of the game.
When Will The Objects Be Removed and What Will I Know At the Time?
- In BOTH of the above cases, the objects in the tables are going to be removed from the world in arbitrary order.
- When I remove an object from the world I will have a reference to that object in my possession. i.e. My code will know what object I am removing.
Why Object Referencing Is Better (In This Case)
When I go to remove the display object(s) in the above scenarios I need to do the following:
- Destroy the display object(s).
- Locate their entry in the ‘tracking’ table and remove (clear) the reference.
- (Optionally) remove the entry from the table. ( TIP: If I do this, #2 is automatically achieved).
We talked about this above, but these steps are required so:
- The object(s) is properly destroyed AND garbage collected.
- The table can still be iterated over.
The challenge here is, if I’m using a numerically indexed table, I have to either:
-
Iterate over the table in reverse order to avoid creating gaps that impede the iteration. - Not hard, but unnatural for me, and the lazy programmer in me hates the extra typing.
-
OR -
-
Write some complex code or wrapper to defer the clearing of entries till after identifying them (the code you asked about above is an example of this approach.)
Therefore, I find it FAR SIMPLER to simply do this:
local myTable = {} local tmp= display.newCircle( 10, 10, 10 ) myTable[tmp] = tmp
Now, removing entries from the table is straight-forward:
-- One nice way do handle this is to have a finalize function for the object function tmp.finalize( self ) myTable[self] = nil end tmp:addEventListener("finalize") -- Now if we delete the object, its entry in the table is automatically cleared
You could also do that clearing in the place you actually delete the object. For example, if you delete the object in its collision handler:
function tmp.collision( self, event ) if( event.phase ~= "began" ) then return false end display.remove( self ) myTable[self] = nil return true end tmp:addEventListener("collision")
The key thing to remember is, wherever you do this work, you must ensure the tracking table is in scope. That is it.
What Are The Drawbacks To Object Indexed Tables?
-
Counting entries is a little more work:
local function tcount( t ) local c = 0 for k,v in pairs(t) do c = c + 1 end return c end
-
“Iteration is slower!” - I put an exclamation point on that because I often see people state this as if somehow it is a big deal. It almost never is.
To be clear, I’m saying this style:
for k,v in pairs(tbl) do end
is slower than this:
for i = 1, #tbl do end
So what? Unless you’re iterating over 10K entries per frame this won’t make a bit of difference to your game speed. i.e. You only notice this in the extreme cases.
- “What about the table size and the way it grows?” - Honestly, I don’t know much about this. I suspect:
- Numeric indexing may be more efficient.
- There may be hidden memory and computing costs associated with object indexing.
However, at the end of the day, I still say this will be MOOT and barely noticeable.
I’m done
I think I’m done on this topic and I hope I’ve answered any open questions as well as explained why I prefer object indexing over numeric.