Gamua / Starling-Framework

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

the bubbleChain in a Touch will not get updated if the target remains the same #936

Closed dietmarweiss closed 5 years ago

dietmarweiss commented 7 years ago

I came across a weird bug where i would get touch events on DisplayObjects that definitely should not get any because they are under another touchable DisplayObject. I looked into it and found that the bubble chain of the event seems to be 'old'. I add an element way up the display list when the user taps it, think of an image that comes forward into 'fullscreen mode' after tapping it. Tapping it again still gets me touch events on the image's old parent (and its parent and so on) even though it's now under the image.

I assume that the problem lies in the target setter of the Touch class, i guess for performance reasons the bubbleChain in a Touch object will not be updated when the target remains the same:

        public function set target(value:DisplayObject):void
        {
            if (_target != value)
            {
                _target = value;
                updateBubbleChain();
            }
        }

This can lead to unwanted behaviour if you add a DisplayObject to a different parent and the touch target is still the same because the bubbleChain does not update accordingly. This can even occur after releasing the touch and touching/clicking again because Touch objects seem to be cached in a pool.

Yet at Touch.clone() - which gets called for all touches at every frame - the updateBubbleChain method gets called anyway, because the _target for the new touch instance is null:

        public function clone():Touch
        {
            var clone:Touch = new Touch(_id);
            ...
            clone.target = _target;
            return clone;
        }

I suggest updating the bubbleChain in the TouchProcessor no matter the target and removing the updateBubbleChain method from the target setter in the Touch class.

PrimaryFeather commented 7 years ago

That's an interesting find, thanks a lot for the heads-up! I have to look into that in a little more detail before I can comment on it — I'll get back to you!

PrimaryFeather commented 7 years ago

Hey Dietmar, sorry for the long delay on this one. I'm currently looking into it, and I agree that the set target property should probably be implemented in a different way.

However, so that I'm absolutely certain we are talking about the same issue, could you please create a minimal sample for the scenario you mentioned (added below)?

I add an element way up the display list when the user taps it, think of an image that comes forward into 'fullscreen mode' after tapping it. Tapping it again still gets me touch events on the image's old parent (and its parent and so on) even though it's now under the image.

Because that's the part I'm not certain yet how it can happen, since I'm not pooling Touch objects, and whenever a Touch enters the "ENDED" phase, I'm discarding it. Well, at least in theory. That's why I'd love to have a demo of this issue, so that I can properly fix it.

Thanks a lot in advance!

PrimaryFeather commented 5 years ago

Lacking further input, I'll close this issue now.