Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert TrackingAnimatedNode to Kotlin #45728

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,14 @@ public abstract class com/facebook/react/animated/AnimatedNode {
public final class com/facebook/react/animated/AnimatedNode$Companion {
}

public abstract interface class com/facebook/react/animated/AnimatedNodeValueListener {
public abstract fun onValueUpdate (D)V
}

public abstract interface class com/facebook/react/animated/AnimatedNodeWithUpdateableConfig {
public abstract fun onUpdateConfig (Lcom/facebook/react/bridge/ReadableMap;)V
}

public class com/facebook/react/animated/NativeAnimatedModule : com/facebook/fbreact/specs/NativeAnimatedModuleSpec, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/UIManagerListener {
public static final field ANIMATED_MODULE_DEBUG Z
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.animated;
package com.facebook.react.animated

/** Interface used to listen to {@link ValueAnimatedNode} updates. */
interface AnimatedNodeValueListener {
void onValueUpdate(double value);
/** Interface used to listen to [ValueAnimatedNode] updates. */
public fun interface AnimatedNodeValueListener {
public fun onValueUpdate(value: Double)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.animated;
package com.facebook.react.animated

import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMap

/** Indicates that AnimatedNode is able to receive native config updates. */
interface AnimatedNodeWithUpdateableConfig {
void onUpdateConfig(ReadableMap config);
public fun interface AnimatedNodeWithUpdateableConfig {
public fun onUpdateConfig(config: ReadableMap?)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* 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.JavaOnlyArray
import com.facebook.react.bridge.JavaOnlyMap
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.ReadableType

/**
* Native counterpart of object animated node (see AnimatedObject class in
* AnimatedImplementation.js)
*/
internal class ObjectAnimatedNode(
config: ReadableMap,
private val nativeAnimatedNodesManager: NativeAnimatedNodesManager
) : AnimatedNode() {
private val configClone: JavaOnlyMap = JavaOnlyMap.deepClone(config)

fun collectViewUpdates(propKey: String, propsMap: JavaOnlyMap) {
val valueType = configClone.getType(VALUE_KEY)
if (valueType == ReadableType.Map) {
propsMap.putMap(propKey, collectViewUpdatesHelper(configClone.getMap(VALUE_KEY)))
} else if (valueType == ReadableType.Array) {
propsMap.putArray(propKey, collectViewUpdatesHelper(configClone.getArray(VALUE_KEY)))
} else {
throw IllegalArgumentException("Invalid value type for ObjectAnimatedNode")
}
}

private fun collectViewUpdatesHelper(source: ReadableArray?): JavaOnlyArray? {
source ?: return null
val result = JavaOnlyArray()
for (i in 0 until source.size()) {
when (source.getType(i)) {
ReadableType.Null -> result.pushNull()
ReadableType.Boolean -> result.pushBoolean(source.getBoolean(i))
ReadableType.Number -> result.pushDouble(source.getDouble(i))
ReadableType.String -> result.pushString(source.getString(i))
ReadableType.Map -> {
val map = source.getMap(i)
if (map.hasKey(NODE_TAG_KEY) && map.getType(NODE_TAG_KEY) == ReadableType.Number) {
val node = nativeAnimatedNodesManager.getNodeById(map.getInt(NODE_TAG_KEY))
requireNotNull(node) { "Mapped value node does not exist" }
if (node is ValueAnimatedNode) {
val animatedObject = node.getAnimatedObject()
if (animatedObject is Int) {
result.pushInt(animatedObject)
} else if (animatedObject is String) {
result.pushString(animatedObject)
} else {
result.pushDouble(node.getValue())
}
} else if (node is ColorAnimatedNode) {
result.pushInt(node.color)
}
} else {
result.pushMap(collectViewUpdatesHelper(source.getMap(i)))
}
}
ReadableType.Array -> result.pushArray(collectViewUpdatesHelper(source.getArray(i)))
}
}
return result
}

private fun collectViewUpdatesHelper(source: ReadableMap?): JavaOnlyMap? {
source ?: return null
val result = JavaOnlyMap()
val iter = source.keySetIterator()
while (iter.hasNextKey()) {
val propKey = iter.nextKey()
when (source.getType(propKey)) {
ReadableType.Null -> result.putNull(propKey)
ReadableType.Boolean -> result.putBoolean(propKey, source.getBoolean(propKey))
ReadableType.Number -> result.putDouble(propKey, source.getDouble(propKey))
ReadableType.String -> result.putString(propKey, source.getString(propKey))
ReadableType.Map -> {
val map = source.getMap(propKey)
if (map != null &&
map.hasKey(NODE_TAG_KEY) &&
map.getType(NODE_TAG_KEY) == ReadableType.Number) {
val node = nativeAnimatedNodesManager.getNodeById(map.getInt(NODE_TAG_KEY))
requireNotNull(node) { "Mapped value node does not exist" }
if (node is ValueAnimatedNode) {
val animatedObject = node.getAnimatedObject()
if (animatedObject is Int) {
result.putInt(propKey, animatedObject)
} else if (animatedObject is String) {
result.putString(propKey, animatedObject)
} else {
result.putDouble(propKey, node.getValue())
}
} else if (node is ColorAnimatedNode) {
result.putInt(propKey, node.color)
}
} else {
result.putMap(propKey, collectViewUpdatesHelper(map))
}
}
ReadableType.Array ->
result.putArray(propKey, collectViewUpdatesHelper(source.getArray(propKey)))
}
}
return result
}

override fun prettyPrint(): String = "ObjectAnimatedNode[$tag]: mConfig: $configClone"

companion object {
private const val VALUE_KEY = "value"
private const val NODE_TAG_KEY = "nodeTag"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ internal class TrackingAnimatedNode(
config: ReadableMap,
private val nativeAnimatedNodesManager: NativeAnimatedNodesManager
) : AnimatedNode() {
private val animationConfig: JavaOnlyMap = JavaOnlyMap.deepClone(config.getMap("animationConfig"))
private val animationId: Int = config.getInt("animationId")
private val toValueNode: Int = config.getInt("toValue")
private val valueNode: Int = config.getInt("value")
private val animationConfig: JavaOnlyMap = JavaOnlyMap.deepClone(config.getMap("animationConfig"))

public override fun update() {
val toValue = nativeAnimatedNodesManager.getNodeById(toValueNode)
Expand Down