|
7 | 7 |
|
8 | 8 | package com.facebook.react.uimanager.events;
|
9 | 9 |
|
| 10 | +import androidx.annotation.Nullable; |
| 11 | +import com.facebook.react.bridge.WritableMap; |
10 | 12 | import com.facebook.react.common.SystemClock;
|
| 13 | +import com.facebook.react.uimanager.IllegalViewOperationException; |
11 | 14 |
|
12 | 15 | /**
|
13 | 16 | * A UI event that can be dispatched to JS.
|
14 | 17 | *
|
15 |
| - * <p>For dispatching events {@link EventDispatcher#dispatchEvent} should be used. Once event object |
16 |
| - * is passed to the EventDispatched it should no longer be used as EventDispatcher may decide to |
17 |
| - * recycle that object (by calling {@link #dispose}). |
| 18 | + * <p>For dispatching events {@code getEventData} should be used. Once event object is passed to the |
| 19 | + * EventDispatched it should no longer be used as EventDispatcher may decide to recycle that object |
| 20 | + * (by calling {@link #dispose}). |
| 21 | + * |
| 22 | + * <p>If you need advanced customizations and overriding only {@code getEventData} doesn't work for |
| 23 | + * you, you must override both {@code dispatch} and {@code dispatchModern}. Both of these will be |
| 24 | + * deleted in the distant future and it is highly recommended to use only {@code getEventData}. |
| 25 | + * |
| 26 | + * <p>Old, pre-Fabric Events only used viewTag as the identifier, but Fabric needs surfaceId as well |
| 27 | + * as viewTag. You may use {@code UIManagerHelper.getSurfaceId} on a Fabric-managed View to get the |
| 28 | + * surfaceId. Fabric will work without surfaceId - making {@code Event} backwards-compatible - but |
| 29 | + * Events without SurfaceId are slightly slower to propagate. |
18 | 30 | */
|
19 | 31 | public abstract class Event<T extends Event> {
|
20 | 32 |
|
@@ -119,15 +131,45 @@ public void onDispose() {}
|
119 | 131 |
|
120 | 132 | /**
|
121 | 133 | * Dispatch this event to JS using the given event emitter. Compatible with old and new renderer.
|
| 134 | + * Instead of using this or dispatchModern, it is recommended that you simply override |
| 135 | + * `getEventData`. In the future |
122 | 136 | */
|
123 | 137 | @Deprecated
|
124 |
| - public abstract void dispatch(RCTEventEmitter rctEventEmitter); |
| 138 | + public void dispatch(RCTEventEmitter rctEventEmitter) { |
| 139 | + WritableMap eventData = getEventData(); |
| 140 | + if (eventData == null) { |
| 141 | + throw new IllegalViewOperationException( |
| 142 | + "Event: you must return a valid, non-null value from `getEventData`, or override `dispatch` and `disatchModern`. Event: " |
| 143 | + + getEventName()); |
| 144 | + } |
| 145 | + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), eventData); |
| 146 | + } |
| 147 | + |
| 148 | + /** |
| 149 | + * Can be overridden by classes to make migrating to RCTModernEventEmitter support easier. If this |
| 150 | + * class returns null, the RCTEventEmitter interface will be used instead of |
| 151 | + * RCTModernEventEmitter. In the future, returning null here will be an error. |
| 152 | + */ |
| 153 | + @Nullable |
| 154 | + protected WritableMap getEventData() { |
| 155 | + return null; |
| 156 | + } |
125 | 157 |
|
126 | 158 | /**
|
127 |
| - * Dispatch this event to JS using a V2 EventEmitter. Events must explicitly override this, by |
128 |
| - * default it uses the V1 dispatcher. |
| 159 | + * Dispatch this event to JS using a V2 EventEmitter. If surfaceId is not -1 and `getEventData` is |
| 160 | + * non-null, this will use the RCTModernEventEmitter API. Otherwise, it falls back to the |
| 161 | + * old-style dispatch function. For Event classes that need to do something different, this method |
| 162 | + * can always be overridden entirely, but it is not recommended. |
129 | 163 | */
|
| 164 | + @Deprecated |
130 | 165 | public void dispatchModern(RCTModernEventEmitter rctEventEmitter) {
|
| 166 | + if (getSurfaceId() != -1) { |
| 167 | + WritableMap eventData = getEventData(); |
| 168 | + if (eventData != null) { |
| 169 | + rctEventEmitter.receiveEvent(getSurfaceId(), getViewTag(), getEventName(), getEventData()); |
| 170 | + return; |
| 171 | + } |
| 172 | + } |
131 | 173 | dispatch(rctEventEmitter);
|
132 | 174 | }
|
133 | 175 | }
|
0 commit comments