diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ViewMutationsListener.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ViewMutationsListener.java new file mode 100644 index 000000000000..e723ee2138c1 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ViewMutationsListener.java @@ -0,0 +1,20 @@ +/* + * 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.bridge; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; + +import java.util.ArrayList; + +public interface ViewMutationsListener { + /** + * Called right before view mutations are dispatched. This is useful if a + * module needs to do something before the views are created/removed. + */ + void willMountViewMutations(ArrayList mutations); +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/InstructionType.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/InstructionType.java new file mode 100644 index 000000000000..d2bc6e8b2b77 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/InstructionType.java @@ -0,0 +1,8 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; + +public enum InstructionType { + CREATE, DELETE, INSERT, REMOVE, UPDATE_PROPS, UPDATE_STATE, UPDATE_LAYOUT, UPDATE_EVENT_EMITTER, + UPDATE_PADDING, UPDATE_OVERFLOW_INSET, REMOVE_DELETE_TREE +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java index ad286fcdd172..e6b073958678 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java @@ -20,8 +20,14 @@ import com.facebook.react.fabric.mounting.MountingManager; import com.facebook.react.fabric.mounting.SurfaceMountingManager; import com.facebook.react.uimanager.StateWrapper; +import com.facebook.react.uimanager.UIManagerModule; import com.facebook.systrace.Systrace; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import android.view.View; + /** * This class represents a batch of {@link MountItem}s, represented directly as int buffers to * remove the need for actual MountItem instances. @@ -117,70 +123,226 @@ public void execute(@NonNull MountingManager mountingManager) { beginMarkers("mountViews"); + ArrayList mutationsArray = new ArrayList<>(); + + // we put views in the mount item objects also for some operations since tags + // are only mapped to ViewState which are internal. + // In most cases we will need the view to perform an action in the listener 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++) { + IntBufferMountItem item; if (type == INSTRUCTION_CREATE) { String componentName = getFabricComponentName((String) mObjBuffer[j++]); - surfaceMountingManager.createView( - componentName, - mIntBuffer[i++], - mObjBuffer[j++], - castToState(mObjBuffer[j++]), - castToEventEmitter(mObjBuffer[j++]), - mIntBuffer[i++] == 1); + int reactTag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(reactTag)) { + view = surfaceMountingManager.getView(reactTag); + } + Object props = mObjBuffer[j++]; + StateWrapper stateWrapper = castToState(mObjBuffer[j++]); + EventEmitterWrapper eventEmitterWrapper = castToEventEmitter(mObjBuffer[j++]); + boolean isLayoutable = mIntBuffer[i++] == 1; + item = new IntBufferMountItemCreate(reactTag, + view, componentName, props, stateWrapper, eventEmitterWrapper, isLayoutable); + } else if (type == INSTRUCTION_DELETE) { - surfaceMountingManager.deleteView(mIntBuffer[i++]); + int reactTag = mIntBuffer[i++]; + item = new IntBufferMountItemDelete(reactTag, null); } else if (type == INSTRUCTION_INSERT) { int tag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(tag)) { + view = surfaceMountingManager.getView(tag); + } int parentTag = mIntBuffer[i++]; - surfaceMountingManager.addViewAt(parentTag, tag, mIntBuffer[i++]); + View parentView = null; + if (surfaceMountingManager.getViewExists(parentTag)) { + parentView = surfaceMountingManager.getView(parentTag); + } + int index = mIntBuffer[i++]; + item = new IntBufferMountItemInsert(tag, view, parentTag, parentView, index); } else if (type == INSTRUCTION_REMOVE) { - surfaceMountingManager.removeViewAt(mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]); + int tag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(tag)) { + view = surfaceMountingManager.getView(tag); + } + int parentTag = mIntBuffer[i++]; + View parentView = null; + if (surfaceMountingManager.getViewExists(parentTag)) { + parentView = surfaceMountingManager.getView(parentTag); + } + int index = mIntBuffer[i++]; + item = new IntBufferMountItemRemove(tag, view, parentTag, parentView, index); } else if (type == INSTRUCTION_REMOVE_DELETE_TREE) { - surfaceMountingManager.removeDeleteTreeAt( - mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]); + int tag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(tag)) { + view = surfaceMountingManager.getView(tag); + } + int parentTag = mIntBuffer[i++]; + View parentView = null; + if (surfaceMountingManager.getViewExists(parentTag)) { + parentView = surfaceMountingManager.getView(parentTag); + } + int index = mIntBuffer[i++]; + item = new IntBufferMountItemRemoveDeleteTree(tag, view, parentTag, parentView, index); } else if (type == INSTRUCTION_UPDATE_PROPS) { - surfaceMountingManager.updateProps(mIntBuffer[i++], mObjBuffer[j++]); + int reactTag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(reactTag)) { + view = surfaceMountingManager.getView(reactTag); + } + Object props = mObjBuffer[j++]; + item = new IntBufferMountItemUpdateProps(reactTag, view, props); } else if (type == INSTRUCTION_UPDATE_STATE) { - surfaceMountingManager.updateState(mIntBuffer[i++], castToState(mObjBuffer[j++])); + int reactTag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(reactTag)) { + view = surfaceMountingManager.getView(reactTag); + } + StateWrapper stateWrapper = castToState(mObjBuffer[j++]); + item = new IntBufferMountItemUpdateState(reactTag, view, stateWrapper); } else if (type == INSTRUCTION_UPDATE_LAYOUT) { int reactTag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(reactTag)) { + view = surfaceMountingManager.getView(reactTag); + } int parentTag = mIntBuffer[i++]; + View parentView = null; + if (surfaceMountingManager.getViewExists(parentTag)) { + parentView = surfaceMountingManager.getView(parentTag); + } int x = mIntBuffer[i++]; int y = mIntBuffer[i++]; int width = mIntBuffer[i++]; int height = mIntBuffer[i++]; int displayType = mIntBuffer[i++]; - - surfaceMountingManager.updateLayout( - reactTag, parentTag, x, y, width, height, displayType); - + item = new IntBufferMountItemUpdateLayout(reactTag, view, parentTag, parentView, x, y, + width, height, displayType); } else if (type == INSTRUCTION_UPDATE_PADDING) { - surfaceMountingManager.updatePadding( - mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]); + int reactTag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(reactTag)) { + view = surfaceMountingManager.getView(reactTag); + } + int left = mIntBuffer[i++]; + int top = mIntBuffer[i++]; + int right = mIntBuffer[i++]; + int bottom = mIntBuffer[i++]; + item = new IntBufferMountItemUpdatePadding(reactTag, view, left, top, right, bottom); } else if (type == INSTRUCTION_UPDATE_OVERFLOW_INSET) { int reactTag = mIntBuffer[i++]; + View view = null; + if (surfaceMountingManager.getViewExists(reactTag)) { + view = surfaceMountingManager.getView(reactTag); + } int overflowInsetLeft = mIntBuffer[i++]; int overflowInsetTop = mIntBuffer[i++]; int overflowInsetRight = mIntBuffer[i++]; int overflowInsetBottom = mIntBuffer[i++]; - - surfaceMountingManager.updateOverflowInset( - reactTag, - overflowInsetLeft, - overflowInsetTop, - overflowInsetRight, - overflowInsetBottom); + item = new IntBufferMountItemUpdateOverflowInset(reactTag, view, overflowInsetLeft, + overflowInsetTop, overflowInsetRight, overflowInsetBottom); } else if (type == INSTRUCTION_UPDATE_EVENT_EMITTER) { - surfaceMountingManager.updateEventEmitter( - mIntBuffer[i++], castToEventEmitter(mObjBuffer[j++])); + int reactTag = mIntBuffer[i++]; + EventEmitterWrapper eventEmitterWrapper = castToEventEmitter(mObjBuffer[j++]); + item = new IntBufferMountItemUpdateEventEmitter(reactTag, null, eventEmitterWrapper); } else { throw new IllegalArgumentException( - "Invalid type argument to IntBufferBatchMountItem: " + type + " at index: " + i); + "Invalid type argument to IntBufferBatchMountItem: " + type + " at index: " + i); + } + mutationsArray.add(item); + } + } + + surfaceMountingManager.getContext().getNativeModule(UIManagerModule.class).viewMutationsWillMount(mutationsArray); + + for (IntBufferMountItem elem: mutationsArray) { + switch (elem.getInstructionType()) { + case CREATE: { + IntBufferMountItemCreate createElem = (IntBufferMountItemCreate) elem; + surfaceMountingManager.createView( + createElem.getComponentName(), + createElem.getReactTag(), + createElem.getProps(), + createElem.getStateWrapper(), + createElem.getEventEmitterWrapper(), + createElem.isLayoutable()); + break; + } + case DELETE: { + IntBufferMountItemDelete deleteElem = (IntBufferMountItemDelete) elem; + surfaceMountingManager.deleteView(deleteElem.getReactTag()); + break; + } + case INSERT: { + IntBufferMountItemInsert insertElem = (IntBufferMountItemInsert) elem; + surfaceMountingManager.addViewAt(insertElem.getParentTag(), insertElem.getReactTag(), insertElem.getIndex()); + break; + } + case REMOVE: { + IntBufferMountItemRemove removeElem = (IntBufferMountItemRemove) elem; + surfaceMountingManager.removeViewAt(removeElem.getReactTag(), removeElem.getParentTag(), removeElem.getIndex()); + break; + } + case REMOVE_DELETE_TREE: { + IntBufferMountItemRemoveDeleteTree removeDeleteTreeElem = (IntBufferMountItemRemoveDeleteTree) elem; + surfaceMountingManager.removeDeleteTreeAt(removeDeleteTreeElem.getReactTag(), + removeDeleteTreeElem.getParentTag(), removeDeleteTreeElem.getIndex()); + break; + } + case UPDATE_PROPS: { + IntBufferMountItemUpdateProps updatePropsElem = (IntBufferMountItemUpdateProps) elem; + surfaceMountingManager.updateProps(updatePropsElem.getReactTag(), + updatePropsElem.getProps()); + break; + } + case UPDATE_STATE: { + IntBufferMountItemUpdateState updateStateElem = (IntBufferMountItemUpdateState) elem; + surfaceMountingManager.updateState(updateStateElem.getReactTag(), + updateStateElem.getStateWrapper()); + break; + } + case UPDATE_LAYOUT: { + IntBufferMountItemUpdateLayout updateLayoutElem = (IntBufferMountItemUpdateLayout) elem; + surfaceMountingManager.updateLayout(updateLayoutElem.getReactTag(), + updateLayoutElem.getParentTag(), updateLayoutElem.getX(), updateLayoutElem.getY(), + updateLayoutElem.getWidth(), updateLayoutElem.getHeight(), + updateLayoutElem.getDisplayType()); + break; + } + case UPDATE_PADDING: { + IntBufferMountItemUpdatePadding updatePaddingElem = (IntBufferMountItemUpdatePadding) elem; + surfaceMountingManager.updatePadding(updatePaddingElem.getReactTag(), + updatePaddingElem.getLeft(), updatePaddingElem.getTop(), + updatePaddingElem.getRight(), updatePaddingElem.getBottom()); + break; + } + case UPDATE_OVERFLOW_INSET: { + IntBufferMountItemUpdateOverflowInset updateOverflowInsetElem = + (IntBufferMountItemUpdateOverflowInset) elem; + surfaceMountingManager.updateOverflowInset(updateOverflowInsetElem.getReactTag(), + updateOverflowInsetElem.getOverflowInsetLeft(), + updateOverflowInsetElem.getOverflowInsetTop(), + updateOverflowInsetElem.getOverflowInsetRight(), + updateOverflowInsetElem.getOverflowInsetBottom()); + break; + } + case UPDATE_EVENT_EMITTER: { + IntBufferMountItemUpdateEventEmitter updateEventEmitterElem = + (IntBufferMountItemUpdateEventEmitter) elem; + surfaceMountingManager.updateEventEmitter(updateEventEmitterElem.getReactTag(), + updateEventEmitterElem.getEventEmitterWrapper()); + break; + } + default: { + throw new IllegalArgumentException( + "Invalid type argument to IntBufferBatchMountItem: " + elem.getInstructionType()); } } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItem.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItem.java new file mode 100644 index 000000000000..15acb2e7625b --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItem.java @@ -0,0 +1,30 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public abstract class IntBufferMountItem { + private final InstructionType instructionType; + private final int reactTag; + private final View view; + + public IntBufferMountItem(InstructionType instructionType, int reactTag, View view) { + this.instructionType = instructionType; + this.reactTag = reactTag; + this.view = view; + } + + public InstructionType getInstructionType() { + return instructionType; + } + + public int getReactTag() { + return reactTag; + } + + public View getView() { + return view; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemCreate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemCreate.java new file mode 100644 index 000000000000..c46b51abe73c --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemCreate.java @@ -0,0 +1,46 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.InstructionType; +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.uimanager.StateWrapper; +import com.facebook.react.fabric.events.EventEmitterWrapper; + +import android.view.View; + +public class IntBufferMountItemCreate extends IntBufferMountItem { + + private final String componentName; + private final Object props; + private final StateWrapper stateWrapper; + private final EventEmitterWrapper eventEmitterWrapper; + private final boolean isLayoutable; + + public IntBufferMountItemCreate(int reactTag, View view, String componentName, Object props, StateWrapper stateWrapper, EventEmitterWrapper eventEmitterWrapper, boolean isLayoutable) { + super(InstructionType.CREATE, reactTag, view); + this.componentName = componentName; + this.props = props; + this.stateWrapper = stateWrapper; + this.eventEmitterWrapper = eventEmitterWrapper; + this.isLayoutable = isLayoutable; + } + + public String getComponentName() { + return componentName; + } + + public Object getProps() { + return props; + } + + public StateWrapper getStateWrapper() { + return stateWrapper; + } + + public EventEmitterWrapper getEventEmitterWrapper() { + return eventEmitterWrapper; + } + + public boolean isLayoutable() { + return isLayoutable; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemDelete.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemDelete.java new file mode 100644 index 000000000000..d5fc005c55fc --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemDelete.java @@ -0,0 +1,13 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemDelete extends IntBufferMountItem { + + public IntBufferMountItemDelete(int reactTag, View view) { + super(InstructionType.DELETE, reactTag, view); + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemInsert.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemInsert.java new file mode 100644 index 000000000000..e4e6ff50acc6 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemInsert.java @@ -0,0 +1,32 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemInsert extends IntBufferMountItem { + + private int parentTag; + private View parentView; + private int index; + + public IntBufferMountItemInsert(int reactTag, View view, int parentTag, View parentView, int index) { + super(InstructionType.INSERT, reactTag, view); + this.parentTag = parentTag; + this.parentView = parentView; + this.index = index; + } + + public int getParentTag() { + return parentTag; + } + + public View getParentView() { + return parentView; + } + + public int getIndex() { + return index; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemRemove.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemRemove.java new file mode 100644 index 000000000000..4f59f67f0921 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemRemove.java @@ -0,0 +1,32 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemRemove extends IntBufferMountItem { + + private int parentTag; + private View parentView; + private int index; + + public IntBufferMountItemRemove(int reactTag, View view, int parentTag, View parentView, int index) { + super(InstructionType.REMOVE, reactTag, view); + this.parentTag = parentTag; + this.parentView = parentView; + this.index = index; + } + + public int getParentTag() { + return parentTag; + } + + public View getParentView() { + return parentView; + } + + public int getIndex() { + return index; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemRemoveDeleteTree.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemRemoveDeleteTree.java new file mode 100644 index 000000000000..48a3a0429655 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemRemoveDeleteTree.java @@ -0,0 +1,32 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemRemoveDeleteTree extends IntBufferMountItem { + + private int parentTag; + private View parentView; + private int index; + + public IntBufferMountItemRemoveDeleteTree(int reactTag, View view, int parentTag, View parentView, int index) { + super(InstructionType.REMOVE_DELETE_TREE, reactTag, view); + this.parentTag = parentTag; + this.parentView = parentView; + this.index = index; + } + + public int getParentTag() { + return parentTag; + } + + public View getParentView() { + return parentView; + } + + public int getIndex() { + return index; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateEventEmitter.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateEventEmitter.java new file mode 100644 index 000000000000..30f896ab0e0b --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateEventEmitter.java @@ -0,0 +1,22 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; +import com.facebook.react.fabric.events.EventEmitterWrapper; + +import android.view.View; + +public class IntBufferMountItemUpdateEventEmitter extends IntBufferMountItem { + + private final EventEmitterWrapper eventEmitterWrapper; + + public IntBufferMountItemUpdateEventEmitter(int reactTag, View view, + EventEmitterWrapper eventEmitterWrapper) { + super(InstructionType.UPDATE_EVENT_EMITTER, reactTag, view); + this.eventEmitterWrapper = eventEmitterWrapper; + } + + public EventEmitterWrapper getEventEmitterWrapper() { + return eventEmitterWrapper; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateLayout.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateLayout.java new file mode 100644 index 000000000000..a166f028fc11 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateLayout.java @@ -0,0 +1,57 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemUpdateLayout extends IntBufferMountItem { + + private int parentTag; + private View parentView; + private int x; + private int y; + private int width; + private int height; + private int displayType; + + public IntBufferMountItemUpdateLayout(int reactTag, View view, int parentTag, View parentView, + int x, int y, int width, int height, int displayType) { + super(InstructionType.UPDATE_LAYOUT, reactTag, view); + this.parentTag = parentTag; + this.parentView = parentView; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.displayType = displayType; + } + + public int getParentTag() { + return parentTag; + } + + public View getParentView() { + return parentView; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public int getDisplayType() { + return displayType; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateOverflowInset.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateOverflowInset.java new file mode 100644 index 000000000000..aeef222b8b1a --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateOverflowInset.java @@ -0,0 +1,39 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemUpdateOverflowInset extends IntBufferMountItem { + + private int overflowInsetLeft; + private int overflowInsetTop; + private int overflowInsetRight; + private int overflowInsetBottom; + + public IntBufferMountItemUpdateOverflowInset(int reactTag, View view, int overflowInsetLeft, int overflowInsetTop, int overflowInsetRight, + int overflowInsetBottom) { + super(InstructionType.UPDATE_OVERFLOW_INSET, reactTag, view); + this.overflowInsetLeft = overflowInsetLeft; + this.overflowInsetTop = overflowInsetTop; + this.overflowInsetRight = overflowInsetRight; + this.overflowInsetBottom = overflowInsetBottom; + } + + public int getOverflowInsetLeft() { + return overflowInsetLeft; + } + + public int getOverflowInsetTop() { + return overflowInsetTop; + } + + public int getOverflowInsetRight() { + return overflowInsetRight; + } + + public int getOverflowInsetBottom() { + return overflowInsetBottom; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdatePadding.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdatePadding.java new file mode 100644 index 000000000000..f405526f74fb --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdatePadding.java @@ -0,0 +1,40 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemUpdatePadding extends IntBufferMountItem { + + + private int left; + private int top; + private int right; + private int bottom; + + public IntBufferMountItemUpdatePadding(int reactTag, View view, int left, int top, int right, + int bottom) { + super(InstructionType.UPDATE_PADDING, reactTag, view); + this.left = left; + this.top = top; + this.right = right; + this.bottom = bottom; + } + + public int getLeft() { + return left; + } + + public int getTop() { + return top; + } + + public int getRight() { + return right; + } + + public int getBottom() { + return bottom; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateProps.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateProps.java new file mode 100644 index 000000000000..a06a66b63d47 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateProps.java @@ -0,0 +1,20 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; + +import android.view.View; + +public class IntBufferMountItemUpdateProps extends IntBufferMountItem { + + private final Object props; + + public IntBufferMountItemUpdateProps(int reactTag, View view, Object props) { + super(InstructionType.UPDATE_PROPS, reactTag, view); + this.props = props; + } + + public Object getProps() { + return props; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateState.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateState.java new file mode 100644 index 000000000000..0006e58522b8 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferMountItemUpdateState.java @@ -0,0 +1,22 @@ +package com.facebook.react.fabric.mounting.mountitems; + +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; +import com.facebook.react.fabric.mounting.mountitems.InstructionType; +import com.facebook.react.uimanager.StateWrapper; + +import android.view.View; + + +public class IntBufferMountItemUpdateState extends IntBufferMountItem { + + private final StateWrapper stateWrapper; + + public IntBufferMountItemUpdateState(int reactTag, View view, StateWrapper stateWrapper) { + super(InstructionType.UPDATE_STATE, reactTag, view); + this.stateWrapper = stateWrapper; + } + + public StateWrapper getStateWrapper() { + return stateWrapper; + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 15a1b4254298..2372c26c4e80 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -37,6 +37,7 @@ import com.facebook.react.bridge.UIManagerListener; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.ViewMutationsListener; import com.facebook.react.common.MapBuilder; import com.facebook.react.common.ReactConstants; import com.facebook.react.module.annotations.ReactModule; @@ -45,9 +46,11 @@ import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.EventDispatcherImpl; import com.facebook.react.uimanager.events.RCTEventEmitter; +import com.facebook.react.fabric.mounting.mountitems.IntBufferMountItem; import com.facebook.systrace.Systrace; import com.facebook.systrace.SystraceMessage; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; @@ -105,6 +108,7 @@ public interface CustomEventNamesResolver { private final UIImplementation mUIImplementation; private final MemoryTrimCallback mMemoryTrimCallback = new MemoryTrimCallback(); private final List mListeners = new ArrayList<>(); + private final CopyOnWriteArrayList mViewMutationsListeners = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList mUIManagerListeners = new CopyOnWriteArrayList<>(); @@ -781,6 +785,20 @@ public void removeUIManagerEventListener(UIManagerListener listener) { mUIManagerListeners.remove(listener); } + public void addViewMutationsListener(ViewMutationsListener listener) { + mViewMutationsListeners.add(listener); + } + + public void removeViewMutationsListener(ViewMutationsListener listener) { + mViewMutationsListeners.remove(listener); + } + + public void viewMutationsWillMount(ArrayList mutations) { + for (ViewMutationsListener listener : mViewMutationsListeners) { + listener.willMountViewMutations(mutations); + } + } + /** * Given a reactTag from a component, find its root node tag, if possible. Otherwise, this will * return 0. If the reactTag belongs to a root node, this will return the same reactTag.