Define event category in Event class

Summary:
Propagate event category definition to every event that is using `dispatchModernV2` (gated in production), providing opportunity to override categories of some events if needed. No events are meaningfully affected by this change, as coalesced events (e.g. scroll) are always dispatched as continuous and touch events are handled separately.

Changelog:
[Internal] Expose event category in Event class

Reviewed By: cortinico

Differential Revision: D31276249

fbshipit-source-id: f9a756b3a5cf5897e17209f3d0aed6a1c16cbd2e
This commit is contained in:
Andrei Shikov
2021-10-13 08:21:38 -07:00
committed by Facebook GitHub Bot
parent 9ae3367431
commit 8ba4a2f127
7 changed files with 48 additions and 24 deletions
@@ -54,7 +54,6 @@ import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.fabric.events.EventBeatManager;
import com.facebook.react.fabric.events.EventCategoryDef;
import com.facebook.react.fabric.events.EventEmitterWrapper;
import com.facebook.react.fabric.events.FabricEventEmitter;
import com.facebook.react.fabric.mounting.MountItemDispatcher;
@@ -78,6 +77,7 @@ import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.ViewManagerPropertyUpdater;
import com.facebook.react.uimanager.ViewManagerRegistry;
import com.facebook.react.uimanager.events.EventCategoryDef;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.EventDispatcherImpl;
import com.facebook.react.uimanager.events.LockFreeEventDispatcherImpl;
@@ -16,6 +16,7 @@ import com.facebook.react.bridge.NativeMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.fabric.FabricSoLoader;
import com.facebook.react.uimanager.events.EventCategoryDef;
/**
* This class holds reference to the C++ EventEmitter object. Instances of this class are created on
@@ -22,6 +22,7 @@ import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.fabric.FabricUIManager;
import com.facebook.react.uimanager.events.EventCategoryDef;
import com.facebook.react.uimanager.events.RCTModernEventEmitter;
import com.facebook.react.uimanager.events.TouchEventType;
import com.facebook.systrace.Systrace;
@@ -46,7 +47,7 @@ public class FabricEventEmitter implements RCTModernEventEmitter {
@Override
public void receiveEvent(
int surfaceId, int reactTag, String eventName, @Nullable WritableMap params) {
receiveEvent(surfaceId, reactTag, eventName, false, 0, params);
receiveEvent(surfaceId, reactTag, eventName, false, 0, params, EventCategoryDef.UNSPECIFIED);
}
@Override
@@ -56,37 +57,46 @@ public class FabricEventEmitter implements RCTModernEventEmitter {
String eventName,
boolean canCoalesceEvent,
int customCoalesceKey,
@Nullable WritableMap params) {
@Nullable WritableMap params,
@EventCategoryDef int category) {
Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"FabricEventEmitter.receiveEvent('" + eventName + "')");
mUIManager.receiveEvent(
surfaceId, reactTag, eventName, canCoalesceEvent, customCoalesceKey, params);
surfaceId, reactTag, eventName, canCoalesceEvent, customCoalesceKey, params, category);
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
/**
* Processes touches in a JS compatible way and send it to Fabric core
*
* @param eventName the event name (see {@link TouchEventType})
* @param touches all the touch data extracted from MotionEvent
* @param changedIndices the indices of the pointers that changed (MOVE/CANCEL includes all
* touches, START/END only the one that was added/removed)
*/
@Override
public void receiveTouches(
@NonNull String eventTopLevelType,
@NonNull String eventName,
@NonNull WritableArray touches,
@NonNull WritableArray changedIndices) {
Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"FabricEventEmitter.receiveTouches('" + eventTopLevelType + "')");
"FabricEventEmitter.receiveTouches('" + eventName + "')");
boolean isPointerEndEvent =
TouchEventType.END.getJsName().equalsIgnoreCase(eventTopLevelType)
|| TouchEventType.CANCEL.getJsName().equalsIgnoreCase(eventTopLevelType);
boolean isFinalEvent =
TouchEventType.END.getJsName().equalsIgnoreCase(eventName)
|| TouchEventType.CANCEL.getJsName().equalsIgnoreCase(eventName);
Pair<WritableArray, WritableArray> result =
isPointerEndEvent
isFinalEvent
? removeTouchesAtIndices(touches, changedIndices)
: touchSubsequence(touches, changedIndices);
WritableArray changedTouches = result.first;
touches = result.second;
int eventCategory = getTouchCategory(eventTopLevelType);
int eventCategory = getTouchCategory(eventName);
for (int jj = 0; jj < changedTouches.size(); jj++) {
WritableMap touch = getWritableMap(changedTouches.getMap(jj));
// Touch objects can fulfill the role of `DOM` `Event` objects if we set
@@ -104,8 +114,7 @@ public class FabricEventEmitter implements RCTModernEventEmitter {
rootNodeID = targetReactTag;
}
mUIManager.receiveEvent(
targetSurfaceId, rootNodeID, eventTopLevelType, false, 0, touch, eventCategory);
receiveEvent(targetSurfaceId, rootNodeID, eventName, false, 0, touch, eventCategory);
}
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
@@ -182,6 +182,11 @@ public abstract class Event<T extends Event> {
return null;
}
@EventCategoryDef
protected int getEventCategory() {
return EventCategoryDef.UNSPECIFIED;
}
/**
* Dispatch this event to JS using a V2 EventEmitter. If surfaceId is not -1 and `getEventData` is
* non-null, this will use the RCTModernEventEmitter API. Otherwise, it falls back to the
@@ -215,7 +220,8 @@ public abstract class Event<T extends Event> {
getEventName(),
canCoalesce(),
getCoalescingKey(),
eventData);
eventData,
getEventCategory());
return;
}
}
@@ -5,13 +5,13 @@
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.fabric.events;
package com.facebook.react.uimanager.events;
import static com.facebook.react.fabric.events.EventCategoryDef.CONTINUOUS;
import static com.facebook.react.fabric.events.EventCategoryDef.CONTINUOUS_END;
import static com.facebook.react.fabric.events.EventCategoryDef.CONTINUOUS_START;
import static com.facebook.react.fabric.events.EventCategoryDef.DISCRETE;
import static com.facebook.react.fabric.events.EventCategoryDef.UNSPECIFIED;
import static com.facebook.react.uimanager.events.EventCategoryDef.CONTINUOUS;
import static com.facebook.react.uimanager.events.EventCategoryDef.CONTINUOUS_END;
import static com.facebook.react.uimanager.events.EventCategoryDef.CONTINUOUS_START;
import static com.facebook.react.uimanager.events.EventCategoryDef.DISCRETE;
import static com.facebook.react.uimanager.events.EventCategoryDef.UNSPECIFIED;
import androidx.annotation.IntDef;
@@ -28,5 +28,6 @@ public interface RCTModernEventEmitter extends RCTEventEmitter {
String eventName,
boolean canCoalesceEvent,
int customCoalesceKey,
@Nullable WritableMap event);
@Nullable WritableMap event,
@EventCategoryDef int category);
}
@@ -64,7 +64,7 @@ public class ReactEventEmitter implements RCTModernEventEmitter {
int surfaceId, int targetTag, String eventName, @Nullable WritableMap event) {
// The two additional params here, `canCoalesceEvent` and `customCoalesceKey`, have no
// meaning outside of Fabric.
receiveEvent(surfaceId, targetTag, eventName, false, 0, event);
receiveEvent(surfaceId, targetTag, eventName, false, 0, event, EventCategoryDef.UNSPECIFIED);
}
@Override
@@ -120,11 +120,18 @@ public class ReactEventEmitter implements RCTModernEventEmitter {
String eventName,
boolean canCoalesceEvent,
int customCoalesceKey,
@Nullable WritableMap event) {
@Nullable WritableMap event,
@EventCategoryDef int category) {
@UIManagerType int uiManagerType = ViewUtil.getUIManagerType(targetReactTag);
if (uiManagerType == UIManagerType.FABRIC && mFabricEventEmitter != null) {
mFabricEventEmitter.receiveEvent(
surfaceId, targetReactTag, eventName, canCoalesceEvent, customCoalesceKey, event);
surfaceId,
targetReactTag,
eventName,
canCoalesceEvent,
customCoalesceKey,
event,
category);
} else if (uiManagerType == UIManagerType.DEFAULT && getEventEmitter(targetReactTag) != null) {
mRCTEventEmitter.receiveEvent(targetReactTag, eventName, event);
} else {