Refactor setup of Event Dispatcher

Reviewed By: achen1

Differential Revision: D7746311

fbshipit-source-id: cfee1c2ced6d85477628085f3260496e80ae48c2
This commit is contained in:
David Vacca 2018-05-30 21:48:52 -07:00 коммит произвёл Facebook Github Bot
Родитель e61341ba32
Коммит 58ea20b5e8
9 изменённых файлов: 126 добавлений и 50 удалений

Просмотреть файл

@ -7,11 +7,12 @@
package com.facebook.react.testing;
import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
@ -38,7 +39,7 @@ import com.facebook.react.testing.idledetection.ReactIdleDetectionUtil;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewManagerRegistry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@ -244,35 +245,28 @@ public class ReactAppTestActivity extends FragmentActivity
.setBridgeIdleDebugListener(mBridgeIdleSignaler)
.setInitialLifecycleState(mLifecycleState)
.setJSIModulesProvider(
new JSIModulesProvider() {
@Override
public List<JSIModuleHolder> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext) {
new JSIModulesProvider() {
@Override
public List<JSIModuleHolder> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext) {
return Arrays.<JSIModuleHolder>asList(new JSIModuleHolder() {
@Override
public Class<? extends JSIModule> getJSIModuleClass() {
return UIManager.class;
}
List<JSIModuleHolder> modules = new ArrayList<>();
modules.add(
new JSIModuleHolder() {
@Override
public Class<? extends JSIModule> getJSIModuleClass() {
return UIManager.class;
}
@Override
public FabricUIManager getJSIModule() {
List<ViewManager> viewManagers =
getReactInstanceManager().getOrCreateViewManagers(reactApplicationContext);
FabricUIManager fabricUIManager =
new FabricUIManager(
reactApplicationContext, new ViewManagerRegistry(viewManagers));
new FabricJSCBinding().installFabric(jsContext, fabricUIManager);
return fabricUIManager;
}
});
return modules;
}})
@Override
public FabricUIManager getJSIModule() {
List<ViewManager> viewManagers =
mReactInstanceManager.getOrCreateViewManagers(reactApplicationContext);
FabricUIManager fabricUIManager =
new FabricUIManager(reactApplicationContext, new ViewManagerRegistry(viewManagers));
new FabricJSCBinding().installFabric(jsContext, fabricUIManager);
return fabricUIManager;
}
});
}})
.setUIImplementationProvider(uiImplementationProvider);
final CountDownLatch latch = new CountDownLatch(1);

Просмотреть файл

@ -82,6 +82,7 @@ import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import com.facebook.soloader.SoLoader;
import com.facebook.systrace.Systrace;
@ -1077,6 +1078,8 @@ public class ReactInstanceManager {
ReactMarker.logMarker(CREATE_REACT_CONTEXT_START, jsExecutor.getName());
final ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);
reactContext.setEventDispatcher(new EventDispatcher(reactContext));
NativeModuleCallExceptionHandler exceptionHandler = mNativeModuleCallExceptionHandler != null
? mNativeModuleCallExceptionHandler
: mDevSupportManager;

Просмотреть файл

@ -0,0 +1,13 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* 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;
/**
* Marker interface for EventDispatcher.
*/
public interface EventDispatcher {
}

Просмотреть файл

@ -39,6 +39,7 @@ public class ReactContext extends ContextWrapper {
private LifecycleState mLifecycleState = LifecycleState.BEFORE_CREATE;
private @Nullable EventDispatcher mEventDispatcher;
private @Nullable CatalystInstance mCatalystInstance;
private @Nullable LayoutInflater mInflater;
private @Nullable MessageQueueThread mUiMessageQueueThread;
@ -349,4 +350,12 @@ public class ReactContext extends ContextWrapper {
public JavaScriptContextHolder getJavaScriptContextHolder() {
return mCatalystInstance.getJavaScriptContextHolder();
}
public <T extends EventDispatcher> T getEventDispatcher() {
return (T) mEventDispatcher;
}
public void setEventDispatcher(EventDispatcher eventDispatcher) {
mEventDispatcher = eventDispatcher;
}
}

Просмотреть файл

@ -22,6 +22,7 @@ public class Scheduler {
public void scheduleWork(Work work) {
// TODO T26717866 this method needs to be implemented. The current implementation is just for
// testing purpose.
work.run();
}

Просмотреть файл

@ -9,12 +9,11 @@ package com.facebook.react.uimanager;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_END;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_START;
import static com.facebook.react.uimanager.common.UIManagerType.DEFAULT;
import android.content.ComponentCallbacks2;
import android.content.res.Configuration;
import android.content.Context;
import android.content.res.Configuration;
import android.media.AudioManager;
import com.facebook.common.logging.FLog;
import com.facebook.debug.holder.PrinterHolder;
@ -42,6 +41,7 @@ import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
import com.facebook.react.uimanager.common.ViewUtil;
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
import java.util.ArrayList;
@ -129,7 +129,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
int minTimeLeftInFrameForNonBatchedOperationMs) {
super(reactContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
mEventDispatcher = new EventDispatcher(reactContext);
mEventDispatcher = reactContext.getEventDispatcher();
mModuleConstants = createConstants(viewManagerResolver);
mCustomDirectEvents = UIManagerModuleConstants.getDirectEventTypeConstants();
mUIImplementation =
@ -149,7 +149,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
int minTimeLeftInFrameForNonBatchedOperationMs) {
super(reactContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
mEventDispatcher = new EventDispatcher(reactContext);
mEventDispatcher = reactContext.getEventDispatcher();
mCustomDirectEvents = MapBuilder.newHashMap();
mModuleConstants = createConstants(viewManagersList, null, mCustomDirectEvents);
mUIImplementation =
@ -182,10 +182,14 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
@Override
public void initialize() {
getReactApplicationContext().registerComponentCallbacks(mMemoryTrimCallback);
mEventDispatcher.registerEventEmitter(
DEFAULT,
getReactApplicationContext().getJSModule(RCTEventEmitter.class));
}
@Override
public void onHostResume() {
mUIImplementation.onHostResume();
}

Просмотреть файл

@ -7,16 +7,7 @@
package com.facebook.react.uimanager.events;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import android.util.LongSparseArray;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
@ -26,6 +17,12 @@ import com.facebook.react.modules.core.ChoreographerCompat;
import com.facebook.react.modules.core.ReactChoreographer;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.systrace.Systrace;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
/**
* Class responsible for dispatching UI events to JS. The main purpose of this class is to act as an
@ -59,7 +56,8 @@ import com.facebook.systrace.Systrace;
* EVENT_TYPE_ID_MASK = 0x0000ffff00000000
* COALESCING_KEY_MASK = 0xffff000000000000
*/
public class EventDispatcher implements LifecycleEventListener {
public class EventDispatcher implements LifecycleEventListener,
com.facebook.react.bridge.EventDispatcher {
private static final Comparator<Event> EVENT_COMPARATOR = new Comparator<Event>() {
@Override
@ -99,7 +97,7 @@ public class EventDispatcher implements LifecycleEventListener {
private Event[] mEventsToDispatch = new Event[16];
private int mEventsToDispatchSize = 0;
private volatile @Nullable RCTEventEmitter mRCTEventEmitter;
private volatile @Nullable ReactEventEmitter mRCTEventEmitter = new ReactEventEmitter();
private short mNextEventTypeId = 0;
private volatile boolean mHasDispatchScheduled = false;
@ -153,9 +151,6 @@ public class EventDispatcher implements LifecycleEventListener {
@Override
public void onHostResume() {
if (mRCTEventEmitter == null) {
mRCTEventEmitter = mReactContext.getJSModule(RCTEventEmitter.class);
}
mCurrentFrameCallback.maybePostFromNonUI();
}
@ -255,6 +250,10 @@ public class EventDispatcher implements LifecycleEventListener {
(((long) coalescingKey) & 0xffff) << 48;
}
public void registerEventEmitter(@UIManagerType int uiManagerType, RCTEventEmitter eventEmitter) {
mRCTEventEmitter.register(uiManagerType, eventEmitter);
}
private class ScheduleDispatchFrameCallback extends ChoreographerCompat.FrameCallback {
private volatile boolean mIsPosted = false;
private boolean mShouldStop = false;

Просмотреть файл

@ -14,8 +14,8 @@ import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
public interface RCTEventEmitter extends JavaScriptModule {
public void receiveEvent(int targetTag, String eventName, @Nullable WritableMap event);
public void receiveTouches(
void receiveEvent(int targetTag, String eventName, @Nullable WritableMap event);
void receiveTouches(
String eventName,
WritableArray touches,
WritableArray changedIndices);

Просмотреть файл

@ -0,0 +1,53 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* 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.uimanager.events;
import static com.facebook.react.uimanager.events.TouchesHelper.TARGET_KEY;
import android.util.SparseArray;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.common.ViewUtil;
import javax.annotation.Nullable;
public class ReactEventEmitter implements RCTEventEmitter {
private final SparseArray<RCTEventEmitter> mEventEmitters = new SparseArray<>();
public ReactEventEmitter() {
}
public void register(@UIManagerType int uiManagerType, RCTEventEmitter eventEmitter) {
mEventEmitters.put(uiManagerType, eventEmitter);
}
@Override
public void receiveEvent(int targetReactTag, String eventName, @Nullable WritableMap event) {
getEventEmitter(targetReactTag).receiveEvent(targetReactTag, eventName, event);
}
@Override
public void receiveTouches(
String eventName,
WritableArray touches,
WritableArray changedIndices) {
Assertions.assertCondition(touches.size() > 0);
int targetReactTag = touches.getMap(0).getInt(TARGET_KEY);
getEventEmitter(targetReactTag).receiveTouches(eventName, touches, changedIndices);
}
private RCTEventEmitter getEventEmitter(int reactTag) {
int type = ViewUtil.getUIManagerType(reactTag);
return mEventEmitters.get(type);
}
}