Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.86k stars 822 forks source link

#2006 Out of bounds Error in 'Starling.isNativeDisplayObjectEmpty' function #975

Closed cgascons closed 5 years ago

cgascons commented 7 years ago

Hi Daniel!

Just got this weird issue by playing on an Android device while (thankfully!) debugging.

This is the stack trace:

_RangeError: Error #2006: The supplied index is out of bounds. at flash.display::DisplayObjectContainer/getChildAt() at Function/Starling.as$586:isNativeDisplayObjectEmpty()[/Users/cgascons/workspace/TCGEngine/externals/Starling-Framework/starling/src/starling/core/Starling.as:1047] at starling.core::Starling/get mustAlwaysRender()[/Users/cgascons/workspace/TCGEngine/externals/Starling-Framework/starling/src/starling/core/Starling.as:748] at starling.core::Starling/render()[/Users/cgascons/workspace/TCGEngine/externals/Starling-Framework/starling/src/starling/core/Starling.as:419] at starling.core::Starling/nextFrame()[/Users/cgascons/workspace/TCGEngine/externals/Starling-Framework/starling/src/starling/core/Starling.as:388] at starling.core::Starling/onEnterFrame()[/Users/cgascons/workspace/TCGEngine/externals/Starling-Framework/starling/src/starling/core/Starling.as:604]_

I recall just gaining focus on a textfield to rename the player nick when it happened, the good news is, it didn't crash the app.

Currently using:

Starling: 2.1 (2016-09-29) Feathers: 3.1.2 (Jan 2017)

Not critical at all, and franky players haven't reported any kind of crash because of this but I thought I'd let you know just in case.

Thanks!

PrimaryFeather commented 7 years ago

Thanks for the report, Christian!

Frankly, though, I have no idea how this can happen. 😲 The function isNativeDisplayObjectEmpty makes all the checks I can think of to avoid this error. Very strange!

Anyone, if this comes up again, please post any information about it here. Thanks in advance!

cgascons commented 7 years ago

No problem Daniel! I will be trying to find some steps to reproduce this and will add more info here as soon as I get them. Thanks!

JohnBlackburne commented 7 years ago

It looks a lot like something I’ve encountered before with events, where the processing on one event (a MouseDown event) coincided with the processing of the EnterFrame event, so as to cause it to fail. The problem was similar, iterating through an array which it did every frame. On rare occasions the user would take an action that changed the length of the array while it was being iterated over, leading to odd outcomes.

The fix was to defer handling of MouseEvents (now TouchEvents), queueing them up until the EnterFrame event fired, processing them before everything else. Looking at the code here I don’t see such an easy solution; it could be the native EnterFrame or native input events that are causing it to change, and Starling has access to none of them. The only fix I can think of is to wrap it all in an exception handler, catching any errors and returning a sensible default value.

PrimaryFeather commented 7 years ago

Thanks a lot for your input, John! You're right, it must be something like that. Though it still puzzles me that the number of children can change while iterating over it, given that AS3 doesn't support any multithreading, and the code called during iteration shouldn't lead to any user code (which could change the display list).

A try/catch would be a workaround — as a last resort. In a release build, though, I don't think this can lead to serious problems, anyway: the game will just skip one frame (since this exception will abort the render method) and should recover in the next.

JohnBlackburne commented 7 years ago

I have encountered it before, so if its not multithreaded it must be some sort of pre-emptive multitasking, interrupting other events such as EnterFrame to immediately deal with input events like MouseEvent. Which makes sense – no matter how slow Flash is you want it to respond instantly to e.g. mouse clicks, on adverts for example.

It is possibly fixable in the code handling the native DisplayObjects, either deferring event handling or deferring updates to DisplayObjectContainers (flag members for removal before removing them in the next EnterFrame). Unclear whether it is worth the effort, but that is where I would look.

PrimaryFeather commented 5 years ago

Since this hasn't been reported again since the issue was originally created, I'll close this issue now.