diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/EventAnimationDriver.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/EventAnimationDriver.java deleted file mode 100644 index c1a4cfe48bb256..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/EventAnimationDriver.java +++ /dev/null @@ -1,116 +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.animated; - -import androidx.annotation.Nullable; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableType; -import com.facebook.react.bridge.UnexpectedNativeTypeException; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.uimanager.events.EventCategoryDef; -import com.facebook.react.uimanager.events.RCTModernEventEmitter; -import com.facebook.react.uimanager.events.TouchEvent; -import java.util.List; - -/** Handles updating a {@link ValueAnimatedNode} when an event gets dispatched. */ -/* package */ class EventAnimationDriver implements RCTModernEventEmitter { - private List mEventPath; - /* package */ ValueAnimatedNode mValueNode; - /* package */ String mEventName; - /* package */ int mViewTag; - - public EventAnimationDriver( - String eventName, int viewTag, List eventPath, ValueAnimatedNode valueNode) { - mEventName = eventName; - mViewTag = viewTag; - mEventPath = eventPath; - mValueNode = valueNode; - } - - @Override - public void receiveEvent(int targetReactTag, String eventName, @Nullable WritableMap event) { - receiveEvent(-1, targetReactTag, eventName, event); - } - - @Override - public void receiveEvent( - int surfaceId, int targetTag, String eventName, @Nullable WritableMap event) { - // We assume this event can't be coalesced. `customCoalesceKey` has no meaning in Fabric. - receiveEvent(surfaceId, targetTag, eventName, false, 0, event, EventCategoryDef.UNSPECIFIED); - } - - @Override - public void receiveTouches( - String eventName, WritableArray touches, WritableArray changedIndices) { - throw new UnsupportedOperationException( - "receiveTouches is not support by native animated events"); - } - - @Override - public void receiveTouches(TouchEvent touchEvent) { - throw new UnsupportedOperationException( - "receiveTouches is not support by native animated events"); - } - - @Override - public void receiveEvent( - int surfaceId, - int targetTag, - String eventName, - boolean canCoalesceEvent, - int customCoalesceKey, - @Nullable WritableMap event, - @EventCategoryDef int category) { - if (event == null) { - throw new IllegalArgumentException("Native animated events must have event data."); - } - - // Get the new value for the node by looking into the event map using the provided event path. - ReadableMap currMap = event; - ReadableArray currArray = null; - for (int i = 0; i < mEventPath.size() - 1; i++) { - if (currMap != null) { - String key = mEventPath.get(i); - ReadableType keyType = currMap.getType(key); - if (keyType == ReadableType.Map) { - currMap = currMap.getMap(key); - currArray = null; - } else if (keyType == ReadableType.Array) { - currArray = currMap.getArray(key); - currMap = null; - } else { - throw new UnexpectedNativeTypeException( - "Unexpected type " + keyType + " for key '" + key + "'"); - } - } else { - int index = Integer.parseInt(mEventPath.get(i)); - ReadableType keyType = currArray.getType(index); - if (keyType == ReadableType.Map) { - currMap = currArray.getMap(index); - currArray = null; - } else if (keyType == ReadableType.Array) { - currArray = currArray.getArray(index); - currMap = null; - } else { - throw new UnexpectedNativeTypeException( - "Unexpected type " + keyType + " for index '" + index + "'"); - } - } - } - - String lastKey = mEventPath.get(mEventPath.size() - 1); - if (currMap != null) { - mValueNode.nodeValue = currMap.getDouble(lastKey); - } else { - int lastIndex = Integer.parseInt(lastKey); - mValueNode.nodeValue = currArray.getDouble(lastIndex); - } - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/EventAnimationDriver.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/EventAnimationDriver.kt new file mode 100644 index 00000000000000..46eb8dee6e2da6 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/EventAnimationDriver.kt @@ -0,0 +1,102 @@ +/* + * 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.animated + +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.ReadableMap +import com.facebook.react.bridge.ReadableType +import com.facebook.react.bridge.UnexpectedNativeTypeException +import com.facebook.react.bridge.WritableArray +import com.facebook.react.bridge.WritableMap +import com.facebook.react.uimanager.events.EventCategoryDef +import com.facebook.react.uimanager.events.RCTModernEventEmitter +import com.facebook.react.uimanager.events.TouchEvent + +/** Handles updating a [ValueAnimatedNode] when an event gets dispatched. */ +internal class EventAnimationDriver( + @JvmField var eventName: String, + @JvmField internal var viewTag: Int, + private val eventPath: List, + @JvmField internal var valueNode: ValueAnimatedNode +) : RCTModernEventEmitter { + override fun receiveEvent(targetReactTag: Int, eventName: String, event: WritableMap?) { + receiveEvent(-1, targetReactTag, eventName, event) + } + + override fun receiveEvent( + surfaceId: Int, + targetTag: Int, + eventName: String, + event: WritableMap? + ) { + // We assume this event can't be coalesced. `customCoalesceKey` has no meaning in Fabric. + receiveEvent(surfaceId, targetTag, eventName, false, 0, event, EventCategoryDef.UNSPECIFIED) + } + + override fun receiveTouches( + eventName: String, + touches: WritableArray, + changedIndices: WritableArray + ) { + throw UnsupportedOperationException("receiveTouches is not support by native animated events") + } + + override fun receiveTouches(touchEvent: TouchEvent) { + throw UnsupportedOperationException("receiveTouches is not support by native animated events") + } + + override fun receiveEvent( + surfaceId: Int, + targetTag: Int, + eventName: String, + canCoalesceEvent: Boolean, + customCoalesceKey: Int, + event: WritableMap?, + @EventCategoryDef category: Int + ) { + requireNotNull(event) { "Native animated events must have event data." } + + // Get the new value for the node by looking into the event map using the provided event path. + var currMap: ReadableMap? = event + var currArray: ReadableArray? = null + for (i in 0 until eventPath.size - 1) { + if (currMap != null) { + val key = eventPath[i] + val keyType = currMap.getType(key) + if (keyType == ReadableType.Map) { + currMap = currMap.getMap(key) + currArray = null + } else if (keyType == ReadableType.Array) { + currArray = currMap.getArray(key) + currMap = null + } else { + throw UnexpectedNativeTypeException("Unexpected type $keyType for key '$key'") + } + } else { + val index = eventPath[i].toInt() + val keyType = currArray?.getType(index) + if (keyType == ReadableType.Map) { + currMap = currArray?.getMap(index) + currArray = null + } else if (keyType == ReadableType.Array) { + currArray = currArray?.getArray(index) + currMap = null + } else { + throw UnexpectedNativeTypeException("Unexpected type $keyType for index '$index'") + } + } + } + val lastKey = eventPath[eventPath.size - 1] + if (currMap != null) { + valueNode.nodeValue = currMap.getDouble(lastKey) + } else { + val lastIndex = lastKey.toInt() + valueNode.nodeValue = currArray?.getDouble(lastIndex) ?: 0.0 + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java index ed7438838b9220..dfece9acaa9909 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java @@ -563,9 +563,9 @@ public void removeAnimatedEventFromView( ListIterator it = mEventDrivers.listIterator(); while (it.hasNext()) { EventAnimationDriver driver = it.next(); - if (eventName.equals(driver.mEventName) - && viewTag == driver.mViewTag - && animatedValueTag == driver.mValueNode.tag) { + if (eventName.equals(driver.eventName) + && viewTag == driver.viewTag + && animatedValueTag == driver.valueNode.tag) { it.remove(); break; } @@ -609,11 +609,11 @@ private void handleEvent(Event event) { boolean foundAtLeastOneDriver = false; Event.EventAnimationDriverMatchSpec matchSpec = event.getEventAnimationDriverMatchSpec(); for (EventAnimationDriver driver : mEventDrivers) { - if (matchSpec.match(driver.mViewTag, driver.mEventName)) { + if (matchSpec.match(driver.viewTag, driver.eventName)) { foundAtLeastOneDriver = true; - stopAnimationsForNode(driver.mValueNode); + stopAnimationsForNode(driver.valueNode); event.dispatchModern(driver); - mRunUpdateNodeList.add(driver.mValueNode); + mRunUpdateNodeList.add(driver.valueNode); } } @@ -704,10 +704,10 @@ Set getTagsOfConnectedNodes(int tag, String eventName) { while (it.hasNext()) { EventAnimationDriver driver = it.next(); if (driver != null) { - if (eventName.equals(driver.mEventName) && tag == driver.mViewTag) { - tags.add(driver.mViewTag); - if (driver.mValueNode != null && driver.mValueNode.children != null) { - for (AnimatedNode node : driver.mValueNode.children) { + if (eventName.equals(driver.eventName) && tag == driver.viewTag) { + tags.add(driver.viewTag); + if (driver.valueNode != null && driver.valueNode.children != null) { + for (AnimatedNode node : driver.valueNode.children) { tags.add(node.tag); } }