core: Fix "too much recursion" with arcgis flex sdk (close #22860)#23355
core: Fix "too much recursion" with arcgis flex sdk (close #22860)#23355falpi wants to merge 1 commit intoruffle-rs:masterfrom
Conversation
| /// Dispatch the `removed` event on a child and log any errors encountered | ||
| /// whilst doing so. | ||
| /// | ||
| /// This function is protected against re-entrant calls: if an AS3 event listener |
There was a problem hiding this comment.
How does the recursion happen when the event is dispatched after removing the child? There's 3 call sites: AVM1 button, AVM2 button, and MC. Looks like in all of them the child is removed first, and then the event is being dispatched.
There was a problem hiding this comment.
Hi, I asked Claude to do an analysis of the problem and the solution in a PDF that I attached to the issue here:
https://github.com/user-attachments/files/26325924/claude_bugfix_report.pdf
I bring you the highlights of the PDF:
3.1 How display-list removal works in Flash
When ActionScript 3 removes a child from a display container, the Flash Player runtime fires two events on
the removed object:
• removed — bubbles up the display tree (dispatched while the child is still technically attached, so the
listener can inspect its parent).
• removedFromStage — does not bubble; dispatched on the child and every one of its descendants.
Adobe Flash Player dispatches these events synchronously but protects against reentrancy: if a listener
attempts to remove the same child again while its events are being dispatched, Flash silently ignores the
second request. This guard was never implemented in Ruffle."
3.3 Why ArcGIS Flex triggers the loop
During a zoom operation the ArcGIS Flex SDK rebuilds the tile layer: it removes all existing tiles
DisplayObjects and adds fresh ones for the new extent. The tile container listens for removed events on its
children to perform housekeeping (clearing bitmaps, canceling pending HTTP requests, etc.). That listener
itself calls removeChild on sibling tiles — perfectly legal in Flash, because Flash silently skips the second
removal for any child already being removed. Without the guard, Ruffle dispatches the event, the listener
runs, Ruffle dispatches the event again, ad infinitum
|
We'll need a test for that, because (1) it's not obvious how the recursion happens, and (2) without the test this can regress. |
f2617b4 to
307057e
Compare
|
Hi @kjarosh, sorry for my ignorance, but I don't understand what stage the PR is at. I saw you tagged it with "waiting-on-author." What does that mean? Do I have to do something? |
|
Hi, no worries. So there are few things:
So these 3 points above need to be solved to continue with the review. Without them, it's fine for the PR to be posted and to wait for someone else (either a maintainer or another human contributor) to take it over (it happens regularly). |
Okay, I understand your caution in accepting LLM-centric contributions. In this case, the proposed changes are very simple (just a few lines of code), but the effect is invaluable, as it re-enables the ArcGIS SDK. So, I hope someone can quickly validate the PR. Regards |
307057e to
f88bbed
Compare
A solution proposed by Claude Code for the problem described in issue #22860