mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
IntBufferBatchMountItem - migrate to Kotlin (#50700)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50700 ## Changelog: [Android] [Internal] - IntBufferBatchMountItem is now in Kotlin Reviewed By: cortinico Differential Revision: D72965060 fbshipit-source-id: d036030ddd3fbd0bc387e02236ee330bb310ca64
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f622923374
commit
309ccb8b60
-346
@@ -1,346 +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.fabric.mounting.mountitems;
|
||||
|
||||
import static com.facebook.react.fabric.FabricUIManager.IS_DEVELOPMENT_ENVIRONMENT;
|
||||
import static com.facebook.react.fabric.mounting.mountitems.FabricNameComponentMapping.getFabricComponentName;
|
||||
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.infer.annotation.Nullsafe;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.ReactMarker;
|
||||
import com.facebook.react.bridge.ReactMarkerConstants;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.fabric.events.EventEmitterWrapper;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.fabric.mounting.SurfaceMountingManager;
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This class represents a batch of {@link MountItem}s, represented directly as int buffers to
|
||||
* remove the need for actual MountItem instances.
|
||||
*
|
||||
* <p>An IntBufferBatchMountItem batch contains an array of ints, indicating the mount actions that
|
||||
* should be taken, and a size; as well as an array of Objects, and a corresponding array size, for
|
||||
* any data that cannot be passed as a raw int.
|
||||
*
|
||||
* <p>The purpose of encapsulating the array of MountItems this way, is to reduce the amount of
|
||||
* allocations in C++ and JNI round-trips.
|
||||
*/
|
||||
@DoNotStrip
|
||||
@Nullsafe(Nullsafe.Mode.LOCAL)
|
||||
final class IntBufferBatchMountItem implements BatchMountItem {
|
||||
static final String TAG = IntBufferBatchMountItem.class.getSimpleName();
|
||||
|
||||
static final int INSTRUCTION_FLAG_MULTIPLE = 1;
|
||||
|
||||
static final int INSTRUCTION_CREATE = 2;
|
||||
static final int INSTRUCTION_DELETE = 4;
|
||||
static final int INSTRUCTION_INSERT = 8;
|
||||
static final int INSTRUCTION_REMOVE = 16;
|
||||
static final int INSTRUCTION_UPDATE_PROPS = 32;
|
||||
static final int INSTRUCTION_UPDATE_STATE = 64;
|
||||
static final int INSTRUCTION_UPDATE_LAYOUT = 128;
|
||||
static final int INSTRUCTION_UPDATE_EVENT_EMITTER = 256;
|
||||
static final int INSTRUCTION_UPDATE_PADDING = 512;
|
||||
static final int INSTRUCTION_UPDATE_OVERFLOW_INSET = 1024;
|
||||
|
||||
private final int mSurfaceId;
|
||||
private final int mCommitNumber;
|
||||
|
||||
private final int[] mIntBuffer;
|
||||
private final Object[] mObjBuffer;
|
||||
|
||||
private final int mIntBufferLen;
|
||||
private final int mObjBufferLen;
|
||||
|
||||
IntBufferBatchMountItem(int surfaceId, int[] intBuf, Object[] objBuf, int commitNumber) {
|
||||
mSurfaceId = surfaceId;
|
||||
mCommitNumber = commitNumber;
|
||||
|
||||
mIntBuffer = intBuf;
|
||||
mObjBuffer = objBuf;
|
||||
|
||||
mIntBufferLen = mIntBuffer.length;
|
||||
mObjBufferLen = mObjBuffer.length;
|
||||
}
|
||||
|
||||
private void beginMarkers(String reason) {
|
||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT, "IntBufferBatchMountItem::" + reason);
|
||||
|
||||
if (mCommitNumber > 0) {
|
||||
ReactMarker.logFabricMarker(
|
||||
ReactMarkerConstants.FABRIC_BATCH_EXECUTION_START, null, mCommitNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void endMarkers() {
|
||||
if (mCommitNumber > 0) {
|
||||
ReactMarker.logFabricMarker(
|
||||
ReactMarkerConstants.FABRIC_BATCH_EXECUTION_END, null, mCommitNumber);
|
||||
}
|
||||
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(MountingManager mountingManager) {
|
||||
SurfaceMountingManager surfaceMountingManager = mountingManager.getSurfaceManager(mSurfaceId);
|
||||
if (surfaceMountingManager == null) {
|
||||
FLog.e(
|
||||
TAG,
|
||||
"Skipping batch of MountItems; no SurfaceMountingManager found for [%d].",
|
||||
mSurfaceId);
|
||||
return;
|
||||
}
|
||||
if (surfaceMountingManager.isStopped()) {
|
||||
FLog.e(TAG, "Skipping batch of MountItems; was stopped [%d].", mSurfaceId);
|
||||
return;
|
||||
}
|
||||
if (ReactNativeFeatureFlags.enableFabricLogs()) {
|
||||
FLog.d(TAG, "Executing IntBufferBatchMountItem on surface [%d]", mSurfaceId);
|
||||
}
|
||||
|
||||
beginMarkers("mountViews");
|
||||
int i = 0, j = 0;
|
||||
while (i < mIntBufferLen) {
|
||||
int rawType = mIntBuffer[i++];
|
||||
int type = rawType & ~INSTRUCTION_FLAG_MULTIPLE;
|
||||
int numInstructions = ((rawType & INSTRUCTION_FLAG_MULTIPLE) != 0 ? mIntBuffer[i++] : 1);
|
||||
|
||||
String[] args = {"numInstructions", String.valueOf(numInstructions)};
|
||||
|
||||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT,
|
||||
"IntBufferBatchMountItem::mountInstructions::" + nameForInstructionString(type),
|
||||
args,
|
||||
args.length);
|
||||
for (int k = 0; k < numInstructions; k++) {
|
||||
if (type == INSTRUCTION_CREATE) {
|
||||
String componentName = getFabricComponentName((String) mObjBuffer[j++]);
|
||||
surfaceMountingManager.createView(
|
||||
componentName,
|
||||
mIntBuffer[i++],
|
||||
(ReadableMap) mObjBuffer[j++],
|
||||
(StateWrapper) mObjBuffer[j++],
|
||||
(EventEmitterWrapper) mObjBuffer[j++],
|
||||
mIntBuffer[i++] == 1);
|
||||
} else if (type == INSTRUCTION_DELETE) {
|
||||
surfaceMountingManager.deleteView(mIntBuffer[i++]);
|
||||
} else if (type == INSTRUCTION_INSERT) {
|
||||
int tag = mIntBuffer[i++];
|
||||
int parentTag = mIntBuffer[i++];
|
||||
surfaceMountingManager.addViewAt(parentTag, tag, mIntBuffer[i++]);
|
||||
} else if (type == INSTRUCTION_REMOVE) {
|
||||
surfaceMountingManager.removeViewAt(mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]);
|
||||
} else if (type == INSTRUCTION_UPDATE_PROPS) {
|
||||
surfaceMountingManager.updateProps(mIntBuffer[i++], (ReadableMap) mObjBuffer[j++]);
|
||||
} else if (type == INSTRUCTION_UPDATE_STATE) {
|
||||
surfaceMountingManager.updateState(mIntBuffer[i++], (StateWrapper) mObjBuffer[j++]);
|
||||
} else if (type == INSTRUCTION_UPDATE_LAYOUT) {
|
||||
int reactTag = mIntBuffer[i++];
|
||||
int parentTag = mIntBuffer[i++];
|
||||
int x = mIntBuffer[i++];
|
||||
int y = mIntBuffer[i++];
|
||||
int width = mIntBuffer[i++];
|
||||
int height = mIntBuffer[i++];
|
||||
int displayType = mIntBuffer[i++];
|
||||
int layoutDirection = mIntBuffer[i++];
|
||||
surfaceMountingManager.updateLayout(
|
||||
reactTag, parentTag, x, y, width, height, displayType, layoutDirection);
|
||||
} else if (type == INSTRUCTION_UPDATE_PADDING) {
|
||||
surfaceMountingManager.updatePadding(
|
||||
mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]);
|
||||
} else if (type == INSTRUCTION_UPDATE_OVERFLOW_INSET) {
|
||||
int reactTag = mIntBuffer[i++];
|
||||
int overflowInsetLeft = mIntBuffer[i++];
|
||||
int overflowInsetTop = mIntBuffer[i++];
|
||||
int overflowInsetRight = mIntBuffer[i++];
|
||||
int overflowInsetBottom = mIntBuffer[i++];
|
||||
|
||||
surfaceMountingManager.updateOverflowInset(
|
||||
reactTag,
|
||||
overflowInsetLeft,
|
||||
overflowInsetTop,
|
||||
overflowInsetRight,
|
||||
overflowInsetBottom);
|
||||
} else if (type == INSTRUCTION_UPDATE_EVENT_EMITTER) {
|
||||
surfaceMountingManager.updateEventEmitter(
|
||||
mIntBuffer[i++], (EventEmitterWrapper) mObjBuffer[j++]);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid type argument to IntBufferBatchMountItem: " + type + " at index: " + i);
|
||||
}
|
||||
}
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT);
|
||||
}
|
||||
endMarkers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSurfaceId() {
|
||||
return mSurfaceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBatchEmpty() {
|
||||
return mIntBufferLen == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(String.format(Locale.ROOT, "IntBufferBatchMountItem [surface:%d]:\n", mSurfaceId));
|
||||
int i = 0, j = 0;
|
||||
while (i < mIntBufferLen) {
|
||||
int rawType = mIntBuffer[i++];
|
||||
int type = rawType & ~INSTRUCTION_FLAG_MULTIPLE;
|
||||
int numInstructions = ((rawType & INSTRUCTION_FLAG_MULTIPLE) != 0 ? mIntBuffer[i++] : 1);
|
||||
for (int k = 0; k < numInstructions; k++) {
|
||||
if (type == INSTRUCTION_CREATE) {
|
||||
String componentName = getFabricComponentName((String) mObjBuffer[j++]);
|
||||
j += 3;
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"CREATE [%d] - layoutable:%d - %s\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
componentName));
|
||||
} else if (type == INSTRUCTION_DELETE) {
|
||||
s.append(String.format(Locale.ROOT, "DELETE [%d]\n", mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_INSERT) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"INSERT [%d]->[%d] @%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_REMOVE) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"REMOVE [%d]->[%d] @%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_UPDATE_PROPS) {
|
||||
Object props = mObjBuffer[j++];
|
||||
String propsString =
|
||||
IS_DEVELOPMENT_ENVIRONMENT
|
||||
? (props != null ? props.toString() : "<null>")
|
||||
: "<hidden>";
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT, "UPDATE PROPS [%d]: %s\n", mIntBuffer[i++], propsString));
|
||||
} else if (type == INSTRUCTION_UPDATE_STATE) {
|
||||
StateWrapper state = (StateWrapper) mObjBuffer[j++];
|
||||
String stateString =
|
||||
IS_DEVELOPMENT_ENVIRONMENT
|
||||
? (state != null ? state.toString() : "<null>")
|
||||
: "<hidden>";
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT, "UPDATE STATE [%d]: %s\n", mIntBuffer[i++], stateString));
|
||||
} else if (type == INSTRUCTION_UPDATE_LAYOUT) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE LAYOUT [%d]->[%d]: x:%d y:%d w:%d h:%d displayType:%d"
|
||||
+ " layoutDirection:%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_UPDATE_PADDING) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE PADDING [%d]: top:%d right:%d bottom:%d left:%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_UPDATE_OVERFLOW_INSET) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE OVERFLOWINSET [%d]: left:%d top:%d right:%d bottom:%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_UPDATE_EVENT_EMITTER) {
|
||||
j += 1;
|
||||
s.append(String.format(Locale.ROOT, "UPDATE EVENTEMITTER [%d]\n", mIntBuffer[i++]));
|
||||
} else {
|
||||
FLog.e(TAG, "String so far: " + s.toString());
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid type argument to IntBufferBatchMountItem: " + type + " at index: " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
} catch (Exception e) {
|
||||
// Generally, this only happens during development when a malformed buffer is sent through.
|
||||
// In these cases, we print the buffers to assist in debugging.
|
||||
// This should never happen in production, but if it does... it'd still be helpful to know.
|
||||
FLog.e(TAG, "Caught exception trying to print", e);
|
||||
|
||||
StringBuilder ss = new StringBuilder();
|
||||
for (int ii = 0; ii < mIntBufferLen; ii++) {
|
||||
ss.append(mIntBuffer[ii]);
|
||||
ss.append(", ");
|
||||
}
|
||||
FLog.e(TAG, ss.toString());
|
||||
|
||||
for (int jj = 0; jj < mObjBufferLen; jj++) {
|
||||
FLog.e(TAG, mObjBuffer[jj] != null ? mObjBuffer[jj].toString() : "null");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static String nameForInstructionString(int type) {
|
||||
if (type == INSTRUCTION_CREATE) {
|
||||
return "CREATE";
|
||||
} else if (type == INSTRUCTION_DELETE) {
|
||||
return "DELETE";
|
||||
} else if (type == INSTRUCTION_INSERT) {
|
||||
return "INSERT";
|
||||
} else if (type == INSTRUCTION_REMOVE) {
|
||||
return "REMOVE";
|
||||
} else if (type == INSTRUCTION_UPDATE_PROPS) {
|
||||
return "UPDATE_PROPS";
|
||||
} else if (type == INSTRUCTION_UPDATE_STATE) {
|
||||
return "UPDATE_STATE";
|
||||
} else if (type == INSTRUCTION_UPDATE_LAYOUT) {
|
||||
return "UPDATE_LAYOUT";
|
||||
} else if (type == INSTRUCTION_UPDATE_PADDING) {
|
||||
return "UPDATE_PADDING";
|
||||
} else if (type == INSTRUCTION_UPDATE_OVERFLOW_INSET) {
|
||||
return "UPDATE_OVERFLOW_INSET";
|
||||
} else if (type == INSTRUCTION_UPDATE_EVENT_EMITTER) {
|
||||
return "UPDATE_EVENT_EMITTER";
|
||||
} else {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
+335
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* 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.fabric.mounting.mountitems
|
||||
|
||||
import com.facebook.common.logging.FLog
|
||||
import com.facebook.proguard.annotations.DoNotStripAny
|
||||
import com.facebook.react.bridge.ReactMarker
|
||||
import com.facebook.react.bridge.ReactMarkerConstants
|
||||
import com.facebook.react.bridge.ReadableMap
|
||||
import com.facebook.react.fabric.FabricUIManager
|
||||
import com.facebook.react.fabric.events.EventEmitterWrapper
|
||||
import com.facebook.react.fabric.mounting.MountingManager
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
|
||||
import com.facebook.react.uimanager.StateWrapper
|
||||
import com.facebook.systrace.Systrace
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* This class represents a batch of [MountItem]s, represented directly as int buffers to remove the
|
||||
* need for actual MountItem instances.
|
||||
*
|
||||
* An IntBufferBatchMountItem batch contains an array of ints, indicating the mount actions that
|
||||
* should be taken, and a size; as well as an array of Objects, and a corresponding array size, for
|
||||
* any data that cannot be passed as a raw int.
|
||||
*
|
||||
* The purpose of encapsulating the array of MountItems this way, is to reduce the amount of
|
||||
* allocations in C++ and JNI round-trips.
|
||||
*/
|
||||
@DoNotStripAny
|
||||
internal class IntBufferBatchMountItem(
|
||||
private val surfaceId: Int,
|
||||
private val intBuffer: IntArray,
|
||||
private val objBuffer: Array<Any?>,
|
||||
private val commitNumber: Int
|
||||
) : BatchMountItem {
|
||||
private val intBufferLen = intBuffer.size
|
||||
private val objBufferLen = objBuffer.size
|
||||
|
||||
private fun beginMarkers(reason: String) {
|
||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT, "IntBufferBatchMountItem::$reason")
|
||||
|
||||
if (commitNumber > 0) {
|
||||
ReactMarker.logFabricMarker(
|
||||
ReactMarkerConstants.FABRIC_BATCH_EXECUTION_START, null, commitNumber)
|
||||
}
|
||||
}
|
||||
|
||||
private fun endMarkers() {
|
||||
if (commitNumber > 0) {
|
||||
ReactMarker.logFabricMarker(
|
||||
ReactMarkerConstants.FABRIC_BATCH_EXECUTION_END, null, commitNumber)
|
||||
}
|
||||
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT)
|
||||
}
|
||||
|
||||
override fun execute(mountingManager: MountingManager) {
|
||||
val surfaceMountingManager = mountingManager.getSurfaceManager(surfaceId)
|
||||
if (surfaceMountingManager == null) {
|
||||
FLog.e(
|
||||
TAG, "Skipping batch of MountItems; no SurfaceMountingManager found for [%d].", surfaceId)
|
||||
return
|
||||
}
|
||||
if (surfaceMountingManager.isStopped()) {
|
||||
FLog.e(TAG, "Skipping batch of MountItems; was stopped [%d].", surfaceId)
|
||||
return
|
||||
}
|
||||
if (ReactNativeFeatureFlags.enableFabricLogs()) {
|
||||
FLog.d(TAG, "Executing IntBufferBatchMountItem on surface [%d]", surfaceId)
|
||||
}
|
||||
|
||||
beginMarkers("mountViews")
|
||||
var i = 0
|
||||
var j = 0
|
||||
while (i < intBufferLen) {
|
||||
val rawType = intBuffer[i++]
|
||||
val type = rawType and INSTRUCTION_FLAG_MULTIPLE.inv()
|
||||
val numInstructions =
|
||||
(if ((rawType and INSTRUCTION_FLAG_MULTIPLE) != 0) intBuffer[i++] else 1)
|
||||
|
||||
val args = arrayOf("numInstructions", numInstructions.toString())
|
||||
|
||||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT,
|
||||
"IntBufferBatchMountItem::mountInstructions::" + nameForInstructionString(type),
|
||||
args,
|
||||
args.size)
|
||||
for (k in 0 until numInstructions) {
|
||||
when (type) {
|
||||
INSTRUCTION_CREATE -> {
|
||||
val componentName = (objBuffer[j++] as String?).orEmpty()
|
||||
val fabricComponentName =
|
||||
FabricNameComponentMapping.getFabricComponentName(componentName)
|
||||
surfaceMountingManager.createView(
|
||||
fabricComponentName,
|
||||
intBuffer[i++],
|
||||
objBuffer[j++] as ReadableMap?,
|
||||
objBuffer[j++] as StateWrapper?,
|
||||
objBuffer[j++] as EventEmitterWrapper?,
|
||||
intBuffer[i++] == 1)
|
||||
}
|
||||
INSTRUCTION_DELETE -> surfaceMountingManager.deleteView(intBuffer[i++])
|
||||
INSTRUCTION_INSERT -> {
|
||||
val tag = intBuffer[i++]
|
||||
val parentTag = intBuffer[i++]
|
||||
surfaceMountingManager.addViewAt(parentTag, tag, intBuffer[i++])
|
||||
}
|
||||
INSTRUCTION_REMOVE ->
|
||||
surfaceMountingManager.removeViewAt(intBuffer[i++], intBuffer[i++], intBuffer[i++])
|
||||
INSTRUCTION_UPDATE_PROPS ->
|
||||
surfaceMountingManager.updateProps(intBuffer[i++], objBuffer[j++] as ReadableMap?)
|
||||
INSTRUCTION_UPDATE_STATE ->
|
||||
surfaceMountingManager.updateState(intBuffer[i++], objBuffer[j++] as StateWrapper?)
|
||||
INSTRUCTION_UPDATE_LAYOUT -> {
|
||||
val reactTag = intBuffer[i++]
|
||||
val parentTag = intBuffer[i++]
|
||||
val x = intBuffer[i++]
|
||||
val y = intBuffer[i++]
|
||||
val width = intBuffer[i++]
|
||||
val height = intBuffer[i++]
|
||||
val displayType = intBuffer[i++]
|
||||
val layoutDirection = intBuffer[i++]
|
||||
surfaceMountingManager.updateLayout(
|
||||
reactTag, parentTag, x, y, width, height, displayType, layoutDirection)
|
||||
}
|
||||
INSTRUCTION_UPDATE_PADDING ->
|
||||
surfaceMountingManager.updatePadding(
|
||||
intBuffer[i++], intBuffer[i++], intBuffer[i++], intBuffer[i++], intBuffer[i++])
|
||||
INSTRUCTION_UPDATE_OVERFLOW_INSET -> {
|
||||
val reactTag = intBuffer[i++]
|
||||
val overflowInsetLeft = intBuffer[i++]
|
||||
val overflowInsetTop = intBuffer[i++]
|
||||
val overflowInsetRight = intBuffer[i++]
|
||||
val overflowInsetBottom = intBuffer[i++]
|
||||
|
||||
surfaceMountingManager.updateOverflowInset(
|
||||
reactTag,
|
||||
overflowInsetLeft,
|
||||
overflowInsetTop,
|
||||
overflowInsetRight,
|
||||
overflowInsetBottom)
|
||||
}
|
||||
INSTRUCTION_UPDATE_EVENT_EMITTER -> {
|
||||
val eventEmitterWrapper = objBuffer[j++] as EventEmitterWrapper?
|
||||
if (eventEmitterWrapper != null) {
|
||||
surfaceMountingManager.updateEventEmitter(intBuffer[i++], eventEmitterWrapper)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
throw IllegalArgumentException(
|
||||
"Invalid type argument to IntBufferBatchMountItem: $type at index: $i")
|
||||
}
|
||||
}
|
||||
}
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT)
|
||||
}
|
||||
endMarkers()
|
||||
}
|
||||
|
||||
override fun getSurfaceId(): Int = surfaceId
|
||||
|
||||
override fun isBatchEmpty(): Boolean = intBufferLen == 0
|
||||
|
||||
override fun toString(): String {
|
||||
try {
|
||||
val s = StringBuilder()
|
||||
s.append(String.format(Locale.ROOT, "IntBufferBatchMountItem [surface:%d]:\n", surfaceId))
|
||||
var i = 0
|
||||
var j = 0
|
||||
while (i < intBufferLen) {
|
||||
val rawType = intBuffer[i++]
|
||||
val type = rawType and INSTRUCTION_FLAG_MULTIPLE.inv()
|
||||
val numInstructions =
|
||||
(if ((rawType and INSTRUCTION_FLAG_MULTIPLE) != 0) intBuffer[i++] else 1)
|
||||
for (k in 0 until numInstructions) {
|
||||
when (type) {
|
||||
INSTRUCTION_CREATE -> {
|
||||
val componentName = (objBuffer[j++] as String?).orEmpty()
|
||||
val fabricComponentName =
|
||||
FabricNameComponentMapping.getFabricComponentName(componentName)
|
||||
|
||||
j += 3
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"CREATE [%d] - layoutable:%d - %s\n",
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
fabricComponentName))
|
||||
}
|
||||
INSTRUCTION_DELETE ->
|
||||
s.append(String.format(Locale.ROOT, "DELETE [%d]\n", intBuffer[i++]))
|
||||
INSTRUCTION_INSERT ->
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"INSERT [%d]->[%d] @%d\n",
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++]))
|
||||
INSTRUCTION_REMOVE ->
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"REMOVE [%d]->[%d] @%d\n",
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++]))
|
||||
INSTRUCTION_UPDATE_PROPS -> {
|
||||
val props = objBuffer[j++]
|
||||
val propsString =
|
||||
if (FabricUIManager.IS_DEVELOPMENT_ENVIRONMENT) (props?.toString() ?: "<null>")
|
||||
else "<hidden>"
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT, "UPDATE PROPS [%d]: %s\n", intBuffer[i++], propsString))
|
||||
}
|
||||
INSTRUCTION_UPDATE_STATE -> {
|
||||
val state: StateWrapper? = objBuffer[j++] as StateWrapper?
|
||||
val stateString =
|
||||
if (FabricUIManager.IS_DEVELOPMENT_ENVIRONMENT) (state?.toString() ?: "<null>")
|
||||
else "<hidden>"
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT, "UPDATE STATE [%d]: %s\n", intBuffer[i++], stateString))
|
||||
}
|
||||
INSTRUCTION_UPDATE_LAYOUT ->
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE LAYOUT [%d]->[%d]: x:%d y:%d w:%d h:%d displayType:%d" +
|
||||
" layoutDirection:%d\n",
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++]))
|
||||
INSTRUCTION_UPDATE_PADDING ->
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE PADDING [%d]: top:%d right:%d bottom:%d left:%d\n",
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++]))
|
||||
INSTRUCTION_UPDATE_OVERFLOW_INSET ->
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE OVERFLOWINSET [%d]: left:%d top:%d right:%d bottom:%d\n",
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++],
|
||||
intBuffer[i++]))
|
||||
INSTRUCTION_UPDATE_EVENT_EMITTER -> {
|
||||
j += 1
|
||||
s.append(String.format(Locale.ROOT, "UPDATE EVENTEMITTER [%d]\n", intBuffer[i++]))
|
||||
}
|
||||
else -> {
|
||||
FLog.e(TAG, "String so far: $s")
|
||||
throw IllegalArgumentException(
|
||||
"Invalid type argument to IntBufferBatchMountItem: $type at index: $i")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return s.toString()
|
||||
} catch (e: Exception) {
|
||||
// Generally, this only happens during development when a malformed buffer is sent through.
|
||||
// In these cases, we print the buffers to assist in debugging.
|
||||
// This should never happen in production, but if it does... it'd still be helpful to know.
|
||||
FLog.e(TAG, "Caught exception trying to print", e)
|
||||
|
||||
val ss = StringBuilder()
|
||||
var ii = 0
|
||||
while (ii < intBufferLen) {
|
||||
ss.append(intBuffer[ii])
|
||||
ss.append(", ")
|
||||
ii++
|
||||
}
|
||||
FLog.e(TAG, ss.toString())
|
||||
|
||||
var jj = 0
|
||||
while (jj < objBufferLen) {
|
||||
FLog.e(TAG, if (objBuffer[jj] != null) objBuffer[jj].toString() else "null")
|
||||
jj++
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG: String = IntBufferBatchMountItem::class.java.simpleName
|
||||
|
||||
const val INSTRUCTION_FLAG_MULTIPLE: Int = 1
|
||||
|
||||
const val INSTRUCTION_CREATE: Int = 2
|
||||
const val INSTRUCTION_DELETE: Int = 4
|
||||
const val INSTRUCTION_INSERT: Int = 8
|
||||
const val INSTRUCTION_REMOVE: Int = 16
|
||||
const val INSTRUCTION_UPDATE_PROPS: Int = 32
|
||||
const val INSTRUCTION_UPDATE_STATE: Int = 64
|
||||
const val INSTRUCTION_UPDATE_LAYOUT: Int = 128
|
||||
const val INSTRUCTION_UPDATE_EVENT_EMITTER: Int = 256
|
||||
const val INSTRUCTION_UPDATE_PADDING: Int = 512
|
||||
const val INSTRUCTION_UPDATE_OVERFLOW_INSET: Int = 1024
|
||||
|
||||
private fun nameForInstructionString(type: Int): String =
|
||||
when (type) {
|
||||
INSTRUCTION_CREATE -> "CREATE"
|
||||
INSTRUCTION_DELETE -> "DELETE"
|
||||
INSTRUCTION_INSERT -> "INSERT"
|
||||
INSTRUCTION_REMOVE -> "REMOVE"
|
||||
INSTRUCTION_UPDATE_PROPS -> "UPDATE_PROPS"
|
||||
INSTRUCTION_UPDATE_STATE -> "UPDATE_STATE"
|
||||
INSTRUCTION_UPDATE_LAYOUT -> "UPDATE_LAYOUT"
|
||||
INSTRUCTION_UPDATE_PADDING -> "UPDATE_PADDING"
|
||||
INSTRUCTION_UPDATE_OVERFLOW_INSET -> "UPDATE_OVERFLOW_INSET"
|
||||
INSTRUCTION_UPDATE_EVENT_EMITTER -> "UPDATE_EVENT_EMITTER"
|
||||
else -> "UNKNOWN"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user