mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-10 10:00:16 +08:00
WebWorkers: Add ExecutorToken to route native module calls to/from workers
Summary:To support native modules in web workers, native modules need to have an notion of the JS executor/thread that called into them in order to respond via Callback or JS module call to the right executor on the right thread. ExecutorToken is an object that only serves as a token that can be used to identify an executor/message queue thread in the bridge. It doesn't expose any methods. Native modules Callback objects automatically have this ExecutionContext attached -- JSModule calls for modules that support workers will need to supply an appropriate ExecutorToken when retrieving the JSModule implementation from the ReactContext. Reviewed By: mhorowitz Differential Revision: D2965458 fb-gh-sync-id: 6e354d4df8536d40b12d02bd055f6d06b4ca595d shipit-source-id: 6e354d4df8536d40b12d02bd055f6d06b4ca595d
This commit is contained in:
committed by
Facebook Github Bot 4
parent
f67fa82008
commit
bd95b22844
@@ -57,14 +57,14 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
}
|
||||
|
||||
public abstract @Nullable T extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex);
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex);
|
||||
}
|
||||
|
||||
static final private ArgumentExtractor<Boolean> ARGUMENT_EXTRACTOR_BOOLEAN =
|
||||
new ArgumentExtractor<Boolean>() {
|
||||
@Override
|
||||
public Boolean extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getBoolean(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -73,7 +73,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
new ArgumentExtractor<Double>() {
|
||||
@Override
|
||||
public Double extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getDouble(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -82,7 +82,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
new ArgumentExtractor<Float>() {
|
||||
@Override
|
||||
public Float extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return (float) jsArguments.getDouble(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -91,7 +91,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
new ArgumentExtractor<Integer>() {
|
||||
@Override
|
||||
public Integer extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return (int) jsArguments.getDouble(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -100,7 +100,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
new ArgumentExtractor<String>() {
|
||||
@Override
|
||||
public String extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getString(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -109,7 +109,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
new ArgumentExtractor<ReadableNativeArray>() {
|
||||
@Override
|
||||
public ReadableNativeArray extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getArray(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -118,7 +118,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
new ArgumentExtractor<ReadableMap>() {
|
||||
@Override
|
||||
public ReadableMap extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getMap(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -127,12 +127,12 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
new ArgumentExtractor<Callback>() {
|
||||
@Override
|
||||
public @Nullable Callback extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
if (jsArguments.isNull(atIndex)) {
|
||||
return null;
|
||||
} else {
|
||||
int id = (int) jsArguments.getDouble(atIndex);
|
||||
return new CallbackImpl(catalystInstance, id);
|
||||
return new CallbackImpl(catalystInstance, executorToken, id);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -146,11 +146,11 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
|
||||
@Override
|
||||
public Promise extractArgument(
|
||||
CatalystInstance catalystInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
Callback resolve = ARGUMENT_EXTRACTOR_CALLBACK
|
||||
.extractArgument(catalystInstance, jsArguments, atIndex);
|
||||
.extractArgument(catalystInstance, executorToken, jsArguments, atIndex);
|
||||
Callback reject = ARGUMENT_EXTRACTOR_CALLBACK
|
||||
.extractArgument(catalystInstance, jsArguments, atIndex + 1);
|
||||
.extractArgument(catalystInstance, executorToken, jsArguments, atIndex + 1);
|
||||
return new PromiseImpl(resolve, reject);
|
||||
}
|
||||
};
|
||||
@@ -174,9 +174,21 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
}
|
||||
|
||||
private ArgumentExtractor[] buildArgumentExtractors(Class[] paramTypes) {
|
||||
ArgumentExtractor[] argumentExtractors = new ArgumentExtractor[paramTypes.length];
|
||||
for (int i = 0; i < paramTypes.length; i += argumentExtractors[i].getJSArgumentsNeeded()) {
|
||||
Class argumentClass = paramTypes[i];
|
||||
// Modules that support web workers are expected to take an ExecutorToken as the first
|
||||
// parameter to all their @ReactMethod-annotated methods. We compensate for that here.
|
||||
int executorTokenOffset = 0;
|
||||
if (BaseJavaModule.this.supportsWebWorkers()) {
|
||||
if (paramTypes[0] != ExecutorToken.class) {
|
||||
throw new RuntimeException(
|
||||
"Module " + BaseJavaModule.this + " supports web workers, but " + mMethod.getName() +
|
||||
"does not take an ExecutorToken as its first parameter.");
|
||||
}
|
||||
executorTokenOffset = 1;
|
||||
}
|
||||
|
||||
ArgumentExtractor[] argumentExtractors = new ArgumentExtractor[paramTypes.length - executorTokenOffset];
|
||||
for (int i = 0; i < paramTypes.length - executorTokenOffset; i += argumentExtractors[i].getJSArgumentsNeeded()) {
|
||||
Class argumentClass = paramTypes[i + executorTokenOffset];
|
||||
if (argumentClass == Boolean.class || argumentClass == boolean.class) {
|
||||
argumentExtractors[i] = ARGUMENT_EXTRACTOR_BOOLEAN;
|
||||
} else if (argumentClass == Integer.class || argumentClass == int.class) {
|
||||
@@ -220,7 +232,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(CatalystInstance catalystInstance, ReadableNativeArray parameters) {
|
||||
public void invoke(CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray parameters) {
|
||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "callJavaModuleMethod");
|
||||
try {
|
||||
if (mJSArgumentsNeeded != parameters.size()) {
|
||||
@@ -229,11 +241,18 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
parameters.size() + " arguments, expected " + mJSArgumentsNeeded);
|
||||
}
|
||||
|
||||
// Modules that support web workers are expected to take an ExecutorToken as the first
|
||||
// parameter to all their @ReactMethod-annotated methods. We compensate for that here.
|
||||
int i = 0, jsArgumentsConsumed = 0;
|
||||
int executorTokenOffset = 0;
|
||||
if (BaseJavaModule.this.supportsWebWorkers()) {
|
||||
mArguments[0] = executorToken;
|
||||
executorTokenOffset = 1;
|
||||
}
|
||||
try {
|
||||
for (; i < mArgumentExtractors.length; i++) {
|
||||
mArguments[i] = mArgumentExtractors[i].extractArgument(
|
||||
catalystInstance, parameters, jsArgumentsConsumed);
|
||||
mArguments[i + executorTokenOffset] = mArgumentExtractors[i].extractArgument(
|
||||
catalystInstance, executorToken, parameters, jsArgumentsConsumed);
|
||||
jsArgumentsConsumed += mArgumentExtractors[i].getJSArgumentsNeeded();
|
||||
}
|
||||
} catch (UnexpectedNativeTypeException e) {
|
||||
@@ -341,7 +360,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
public void onCatalystInstanceDestroy() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsWebWorkers() {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user