Migrate ShadowNodeRegistry to Kotlin (#50081)

Summary:
Migrate com.facebook.react.uimanager.ShadowNodeRegistry to Kotlin.

## Changelog:

[INTERNAL] - Migrate com.facebook.react.uimanager.ShadowNodeRegistry to Kotlin

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

Test Plan:
```bash
yarn test-android
yarn android
```

Reviewed By: cortinico, rshest

Differential Revision: D71385038

Pulled By: javache

fbshipit-source-id: 155c9d5b60e3e4b4436424577c1868d60dfb4014
This commit is contained in:
Mateo Guzmán
2025-03-18 04:33:24 -07:00
committed by Facebook GitHub Bot
parent d6ca25b0c1
commit ac97177651
2 changed files with 91 additions and 96 deletions
@@ -1,96 +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;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.View;
import com.facebook.react.common.SingleThreadAsserter;
import com.facebook.react.common.annotations.internal.LegacyArchitecture;
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel;
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
/**
* Simple container class to keep track of {@link ReactShadowNode}s associated with a particular
* UIManagerModule instance.
*/
@LegacyArchitecture
class ShadowNodeRegistry {
static {
LegacyArchitectureLogger.assertWhenLegacyArchitectureMinifyingEnabled(
"ShadowNodeRegistry", LegacyArchitectureLogLevel.WARNING);
}
private final SparseArray<ReactShadowNode> mTagsToCSSNodes;
private final SparseBooleanArray mRootTags;
private final SingleThreadAsserter mThreadAsserter;
public ShadowNodeRegistry() {
mTagsToCSSNodes = new SparseArray<>();
mRootTags = new SparseBooleanArray();
mThreadAsserter = new SingleThreadAsserter();
}
public void addRootNode(ReactShadowNode node) {
mThreadAsserter.assertNow();
int tag = node.getReactTag();
mTagsToCSSNodes.put(tag, node);
mRootTags.put(tag, true);
}
public void removeRootNode(int tag) {
mThreadAsserter.assertNow();
if (tag == View.NO_ID) {
// This root node has already been removed (likely due to a threading issue caused by async js
// execution). Ignore this root removal.
return;
}
if (!mRootTags.get(tag)) {
throw new IllegalViewOperationException(
"View with tag " + tag + " is not registered as a root view");
}
mTagsToCSSNodes.remove(tag);
mRootTags.delete(tag);
}
public void addNode(ReactShadowNode node) {
mThreadAsserter.assertNow();
mTagsToCSSNodes.put(node.getReactTag(), node);
}
public void removeNode(int tag) {
mThreadAsserter.assertNow();
if (mRootTags.get(tag)) {
throw new IllegalViewOperationException(
"Trying to remove root node " + tag + " without using removeRootNode!");
}
mTagsToCSSNodes.remove(tag);
}
public ReactShadowNode getNode(int tag) {
mThreadAsserter.assertNow();
return mTagsToCSSNodes.get(tag);
}
public boolean isRootNode(int tag) {
mThreadAsserter.assertNow();
return mRootTags.get(tag);
}
public int getRootNodeCount() {
mThreadAsserter.assertNow();
return mRootTags.size();
}
public int getRootTag(int index) {
mThreadAsserter.assertNow();
return mRootTags.keyAt(index);
}
}
@@ -0,0 +1,91 @@
/*
* 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
import android.util.SparseArray
import android.util.SparseBooleanArray
import android.view.View
import com.facebook.react.common.SingleThreadAsserter
import com.facebook.react.common.annotations.internal.LegacyArchitecture
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger
/**
* Simple container class to keep track of [ReactShadowNode]s associated with a particular
* UIManagerModule instance.
*/
@LegacyArchitecture
internal class ShadowNodeRegistry {
private val tagsToCSSNodes = SparseArray<ReactShadowNode<*>>()
private val rootTags = SparseBooleanArray()
private val threadAsserter = SingleThreadAsserter()
fun addRootNode(node: ReactShadowNode<*>) {
threadAsserter.assertNow()
val tag = node.reactTag
tagsToCSSNodes.put(tag, node)
rootTags.put(tag, true)
}
fun removeRootNode(tag: Int) {
threadAsserter.assertNow()
if (tag == View.NO_ID) {
// This root node has already been removed (likely due to a threading issue caused by async js
// execution). Ignore this root removal.
return
}
if (!rootTags[tag]) {
throw IllegalViewOperationException("View with tag $tag is not registered as a root view")
}
tagsToCSSNodes.remove(tag)
rootTags.delete(tag)
}
fun addNode(node: ReactShadowNode<*>) {
threadAsserter.assertNow()
tagsToCSSNodes.put(node.reactTag, node)
}
fun removeNode(tag: Int) {
threadAsserter.assertNow()
if (rootTags[tag]) {
throw IllegalViewOperationException(
"Trying to remove root node $tag without using removeRootNode!")
}
tagsToCSSNodes.remove(tag)
}
fun getNode(tag: Int): ReactShadowNode<*>? {
threadAsserter.assertNow()
return tagsToCSSNodes[tag]
}
fun isRootNode(tag: Int): Boolean {
threadAsserter.assertNow()
return rootTags[tag]
}
val rootNodeCount: Int
get() {
threadAsserter.assertNow()
return rootTags.size()
}
fun getRootTag(index: Int): Int {
threadAsserter.assertNow()
return rootTags.keyAt(index)
}
private companion object {
init {
LegacyArchitectureLogger.assertWhenLegacyArchitectureMinifyingEnabled(
"ShadowNodeRegistry", LegacyArchitectureLogLevel.WARNING)
}
}
}