TouchEventCoalescingKeyHelper -> Kotlin (#48448)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/48448

# Changelog:
[Internal] -

As in the title.

Reviewed By: tdn120

Differential Revision: D67759862

fbshipit-source-id: 7a8e133962cdc43aed0bae38a89d37fb7e6031a6
This commit is contained in:
Ruslan Shestopalyuk
2025-01-02 11:18:07 -08:00
committed by Facebook GitHub Bot
parent e8347b9854
commit 5ef9e1fffe
3 changed files with 83 additions and 91 deletions
@@ -5752,13 +5752,13 @@ public final class com/facebook/react/uimanager/events/TouchEvent$Companion {
public final fun obtain (ILcom/facebook/react/uimanager/events/TouchEventType;Landroid/view/MotionEvent;JFFLcom/facebook/react/uimanager/events/TouchEventCoalescingKeyHelper;)Lcom/facebook/react/uimanager/events/TouchEvent;
}
public class com/facebook/react/uimanager/events/TouchEventCoalescingKeyHelper {
public final class com/facebook/react/uimanager/events/TouchEventCoalescingKeyHelper {
public fun <init> ()V
public fun addCoalescingKey (J)V
public fun getCoalescingKey (J)S
public fun hasCoalescingKey (J)Z
public fun incrementCoalescingKey (J)V
public fun removeCoalescingKey (J)V
public final fun addCoalescingKey (J)V
public final fun getCoalescingKey (J)S
public final fun hasCoalescingKey (J)Z
public final fun incrementCoalescingKey (J)V
public final fun removeCoalescingKey (J)V
}
public final class com/facebook/react/uimanager/events/TouchEventType : java/lang/Enum {
@@ -1,85 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager.events;
import android.util.SparseIntArray;
import com.facebook.infer.annotation.Nullsafe;
/**
* Utility for determining coalescing keys for TouchEvents. To preserve proper ordering of events,
* move events should only be coalesced if there has been no up/down event between them (this
* basically only applies to multitouch since for single touches an up would signal the end of the
* gesture). To illustrate to kind of coalescing we want, imagine we are coalescing the following
* touch stream:
*
* <p>(U = finger up, D = finger down, M = move) D MMMMM D MMMMMMMMMMMMMM U MMMMM D MMMMMM U U
*
* <p>We want to make sure to coalesce this as
*
* <p>D M D M U M D U U
*
* <p>and *not*
*
* <p>D D U M D U U
*
* <p>To accomplish this, this class provides a way to initialize a coalescing key for a gesture and
* then increment it for every pointer up/down that occurs during that single gesture.
*
* <p>We identify a single gesture based on {@link android.view.MotionEvent#getDownTime()} which
* will stay constant for a given set of related touches on a single view.
*
* <p>NB: even though down time is a long, we cast as an int using the least significant bits as the
* identifier. In practice, we will not be coalescing over a time range where the most significant
* bits of that time range matter. This would require a gesture that lasts Integer.MAX_VALUE * 2 ms,
* or ~48 days.
*
* <p>NB: we assume two gestures cannot begin at the same time.
*
* <p>NB: this class should only be used from the UI thread.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
public class TouchEventCoalescingKeyHelper {
private final SparseIntArray mDownTimeToCoalescingKey = new SparseIntArray();
/** Starts tracking a new coalescing key corresponding to the gesture with this down time. */
public void addCoalescingKey(long downTime) {
mDownTimeToCoalescingKey.put((int) downTime, 0);
}
/** Increments the coalescing key corresponding to the gesture with this down time. */
public void incrementCoalescingKey(long downTime) {
int currentValue = mDownTimeToCoalescingKey.get((int) downTime, -1);
if (currentValue == -1) {
throw new RuntimeException("Tried to increment non-existent cookie");
}
mDownTimeToCoalescingKey.put((int) downTime, currentValue + 1);
}
/** Gets the coalescing key corresponding to the gesture with this down time. */
public short getCoalescingKey(long downTime) {
int currentValue = mDownTimeToCoalescingKey.get((int) downTime, -1);
if (currentValue == -1) {
throw new RuntimeException("Tried to get non-existent cookie");
}
return ((short) (0xffff & currentValue));
}
/** Stops tracking a new coalescing key corresponding to the gesture with this down time. */
public void removeCoalescingKey(long downTime) {
mDownTimeToCoalescingKey.delete((int) downTime);
}
public boolean hasCoalescingKey(long downTime) {
int currentValue = mDownTimeToCoalescingKey.get((int) downTime, -1);
if (currentValue == -1) {
return false;
}
return true;
}
}
@@ -0,0 +1,77 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager.events
import android.util.SparseIntArray
/**
* Utility for determining coalescing keys for TouchEvents. To preserve proper ordering of events,
* move events should only be coalesced if there has been no up/down event between them (this
* basically only applies to multitouch since for single touches an up would signal the end of the
* gesture). To illustrate to kind of coalescing we want, imagine we are coalescing the following
* touch stream:
*
* (U = finger up, D = finger down, M = move) D MMMMM D MMMMMMMMMMMMMM U MMMMM D MMMMMM U U
*
* We want to make sure to coalesce this as
*
* D M D M U M D U U
*
* and *not*
*
* D D U M D U U
*
* To accomplish this, this class provides a way to initialize a coalescing key for a gesture and
* then increment it for every pointer up/down that occurs during that single gesture.
*
* We identify a single gesture based on [android.view.MotionEvent.getDownTime] which will stay
* constant for a given set of related touches on a single view.
*
* NB: even though down time is a long, we cast as an int using the least significant bits as the
* identifier. In practice, we will not be coalescing over a time range where the most significant
* bits of that time range matter. This would require a gesture that lasts Integer.MAX_VALUE * 2 ms,
* or ~48 days.
*
* NB: we assume two gestures cannot begin at the same time.
*
* NB: this class should only be used from the UI thread.
*/
public class TouchEventCoalescingKeyHelper {
private val downTimeToCoalescingKey = SparseIntArray()
/** Starts tracking a new coalescing key corresponding to the gesture with this down time. */
public fun addCoalescingKey(downTime: Long) {
downTimeToCoalescingKey.put(downTime.toInt(), 0)
}
/** Increments the coalescing key corresponding to the gesture with this down time. */
public fun incrementCoalescingKey(downTime: Long) {
val currentValue = downTimeToCoalescingKey[downTime.toInt(), -1]
if (currentValue == -1) {
throw RuntimeException("Tried to increment non-existent cookie")
}
downTimeToCoalescingKey.put(downTime.toInt(), currentValue + 1)
}
/** Gets the coalescing key corresponding to the gesture with this down time. */
public fun getCoalescingKey(downTime: Long): Short {
val currentValue = downTimeToCoalescingKey[downTime.toInt(), -1]
if (currentValue == -1) {
throw RuntimeException("Tried to get non-existent cookie")
}
return ((0xffff and currentValue).toShort())
}
/** Stops tracking a new coalescing key corresponding to the gesture with this down time. */
public fun removeCoalescingKey(downTime: Long) {
downTimeToCoalescingKey.delete(downTime.toInt())
}
public fun hasCoalescingKey(downTime: Long): Boolean =
downTimeToCoalescingKey[downTime.toInt(), -1] != -1
}