mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Ship IntBufferBatchMountItem experiment
Summary: This experiment has been successfully running for several weeks and show small but statsig perf improvements. Delete the old code and ship this 100% in code to simplify Fabric code. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D25775668 fbshipit-source-id: d2b41dfe691775e52b1e89c2fb6790a6500e560e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a2164f429a
commit
0db56f1888
@@ -18,21 +18,13 @@ import com.facebook.react.fabric.events.EventEmitterWrapper;
|
||||
import com.facebook.react.fabric.events.FabricEventEmitter;
|
||||
import com.facebook.react.fabric.mounting.LayoutMetricsConversions;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.fabric.mounting.mountitems.BatchMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.CreateMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchIntCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchStringCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.InsertMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.MountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.PreAllocateViewMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.RemoveDeleteMultiMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.SendAccessibilityEvent;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateEventEmitterMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateLayoutMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdatePaddingMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdatePropsMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateStateMountItem;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.events.BatchEventDispatchedListener;
|
||||
@@ -107,21 +99,12 @@ public class FabricJSIModuleProvider implements JSIModuleProvider<UIManager> {
|
||||
EventBeatManager.class.getClass();
|
||||
EventEmitterWrapper.class.getClass();
|
||||
FabricEventEmitter.class.getClass();
|
||||
BatchMountItem.class.getClass();
|
||||
CreateMountItem.class.getClass();
|
||||
DispatchCommandMountItem.class.getClass();
|
||||
DispatchIntCommandMountItem.class.getClass();
|
||||
DispatchStringCommandMountItem.class.getClass();
|
||||
InsertMountItem.class.getClass();
|
||||
MountItem.class.getClass();
|
||||
PreAllocateViewMountItem.class.getClass();
|
||||
RemoveDeleteMultiMountItem.class.getClass();
|
||||
SendAccessibilityEvent.class.getClass();
|
||||
UpdateEventEmitterMountItem.class.getClass();
|
||||
UpdateLayoutMountItem.class.getClass();
|
||||
UpdatePaddingMountItem.class.getClass();
|
||||
UpdatePropsMountItem.class.getClass();
|
||||
UpdateStateMountItem.class.getClass();
|
||||
LayoutMetricsConversions.class.getClass();
|
||||
MountingManager.class.getClass();
|
||||
Binding.class.getClass();
|
||||
@@ -134,5 +117,6 @@ public class FabricJSIModuleProvider implements JSIModuleProvider<UIManager> {
|
||||
StateWrapperImpl.class.getClass();
|
||||
BatchEventDispatchedListener.class.getClass();
|
||||
ReactNativeConfig.class.getClass();
|
||||
IntBufferBatchMountItem.class.getClass();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,22 +57,13 @@ import com.facebook.react.fabric.events.EventBeatManager;
|
||||
import com.facebook.react.fabric.events.EventEmitterWrapper;
|
||||
import com.facebook.react.fabric.events.FabricEventEmitter;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.fabric.mounting.mountitems.BatchMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.CreateMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchIntCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.DispatchStringCommandMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.InsertMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.MountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.PreAllocateViewMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.RemoveDeleteMultiMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.SendAccessibilityEvent;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateEventEmitterMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateLayoutMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdatePaddingMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdatePropsMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateStateMountItem;
|
||||
import com.facebook.react.modules.core.ReactChoreographer;
|
||||
import com.facebook.react.modules.i18nmanager.I18nUtil;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
@@ -352,100 +343,6 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
isLayoutable));
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem createMountItem(
|
||||
String componentName,
|
||||
@Nullable ReadableMap props,
|
||||
@Nullable Object stateWrapper,
|
||||
int reactRootTag,
|
||||
int reactTag,
|
||||
boolean isLayoutable) {
|
||||
String component = getFabricComponentName(componentName);
|
||||
|
||||
// This could be null if teardown/navigation away from a surface on the main thread happens
|
||||
// while a commit is being processed in a different thread. By contract we expect this to be
|
||||
// possible at teardown, but this race should *never* happen at startup.
|
||||
@Nullable ThemedReactContext reactContext = mReactContextForRootTag.get(reactRootTag);
|
||||
|
||||
return new CreateMountItem(
|
||||
reactContext,
|
||||
reactRootTag,
|
||||
reactTag,
|
||||
component,
|
||||
props,
|
||||
(StateWrapper) stateWrapper,
|
||||
isLayoutable);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem insertMountItem(int reactTag, int parentReactTag, int index) {
|
||||
return new InsertMountItem(reactTag, parentReactTag, index);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem removeDeleteMultiMountItem(int[] metadata) {
|
||||
return new RemoveDeleteMultiMountItem(metadata);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem updateLayoutMountItem(
|
||||
int reactTag, int x, int y, int width, int height, int layoutDirection) {
|
||||
return new UpdateLayoutMountItem(reactTag, x, y, width, height, layoutDirection);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem updatePaddingMountItem(int reactTag, int left, int top, int right, int bottom) {
|
||||
return new UpdatePaddingMountItem(reactTag, left, top, right, bottom);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem updatePropsMountItem(int reactTag, ReadableMap map) {
|
||||
return new UpdatePropsMountItem(reactTag, map);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem updateStateMountItem(int reactTag, @Nullable Object stateWrapper) {
|
||||
return new UpdateStateMountItem(reactTag, (StateWrapper) stateWrapper);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem updateEventEmitterMountItem(int reactTag, Object eventEmitter) {
|
||||
return new UpdateEventEmitterMountItem(reactTag, (EventEmitterWrapper) eventEmitter);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private MountItem createBatchMountItem(
|
||||
int rootTag, MountItem[] items, int size, int commitNumber) {
|
||||
return new BatchMountItem(rootTag, items, size, commitNumber);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@AnyThread
|
||||
@@ -599,7 +496,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
try {
|
||||
updatePropsMountItem(reactTag, props).execute(mountingManager);
|
||||
mountingManager.updateProps(reactTag, props);
|
||||
} catch (Exception ex) {
|
||||
// TODO T42943890: Fix animations in Fabric and remove this try/catch
|
||||
ReactSoftException.logSoftException(
|
||||
@@ -664,12 +561,9 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
// When Binding.cpp calls scheduleMountItems during a commit phase, it always calls with
|
||||
// a BatchMountItem. No other sites call into this with a BatchMountItem, and Binding.cpp only
|
||||
// calls scheduleMountItems with a BatchMountItem.
|
||||
boolean isClassicBatchMountItem = mountItem instanceof BatchMountItem;
|
||||
boolean isIntBufferMountItem = mountItem instanceof IntBufferBatchMountItem;
|
||||
boolean isBatchMountItem = isClassicBatchMountItem || isIntBufferMountItem;
|
||||
boolean isBatchMountItem = mountItem instanceof IntBufferBatchMountItem;
|
||||
boolean shouldSchedule =
|
||||
(isClassicBatchMountItem && ((BatchMountItem) mountItem).shouldSchedule())
|
||||
|| (isIntBufferMountItem && ((IntBufferBatchMountItem) mountItem).shouldSchedule())
|
||||
(isBatchMountItem && ((IntBufferBatchMountItem) mountItem).shouldSchedule())
|
||||
|| (!isBatchMountItem && mountItem != null);
|
||||
|
||||
// In case of sync rendering, this could be called on the UI thread. Otherwise,
|
||||
@@ -939,16 +833,6 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
}
|
||||
|
||||
try {
|
||||
// Make sure surface associated with this MountItem has been started, and not stopped.
|
||||
// TODO T68118357: clean up this logic and simplify this method overall
|
||||
if (mountItem instanceof BatchMountItem) {
|
||||
BatchMountItem batchMountItem = (BatchMountItem) mountItem;
|
||||
if (!isSurfaceActiveForExecution(
|
||||
batchMountItem.getRootTag(), "dispatchMountItems BatchMountItem")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure surface associated with this MountItem has been started, and not stopped.
|
||||
// TODO T68118357: clean up this logic and simplify this method overall
|
||||
if (mountItem instanceof IntBufferBatchMountItem) {
|
||||
|
||||
@@ -437,9 +437,6 @@ void Binding::installFabricUIManager(
|
||||
// Keep reference to config object and cache some feature flags here
|
||||
reactNativeConfig_ = config;
|
||||
|
||||
useIntBufferBatchMountItem_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:use_int_buffer_batch_mountitem_android");
|
||||
|
||||
disablePreallocateViews_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:disabled_view_preallocation_android");
|
||||
|
||||
@@ -506,226 +503,7 @@ local_ref<JString> getPlatformComponentName(const ShadowView &shadowView) {
|
||||
return componentName;
|
||||
}
|
||||
|
||||
local_ref<JMountItem::javaobject> createUpdateEventEmitterMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const ShadowViewMutation &mutation) {
|
||||
if (!mutation.newChildShadowView.eventEmitter) {
|
||||
return nullptr;
|
||||
}
|
||||
SharedEventEmitter eventEmitter = mutation.newChildShadowView.eventEmitter;
|
||||
|
||||
// Do not hold a reference to javaEventEmitter from the C++ side.
|
||||
auto javaEventEmitter = EventEmitterWrapper::newObjectJavaArgs();
|
||||
EventEmitterWrapper *cEventEmitter = cthis(javaEventEmitter);
|
||||
cEventEmitter->eventEmitter = eventEmitter;
|
||||
|
||||
static auto updateEventEmitterInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(jint, jobject)>(
|
||||
"updateEventEmitterMountItem");
|
||||
|
||||
return updateEventEmitterInstruction(
|
||||
javaUIManager, mutation.newChildShadowView.tag, javaEventEmitter.get());
|
||||
}
|
||||
|
||||
local_ref<JMountItem::javaobject> createUpdatePropsMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const ShadowViewMutation &mutation) {
|
||||
auto shadowView = mutation.newChildShadowView;
|
||||
|
||||
// TODO: move props from map to a typed object.
|
||||
auto newProps = shadowView.props->rawProps;
|
||||
|
||||
local_ref<ReadableMap::javaobject> readableMap =
|
||||
castReadableMap(ReadableNativeMap::newObjectCxxArgs(newProps));
|
||||
static auto updatePropsInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(jint, ReadableMap::javaobject)>(
|
||||
"updatePropsMountItem");
|
||||
|
||||
return updatePropsInstruction(
|
||||
javaUIManager, mutation.newChildShadowView.tag, readableMap.get());
|
||||
}
|
||||
|
||||
local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const ShadowViewMutation &mutation) {
|
||||
auto oldChildShadowView = mutation.oldChildShadowView;
|
||||
auto newChildShadowView = mutation.newChildShadowView;
|
||||
|
||||
if (newChildShadowView.layoutMetrics != EmptyLayoutMetrics &&
|
||||
oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) {
|
||||
static auto updateLayoutInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(
|
||||
jint, jint, jint, jint, jint, jint)>("updateLayoutMountItem");
|
||||
auto layoutMetrics = newChildShadowView.layoutMetrics;
|
||||
auto pointScaleFactor = layoutMetrics.pointScaleFactor;
|
||||
auto frame = layoutMetrics.frame;
|
||||
|
||||
int x = round(frame.origin.x * pointScaleFactor);
|
||||
int y = round(frame.origin.y * pointScaleFactor);
|
||||
int w = round(frame.size.width * pointScaleFactor);
|
||||
int h = round(frame.size.height * pointScaleFactor);
|
||||
auto layoutDirection =
|
||||
toInt(newChildShadowView.layoutMetrics.layoutDirection);
|
||||
return updateLayoutInstruction(
|
||||
javaUIManager, newChildShadowView.tag, x, y, w, h, layoutDirection);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
local_ref<JMountItem::javaobject> createUpdatePaddingMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const ShadowViewMutation &mutation) {
|
||||
auto oldChildShadowView = mutation.oldChildShadowView;
|
||||
auto newChildShadowView = mutation.newChildShadowView;
|
||||
|
||||
if (oldChildShadowView.layoutMetrics.contentInsets ==
|
||||
newChildShadowView.layoutMetrics.contentInsets &&
|
||||
mutation.type != ShadowViewMutation::Type::Insert) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static auto updatePaddingInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(jint, jint, jint, jint, jint)>(
|
||||
"updatePaddingMountItem");
|
||||
|
||||
auto layoutMetrics = newChildShadowView.layoutMetrics;
|
||||
auto pointScaleFactor = layoutMetrics.pointScaleFactor;
|
||||
auto contentInsets = layoutMetrics.contentInsets;
|
||||
|
||||
int left = floor(contentInsets.left * pointScaleFactor);
|
||||
int top = floor(contentInsets.top * pointScaleFactor);
|
||||
int right = floor(contentInsets.right * pointScaleFactor);
|
||||
int bottom = floor(contentInsets.bottom * pointScaleFactor);
|
||||
|
||||
return updatePaddingInstruction(
|
||||
javaUIManager, newChildShadowView.tag, left, top, right, bottom);
|
||||
}
|
||||
|
||||
local_ref<JMountItem::javaobject> createInsertMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const ShadowViewMutation &mutation) {
|
||||
static auto insertInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(jint, jint, jint)>(
|
||||
"insertMountItem");
|
||||
|
||||
return insertInstruction(
|
||||
javaUIManager,
|
||||
mutation.newChildShadowView.tag,
|
||||
mutation.parentShadowView.tag,
|
||||
mutation.index);
|
||||
}
|
||||
|
||||
local_ref<JMountItem::javaobject> createUpdateStateMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const ShadowViewMutation &mutation) {
|
||||
static auto updateStateInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(jint, jobject)>(
|
||||
"updateStateMountItem");
|
||||
|
||||
auto state = mutation.newChildShadowView.state;
|
||||
|
||||
// Do not hold onto Java object from C
|
||||
// We DO want to hold onto C object from Java, since we don't know the
|
||||
// lifetime of the Java object
|
||||
local_ref<StateWrapperImpl::JavaPart> javaStateWrapper = nullptr;
|
||||
if (state != nullptr) {
|
||||
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl *cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = state;
|
||||
}
|
||||
|
||||
return updateStateInstruction(
|
||||
javaUIManager,
|
||||
mutation.newChildShadowView.tag,
|
||||
(javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr));
|
||||
}
|
||||
|
||||
local_ref<JMountItem::javaobject> createRemoveAndDeleteMultiMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const std::vector<RemoveDeleteMetadata> &metadata) {
|
||||
auto env = Environment::current();
|
||||
auto removeAndDeleteArray = env->NewIntArray(metadata.size() * 4);
|
||||
int position = 0;
|
||||
jint temp[4];
|
||||
for (const auto &x : metadata) {
|
||||
temp[0] = x.tag;
|
||||
temp[1] = x.parentTag;
|
||||
temp[2] = x.index;
|
||||
temp[3] = (x.shouldRemove ? 1 : 0) | (x.shouldDelete ? 2 : 0);
|
||||
env->SetIntArrayRegion(removeAndDeleteArray, position, 4, temp);
|
||||
position += 4;
|
||||
}
|
||||
|
||||
static auto removeDeleteMultiInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(jintArray)>(
|
||||
"removeDeleteMultiMountItem");
|
||||
|
||||
auto ret = removeDeleteMultiInstruction(javaUIManager, removeAndDeleteArray);
|
||||
|
||||
// It is not strictly necessary to manually delete the ref here, in this
|
||||
// particular case. If JNI memory is being allocated in a loop, it's easy to
|
||||
// overload the localref table and crash; this is not possible in this case
|
||||
// since the JNI would automatically clear this ref when it goes out of scope,
|
||||
// anyway. However, this is being left here as a reminder of good hygiene and
|
||||
// to be careful with JNI-allocated memory in general.
|
||||
env->DeleteLocalRef(removeAndDeleteArray);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO T48019320: because we pass initial props and state to the Create (and
|
||||
// preallocate) mount instruction, we technically don't need to pass the first
|
||||
// Update to any components. Dedupe?
|
||||
local_ref<JMountItem::javaobject> createCreateMountItem(
|
||||
const jni::global_ref<jobject> &javaUIManager,
|
||||
const ShadowViewMutation &mutation,
|
||||
const Tag surfaceId) {
|
||||
static auto createJavaInstruction =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(
|
||||
jstring, ReadableMap::javaobject, jobject, jint, jint, jboolean)>(
|
||||
"createMountItem");
|
||||
|
||||
auto newChildShadowView = mutation.newChildShadowView;
|
||||
|
||||
local_ref<JString> componentName =
|
||||
getPlatformComponentName(newChildShadowView);
|
||||
|
||||
jboolean isLayoutable =
|
||||
newChildShadowView.layoutMetrics != EmptyLayoutMetrics;
|
||||
|
||||
local_ref<ReadableMap::javaobject> props = castReadableMap(
|
||||
ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps));
|
||||
|
||||
// Do not hold onto Java object from C
|
||||
// We DO want to hold onto C object from Java, since we don't know the
|
||||
// lifetime of the Java object
|
||||
local_ref<StateWrapperImpl::JavaPart> javaStateWrapper = nullptr;
|
||||
if (newChildShadowView.state != nullptr) {
|
||||
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl *cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = newChildShadowView.state;
|
||||
}
|
||||
|
||||
return createJavaInstruction(
|
||||
javaUIManager,
|
||||
componentName.get(),
|
||||
props.get(),
|
||||
(javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr),
|
||||
surfaceId,
|
||||
newChildShadowView.tag,
|
||||
isLayoutable);
|
||||
}
|
||||
|
||||
void Binding::schedulerDidFinishTransactionIntBuffer(
|
||||
void Binding::schedulerDidFinishTransaction(
|
||||
MountingCoordinator::Shared const &mountingCoordinator) {
|
||||
std::lock_guard<std::recursive_mutex> lock(commitMutex_);
|
||||
|
||||
@@ -1183,251 +961,6 @@ void Binding::schedulerDidFinishTransactionIntBuffer(
|
||||
env->DeleteLocalRef(intBufferArray);
|
||||
}
|
||||
|
||||
void Binding::schedulerDidFinishTransaction(
|
||||
MountingCoordinator::Shared const &mountingCoordinator) {
|
||||
std::lock_guard<std::recursive_mutex> lock(commitMutex_);
|
||||
|
||||
if (useIntBufferBatchMountItem_) {
|
||||
return schedulerDidFinishTransactionIntBuffer(mountingCoordinator);
|
||||
}
|
||||
|
||||
SystraceSection s("FabricUIManagerBinding::schedulerDidFinishTransaction");
|
||||
auto finishTransactionStartTime = telemetryTimePointNow();
|
||||
|
||||
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
||||
if (!localJavaUIManager) {
|
||||
LOG(ERROR)
|
||||
<< "Binding::schedulerDidFinishTransaction: JavaUIManager disappeared";
|
||||
return;
|
||||
}
|
||||
|
||||
auto mountingTransaction = mountingCoordinator->pullTransaction();
|
||||
|
||||
if (!mountingTransaction.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto telemetry = mountingTransaction->getTelemetry();
|
||||
auto surfaceId = mountingTransaction->getSurfaceId();
|
||||
auto &mutations = mountingTransaction->getMutations();
|
||||
|
||||
auto revisionNumber = telemetry.getRevisionNumber();
|
||||
|
||||
std::vector<local_ref<jobject>> queue;
|
||||
// Upper bound estimation of mount items to be delivered to Java side.
|
||||
int size = mutations.size() * 3 + 42;
|
||||
|
||||
local_ref<JArrayClass<JMountItem::javaobject>> mountItemsArray =
|
||||
JArrayClass<JMountItem::javaobject>::newArray(size);
|
||||
|
||||
auto mountItems = *(mountItemsArray);
|
||||
std::unordered_set<Tag> deletedViewTags;
|
||||
|
||||
// Find the set of tags that are removed and deleted in one block
|
||||
std::vector<RemoveDeleteMetadata> toRemove;
|
||||
|
||||
int position = 0;
|
||||
for (const auto &mutation : mutations) {
|
||||
auto oldChildShadowView = mutation.oldChildShadowView;
|
||||
auto newChildShadowView = mutation.newChildShadowView;
|
||||
|
||||
bool isVirtual = newChildShadowView.layoutMetrics == EmptyLayoutMetrics &&
|
||||
oldChildShadowView.layoutMetrics == EmptyLayoutMetrics;
|
||||
|
||||
// Handle accumulated removals/deletions
|
||||
if (mutation.type != ShadowViewMutation::Remove &&
|
||||
mutation.type != ShadowViewMutation::Delete) {
|
||||
if (toRemove.size() > 0) {
|
||||
mountItems[position++] =
|
||||
createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
|
||||
toRemove.clear();
|
||||
}
|
||||
}
|
||||
|
||||
switch (mutation.type) {
|
||||
case ShadowViewMutation::Create: {
|
||||
if (disablePreallocateViews_ ||
|
||||
mutation.newChildShadowView.props->revision > 1 ||
|
||||
deletedViewTags.find(mutation.newChildShadowView.tag) !=
|
||||
deletedViewTags.end()) {
|
||||
mountItems[position++] =
|
||||
createCreateMountItem(localJavaUIManager, mutation, surfaceId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ShadowViewMutation::Remove: {
|
||||
if (!isVirtual) {
|
||||
toRemove.push_back(
|
||||
RemoveDeleteMetadata{mutation.oldChildShadowView.tag,
|
||||
mutation.parentShadowView.tag,
|
||||
mutation.index,
|
||||
true,
|
||||
false});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ShadowViewMutation::Delete: {
|
||||
// It is impossible to delete without removing node first
|
||||
const auto &it = std::find_if(
|
||||
std::begin(toRemove),
|
||||
std::end(toRemove),
|
||||
[&mutation](const auto &x) {
|
||||
return x.tag == mutation.oldChildShadowView.tag;
|
||||
});
|
||||
|
||||
if (it != std::end(toRemove)) {
|
||||
it->shouldDelete = true;
|
||||
} else {
|
||||
toRemove.push_back(RemoveDeleteMetadata{
|
||||
mutation.oldChildShadowView.tag, -1, -1, false, true});
|
||||
}
|
||||
|
||||
deletedViewTags.insert(mutation.oldChildShadowView.tag);
|
||||
break;
|
||||
}
|
||||
case ShadowViewMutation::Update: {
|
||||
if (!isVirtual) {
|
||||
if (mutation.oldChildShadowView.props !=
|
||||
mutation.newChildShadowView.props) {
|
||||
mountItems[position++] =
|
||||
createUpdatePropsMountItem(localJavaUIManager, mutation);
|
||||
}
|
||||
if (mutation.oldChildShadowView.state !=
|
||||
mutation.newChildShadowView.state) {
|
||||
mountItems[position++] =
|
||||
createUpdateStateMountItem(localJavaUIManager, mutation);
|
||||
}
|
||||
|
||||
// Padding: padding mountItems must be executed before layout props
|
||||
// are updated in the view. This is necessary to ensure that events
|
||||
// (resulting from layout changes) are dispatched with the correct
|
||||
// padding information.
|
||||
auto updatePaddingMountItem =
|
||||
createUpdatePaddingMountItem(localJavaUIManager, mutation);
|
||||
if (updatePaddingMountItem) {
|
||||
mountItems[position++] = updatePaddingMountItem;
|
||||
}
|
||||
|
||||
auto updateLayoutMountItem =
|
||||
createUpdateLayoutMountItem(localJavaUIManager, mutation);
|
||||
if (updateLayoutMountItem) {
|
||||
mountItems[position++] = updateLayoutMountItem;
|
||||
}
|
||||
}
|
||||
|
||||
if (mutation.oldChildShadowView.eventEmitter !=
|
||||
mutation.newChildShadowView.eventEmitter) {
|
||||
auto updateEventEmitterMountItem =
|
||||
createUpdateEventEmitterMountItem(localJavaUIManager, mutation);
|
||||
if (updateEventEmitterMountItem) {
|
||||
mountItems[position++] = updateEventEmitterMountItem;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ShadowViewMutation::Insert: {
|
||||
if (!isVirtual) {
|
||||
// Insert item
|
||||
mountItems[position++] =
|
||||
createInsertMountItem(localJavaUIManager, mutation);
|
||||
|
||||
if (disablePreallocateViews_ ||
|
||||
mutation.newChildShadowView.props->revision > 1 ||
|
||||
deletedViewTags.find(mutation.newChildShadowView.tag) !=
|
||||
deletedViewTags.end()) {
|
||||
mountItems[position++] =
|
||||
createUpdatePropsMountItem(localJavaUIManager, mutation);
|
||||
}
|
||||
|
||||
// State
|
||||
if (mutation.newChildShadowView.state) {
|
||||
mountItems[position++] =
|
||||
createUpdateStateMountItem(localJavaUIManager, mutation);
|
||||
}
|
||||
|
||||
// Padding: padding mountItems must be executed before layout props
|
||||
// are updated in the view. This is necessary to ensure that events
|
||||
// (resulting from layout changes) are dispatched with the correct
|
||||
// padding information.
|
||||
auto updatePaddingMountItem =
|
||||
createUpdatePaddingMountItem(localJavaUIManager, mutation);
|
||||
if (updatePaddingMountItem) {
|
||||
mountItems[position++] = updatePaddingMountItem;
|
||||
}
|
||||
|
||||
// Layout
|
||||
auto updateLayoutMountItem =
|
||||
createUpdateLayoutMountItem(localJavaUIManager, mutation);
|
||||
if (updateLayoutMountItem) {
|
||||
mountItems[position++] = updateLayoutMountItem;
|
||||
}
|
||||
}
|
||||
|
||||
// EventEmitter
|
||||
auto updateEventEmitterMountItem =
|
||||
createUpdateEventEmitterMountItem(localJavaUIManager, mutation);
|
||||
if (updateEventEmitterMountItem) {
|
||||
mountItems[position++] = updateEventEmitterMountItem;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle remaining removals and deletions
|
||||
if (toRemove.size() > 0) {
|
||||
mountItems[position++] =
|
||||
createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
|
||||
toRemove.clear();
|
||||
}
|
||||
|
||||
static auto createMountItemsBatchContainer =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<alias_ref<JMountItem>(
|
||||
jint, jtypeArray<JMountItem::javaobject>, jint, jint)>(
|
||||
"createBatchMountItem");
|
||||
|
||||
// If there are no items, we pass a nullptr instead of passing the object
|
||||
// through the JNI
|
||||
auto batch = createMountItemsBatchContainer(
|
||||
localJavaUIManager,
|
||||
surfaceId,
|
||||
position == 0 ? nullptr : mountItemsArray.get(),
|
||||
position,
|
||||
revisionNumber);
|
||||
|
||||
static auto scheduleMountItem =
|
||||
jni::findClassStatic(Binding::UIManagerJavaDescriptor)
|
||||
->getMethod<void(
|
||||
JMountItem::javaobject,
|
||||
jint,
|
||||
jlong,
|
||||
jlong,
|
||||
jlong,
|
||||
jlong,
|
||||
jlong,
|
||||
jlong,
|
||||
jlong)>("scheduleMountItem");
|
||||
|
||||
auto finishTransactionEndTime = telemetryTimePointNow();
|
||||
|
||||
scheduleMountItem(
|
||||
localJavaUIManager,
|
||||
batch.get(),
|
||||
telemetry.getRevisionNumber(),
|
||||
telemetryTimePointToMilliseconds(telemetry.getCommitStartTime()),
|
||||
telemetryTimePointToMilliseconds(telemetry.getDiffStartTime()),
|
||||
telemetryTimePointToMilliseconds(telemetry.getDiffEndTime()),
|
||||
telemetryTimePointToMilliseconds(telemetry.getLayoutStartTime()),
|
||||
telemetryTimePointToMilliseconds(telemetry.getLayoutEndTime()),
|
||||
telemetryTimePointToMilliseconds(finishTransactionStartTime),
|
||||
telemetryTimePointToMilliseconds(finishTransactionEndTime));
|
||||
}
|
||||
|
||||
void Binding::setPixelDensity(float pointScaleFactor) {
|
||||
pointScaleFactor_ = pointScaleFactor;
|
||||
}
|
||||
|
||||
@@ -169,14 +169,9 @@ class Binding : public jni::HybridClass<Binding>,
|
||||
float pointScaleFactor_ = 1;
|
||||
|
||||
std::shared_ptr<const ReactNativeConfig> reactNativeConfig_{nullptr};
|
||||
bool useIntBufferBatchMountItem_{false};
|
||||
bool disablePreallocateViews_{false};
|
||||
bool disableVirtualNodePreallocation_{false};
|
||||
bool enableFabricLogs_{false};
|
||||
|
||||
private:
|
||||
void schedulerDidFinishTransactionIntBuffer(
|
||||
MountingCoordinator::Shared const &mountingCoordinator);
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
-117
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.ReactMarker;
|
||||
import com.facebook.react.bridge.ReactMarkerConstants;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.systrace.Systrace;
|
||||
|
||||
/**
|
||||
* This class represents a batch of {@link MountItem}s
|
||||
*
|
||||
* <p>A MountItem batch contains an array of {@link MountItem} and a size. The size determines the
|
||||
* amount of items that needs to be processed in the array.
|
||||
*
|
||||
* <p>The purpose of encapsulating the array of MountItems this way, is to reduce the amount of
|
||||
* allocations in C++
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class BatchMountItem implements MountItem {
|
||||
static final String TAG = "FabricBatchMountItem";
|
||||
|
||||
private final int mRootTag;
|
||||
@NonNull private final MountItem[] mMountItems;
|
||||
|
||||
private final int mSize;
|
||||
|
||||
private final int mCommitNumber;
|
||||
|
||||
public BatchMountItem(int rootTag, MountItem[] items, int size, int commitNumber) {
|
||||
int itemsLength = (items == null ? 0 : items.length);
|
||||
if (size < 0 || size > itemsLength) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid size received by parameter size: " + size + " items.size = " + itemsLength);
|
||||
}
|
||||
mRootTag = rootTag;
|
||||
mMountItems = items;
|
||||
mSize = size;
|
||||
mCommitNumber = commitNumber;
|
||||
}
|
||||
|
||||
private void beginMarkers(String reason) {
|
||||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||
"FabricUIManager::" + reason + " - " + mSize + " items");
|
||||
|
||||
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_JAVA_BRIDGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
beginMarkers("mountViews");
|
||||
|
||||
int mountItemIndex = 0;
|
||||
try {
|
||||
for (; mountItemIndex < mSize; mountItemIndex++) {
|
||||
mMountItems[mountItemIndex].execute(mountingManager);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
FLog.e(
|
||||
TAG,
|
||||
"Caught exception executing mountItem @"
|
||||
+ mountItemIndex
|
||||
+ ": "
|
||||
+ mMountItems[mountItemIndex].toString(),
|
||||
e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
endMarkers();
|
||||
}
|
||||
|
||||
public int getRootTag() {
|
||||
return mRootTag;
|
||||
}
|
||||
|
||||
public boolean shouldSchedule() {
|
||||
return mSize != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < mSize; i++) {
|
||||
if (s.length() > 0) {
|
||||
s.append("\n");
|
||||
}
|
||||
s.append("BatchMountItem [S:" + mRootTag + "] (")
|
||||
.append(i + 1)
|
||||
.append("/")
|
||||
.append(mSize)
|
||||
.append("): ")
|
||||
.append(mMountItems[i]);
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
|
||||
public class CreateMountItem implements MountItem {
|
||||
|
||||
@NonNull private final String mComponent;
|
||||
private final int mRootTag;
|
||||
private final int mReactTag;
|
||||
@NonNull private final ThemedReactContext mContext;
|
||||
private final @Nullable ReadableMap mProps;
|
||||
private final @Nullable StateWrapper mStateWrapper;
|
||||
private final boolean mIsLayoutable;
|
||||
|
||||
public CreateMountItem(
|
||||
@Nullable ThemedReactContext context,
|
||||
int rootTag,
|
||||
int reactTag,
|
||||
@NonNull String component,
|
||||
@Nullable ReadableMap props,
|
||||
@NonNull StateWrapper stateWrapper,
|
||||
boolean isLayoutable) {
|
||||
mContext = context;
|
||||
mComponent = component;
|
||||
mRootTag = rootTag;
|
||||
mReactTag = reactTag;
|
||||
mProps = props;
|
||||
mStateWrapper = stateWrapper;
|
||||
mIsLayoutable = isLayoutable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
if (mContext == null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot execute PreAllocateViewMountItem without Context for ReactTag: "
|
||||
+ mReactTag
|
||||
+ " and rootTag: "
|
||||
+ mRootTag);
|
||||
}
|
||||
mountingManager.createView(
|
||||
mContext, mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CreateMountItem ["
|
||||
+ mReactTag
|
||||
+ "] - component: "
|
||||
+ mComponent
|
||||
+ " - rootTag: "
|
||||
+ mRootTag
|
||||
+ " - isLayoutable: "
|
||||
+ mIsLayoutable;
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
|
||||
public class InsertMountItem implements MountItem {
|
||||
|
||||
private int mReactTag;
|
||||
private int mParentReactTag;
|
||||
private int mIndex;
|
||||
|
||||
public InsertMountItem(int reactTag, int parentReactTag, int index) {
|
||||
mReactTag = reactTag;
|
||||
mParentReactTag = parentReactTag;
|
||||
mIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
mountingManager.addViewAt(mParentReactTag, mReactTag, mIndex);
|
||||
}
|
||||
|
||||
public int getParentReactTag() {
|
||||
return mParentReactTag;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InsertMountItem ["
|
||||
+ mReactTag
|
||||
+ "] - parentTag: ["
|
||||
+ mParentReactTag
|
||||
+ "] - index: "
|
||||
+ mIndex;
|
||||
}
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
|
||||
public class RemoveDeleteMultiMountItem implements MountItem {
|
||||
|
||||
// Metadata is an array of ints, grouped into 4 ints per instruction (so the length of metadata
|
||||
// is always divisible by 4):
|
||||
//
|
||||
// `instruction*4 + 0`: react tag of view instruction
|
||||
// `instruction*4 + 1`: react tag of view's parent
|
||||
// `instruction*4 + 2`: index of view in parents' children instruction
|
||||
// `instruction*4 + 3`: flags indicating if the view should be removed, and/or deleted
|
||||
@NonNull private int[] mMetadata;
|
||||
|
||||
// Bitfields of "flag", indicating if a view should be removed and/or deleted
|
||||
private static final int REMOVE_FLAG = 1;
|
||||
private static final int DELETE_FLAG = 2;
|
||||
|
||||
// Indices for each parameter within an "instruction"
|
||||
private static final int INSTRUCTION_FIELDS_LEN = 4;
|
||||
private static final int TAG_INDEX = 0;
|
||||
private static final int PARENT_TAG_INDEX = 1;
|
||||
private static final int VIEW_INDEX_INDEX = 2;
|
||||
private static final int FLAGS_INDEX = 3;
|
||||
|
||||
public RemoveDeleteMultiMountItem(@NonNull int[] metadata) {
|
||||
mMetadata = metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
// First, go through instructions and remove all views that are marked
|
||||
// for removal.
|
||||
// Not all views that are removed are deleted, and not all deleted views
|
||||
// are removed first.
|
||||
// *All* views must be removed here before we can delete any views.
|
||||
// Removal of a view from a parent is based on indices within the parents' children,
|
||||
// and deletion causes reordering; so we must perform all removals first.
|
||||
for (int i = 0; i < mMetadata.length; i += INSTRUCTION_FIELDS_LEN) {
|
||||
int flags = mMetadata[i + FLAGS_INDEX];
|
||||
if ((flags & REMOVE_FLAG) != 0) {
|
||||
int parentTag = mMetadata[i + PARENT_TAG_INDEX];
|
||||
int tag = mMetadata[i + TAG_INDEX];
|
||||
int index = mMetadata[i + VIEW_INDEX_INDEX];
|
||||
mountingManager.removeViewAt(tag, parentTag, index);
|
||||
}
|
||||
}
|
||||
|
||||
// After removing all views, delete all views marked for deletion.
|
||||
for (int i = 0; i < mMetadata.length; i += 4) {
|
||||
int flags = mMetadata[i + FLAGS_INDEX];
|
||||
if ((flags & DELETE_FLAG) != 0) {
|
||||
int tag = mMetadata[i + TAG_INDEX];
|
||||
mountingManager.deleteView(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < mMetadata.length; i += 4) {
|
||||
if (s.length() > 0) {
|
||||
s.append("\n");
|
||||
}
|
||||
s.append("RemoveDeleteMultiMountItem (")
|
||||
.append(i / INSTRUCTION_FIELDS_LEN + 1)
|
||||
.append("/")
|
||||
.append(mMetadata.length / INSTRUCTION_FIELDS_LEN)
|
||||
.append("): [")
|
||||
.append(mMetadata[i + TAG_INDEX])
|
||||
.append("] parent [")
|
||||
.append(mMetadata[i + PARENT_TAG_INDEX])
|
||||
.append("] idx ")
|
||||
.append(mMetadata[i + VIEW_INDEX_INDEX])
|
||||
.append(" ")
|
||||
.append(mMetadata[i + FLAGS_INDEX]);
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import com.facebook.react.fabric.events.EventEmitterWrapper;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
|
||||
public class UpdateEventEmitterMountItem implements MountItem {
|
||||
|
||||
@NonNull private final EventEmitterWrapper mEventHandler;
|
||||
private final int mReactTag;
|
||||
|
||||
public UpdateEventEmitterMountItem(int reactTag, @NonNull EventEmitterWrapper EventHandler) {
|
||||
mReactTag = reactTag;
|
||||
mEventHandler = EventHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
mountingManager.updateEventEmitter(mReactTag, mEventHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UpdateEventEmitterMountItem [" + mReactTag + "]";
|
||||
}
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.util.LayoutDirection;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
|
||||
public class UpdateLayoutMountItem implements MountItem {
|
||||
|
||||
private final int mReactTag;
|
||||
private final int mX;
|
||||
private final int mY;
|
||||
private final int mWidth;
|
||||
private final int mHeight;
|
||||
private final int mLayoutDirection;
|
||||
|
||||
public UpdateLayoutMountItem(
|
||||
int reactTag, int x, int y, int width, int height, int layoutDirection) {
|
||||
mReactTag = reactTag;
|
||||
mX = x;
|
||||
mY = y;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mLayoutDirection = convertLayoutDirection(layoutDirection);
|
||||
}
|
||||
|
||||
// TODO move this from here
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private static int convertLayoutDirection(int layoutDirection) {
|
||||
switch (layoutDirection) {
|
||||
case 0:
|
||||
return LayoutDirection.INHERIT;
|
||||
case 1:
|
||||
return LayoutDirection.LTR;
|
||||
case 2:
|
||||
return LayoutDirection.RTL;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported layout direction: " + layoutDirection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
mountingManager.updateLayout(mReactTag, mX, mY, mWidth, mHeight);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return mX;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return mY;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
public int getLayoutDirection() {
|
||||
return mLayoutDirection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UpdateLayoutMountItem ["
|
||||
+ mReactTag
|
||||
+ "] - x: "
|
||||
+ mX
|
||||
+ " - y: "
|
||||
+ mY
|
||||
+ " - height: "
|
||||
+ mHeight
|
||||
+ " - width: "
|
||||
+ mWidth
|
||||
+ " - layoutDirection: "
|
||||
+ +mLayoutDirection;
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
|
||||
/**
|
||||
* A MountItem that represents setting the padding properties of a view (left, top, right, bottom).
|
||||
* This is distinct from layout because it happens far less frequently from layout; so it is a perf
|
||||
* optimization to transfer this data and execute the methods strictly less than the layout-related
|
||||
* properties.
|
||||
*/
|
||||
public class UpdatePaddingMountItem implements MountItem {
|
||||
|
||||
private final int mReactTag;
|
||||
private final int mLeft;
|
||||
private final int mTop;
|
||||
private final int mRight;
|
||||
private final int mBottom;
|
||||
|
||||
public UpdatePaddingMountItem(int reactTag, int left, int top, int right, int bottom) {
|
||||
mReactTag = reactTag;
|
||||
mLeft = left;
|
||||
mTop = top;
|
||||
mRight = right;
|
||||
mBottom = bottom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
mountingManager.updatePadding(mReactTag, mLeft, mTop, mRight, mBottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UpdatePaddingMountItem ["
|
||||
+ mReactTag
|
||||
+ "] - left: "
|
||||
+ mLeft
|
||||
+ " - top: "
|
||||
+ mTop
|
||||
+ " - right: "
|
||||
+ mRight
|
||||
+ " - bottom: "
|
||||
+ mBottom;
|
||||
}
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
|
||||
public class UpdatePropsMountItem implements MountItem {
|
||||
|
||||
private final int mReactTag;
|
||||
@NonNull private final ReadableMap mUpdatedProps;
|
||||
|
||||
public UpdatePropsMountItem(int reactTag, @NonNull ReadableMap updatedProps) {
|
||||
mReactTag = reactTag;
|
||||
mUpdatedProps = updatedProps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
mountingManager.updateProps(mReactTag, mUpdatedProps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result =
|
||||
new StringBuilder("UpdatePropsMountItem [").append(mReactTag).append("]");
|
||||
|
||||
if (IS_DEVELOPMENT_ENVIRONMENT) {
|
||||
result.append(" props: ").append(mUpdatedProps);
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
|
||||
public class UpdateStateMountItem implements MountItem {
|
||||
|
||||
private final int mReactTag;
|
||||
@Nullable private final StateWrapper mStateWrapper;
|
||||
|
||||
public UpdateStateMountItem(int reactTag, @Nullable StateWrapper stateWrapper) {
|
||||
mReactTag = reactTag;
|
||||
mStateWrapper = stateWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NonNull MountingManager mountingManager) {
|
||||
mountingManager.updateState(mReactTag, mStateWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result =
|
||||
new StringBuilder("UpdateStateMountItem [").append(mReactTag).append("]");
|
||||
|
||||
if (IS_DEVELOPMENT_ENVIRONMENT) {
|
||||
result.append(" state: ").append(mStateWrapper != null ? mStateWrapper.getState() : "<null>");
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user