Add display.isValidObject function - #908
Conversation
- Add display.isValidObject( object ) to init.lua - Set _isRemoved on removed proxies; cascade to group and snapshot descendants - Clear _isRemoved on re-insert so same-frame re-parent rescues work - Make double-remove a no-op instead of an error - Set _isInvalid on newImage / newImageRect proxies when the bitmap loads as zero bytes
|
Here's an updated test suite with 3 added stress tests. The unit tests are commented out by default. There's a clear performance cost with the recursive marking of objects, but in absolute terms the performance seems to still hold very well. |
- Moved display.isValidObject function from Lua to C++ - Now also avoids false positives in case some developer has brilliantly added "removeSelf" function to a regular Lua table - Rewrote the recursive _isRemoved marking to work lazily by walking the object's parent chain to its root when the function itself is called - Objects rooted at an orphanage, deleted objects, and broken images all fail - Reparenting out of a removed subtree restores validity automatically
|
I was talking to StarCrunch yesterday and I had a off the cuff idea that this could be written lazily, so I did. 😄 I moved the This new approach means that there's no performance impact on removing objects. The same isValidObject (unit & stress tests).zip works, if you want to run the stress tests. Now that the function is on the C++ side, it also correctly identifies if a target object is actually a display object instead of just naively checking if it has a I also made it so that removing an already-removed object is now an explicit safe no-op; previously it asserted in debug builds and re-ran the removal path in release builds. |
display.isValidObject
Adds a Lua-level API for checking whether a given object is a valid display object that has not been removed.
Current behaviour
Object removal
Calling
display.remove( object )orobject:removeSelf()will take until the next frame to finish removing the object. In certain situations, like with collision events, callbacks, etc. it's possible that an object has been removed, but the removal isn't yet finished, which results in a crash if the app tries to access the object.Example
There is currently no reliable way to programmatically checking if a display object has already been removed and developers need to implement their own ad-hoc approaches to test for it.
Image object validity
Solar2D detects when
display.newImageordisplay.newImageRectis given a file that is not an image, or if the image is corrupted or otherwise invalid. Solar2D sends a warning about it to console viaCoronaLuaWarning(L, "file '%s' does not contain a valid image", imageName);. Funnily enough, Solar2D does not currently provide a reliable way to check this programmatically.What this PR does
This PR adds two internal proxy flags to objects,
_isRemovedand_isInvalid, that the engine sets at the moment an object is removed or when Solar2D detects an image is invalid upon trying to create it.This PR also adds a new
display.isValidObject( object )that verifies if a given object is 1) a display object, 2) it has not been removed, and 3) it is not invalid. The function always return a Boolean value, giving developers a reliable way of checking if their display objects are indeed valid or not.Example
Example
Unit tests
The test project runs 18 unit tests that exercise
display.isValidObjectacross all the edge cases: type safety with non-display-object inputs (nil, numbers, strings, tables, functions), removal viadisplay.removeandremoveSelf, idempotent double-removal, stage validity, group cascade at various nesting depths,finalizelistener timing, same-frame re-parent rescue for both groups and snapshots, every display primitive type (rect, circle, line, polygon, text, container, snapshot, group, capture), widgets, sprites, emitters, snapshot internals (snapshot.groupandsnapshot.canvaswith children), and corrupt/missing images vianewImageandnewImageRectto verify the_isInvalidflag. Each test checksisValidObjectbefore removal, same-frame after removal, and next-frame after removal, reporting pass/fail.isValidObject test.zip