mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-07 09:17:55 +08:00
Decouple Module System from Native Calls
Summary: The JavaScript ecosystem doesn't have the notion of a built-in native module loader. Even Node is decoupled from its module loader. The module loader system is just JS that runs on top of the global `process` object which has all the built-in goodies. Additionally there is no such thing as a global require. That is something unique to our providesModule system. In other module systems such as node, every require is contextual. Even registered npm names are localized by version. The only global namespace that is accessible to the host environment is the global object. Normally module systems attaches itself onto the hooks provided by the host environment on the global object. Currently, we have two forms of dispatch that reaches directly into the module system. executeJSCall which reaches directly into require. Everything now calls through the BatchedBridge module (except one RCTLog edge case that I will fix). I propose that the executors calls directly onto `BatchedBridge` through an instance on the global so that everything is guaranteed to go through it. It becomes the main communication hub. I also propose that we drop the dynamic requires inside of MessageQueue/BatchBridge and instead have the modules register themselves with the bridge. executeJSCall was originally modeled after the XHP equivalent. The XHP equivalent was designed that way because the act of doing the call was the thing that defined a dependency on the module from the page. However, that is not how React Native works. The JS side is driving the dependencies by virtue of requiring new modules and frameworks and the existence of dependencies is driven by the JS side, so this design doesn't make as much sense. The main driver for this is to be able to introduce a new module system like Prepack's module system. However, it also unlocks the possibility to do dead module elimination even in our current module system. It is currently not possible because we don't know which module might be called from native. Since the module system now becomes decoupled we could publish all our providesModule modules as npm/CommonJS modules using a rewrite script. That's what React Core does. That way people could use any CommonJS bundler such as Webpack, Closure Compiler, Rollup or some new innovation to create a JS bundle. This diff expands the executeJSCalls to the BatchedBridge's three individual pieces to make them first class instead of being dynamic. This removes one layer of abstraction. Hopefully we can also remove more of the things that register themselves with the BatchedBridge (various EventEmitters) and instead have everything go through the public protocol. ReactMethod/RCT_EXPORT_METHOD. public Reviewed By: vjeux Differential Revision: D2717535 fb-gh-sync-id: 70114f05483124f5ac5c4570422bb91a60a727f6
This commit is contained in:
committed by
facebook-github-bot-5
parent
99bba8ca4e
commit
8d397b4cbc
@@ -27,7 +27,6 @@ import com.facebook.react.modules.debug.AnimationsDebugModule;
|
||||
import com.facebook.react.modules.debug.SourceCodeModule;
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
||||
import com.facebook.react.uimanager.AppRegistry;
|
||||
import com.facebook.react.uimanager.ReactNative;
|
||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
@@ -97,7 +96,6 @@ import com.facebook.systrace.Systrace;
|
||||
RCTNativeAppEventEmitter.class,
|
||||
AppRegistry.class,
|
||||
BridgeProfiling.class,
|
||||
ReactNative.class,
|
||||
DebugComponentOwnershipModule.RCTDebugComponentOwnership.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ import com.facebook.react.devsupport.ReactInstanceDevCommandsHandler;
|
||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.AppRegistry;
|
||||
import com.facebook.react.uimanager.ReactNative;
|
||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
@@ -581,8 +580,8 @@ import com.facebook.systrace.Systrace;
|
||||
ReactRootView rootView,
|
||||
CatalystInstance catalystInstance) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
catalystInstance.getJSModule(ReactNative.class)
|
||||
.unmountComponentAtNodeAndRemoveContainer(rootView.getId());
|
||||
catalystInstance.getJSModule(AppRegistry.class)
|
||||
.unmountApplicationComponentAtRootTag(rootView.getId());
|
||||
}
|
||||
|
||||
private void tearDownReactContext(ReactContext reactContext) {
|
||||
|
||||
@@ -126,7 +126,6 @@ public class JSDebuggerWebSocketClient implements WebSocketListener {
|
||||
}
|
||||
|
||||
public void executeJSCall(
|
||||
String moduleName,
|
||||
String methodName,
|
||||
String jsonArgsArray,
|
||||
JSDebuggerCallback callback) {
|
||||
@@ -136,9 +135,7 @@ public class JSDebuggerWebSocketClient implements WebSocketListener {
|
||||
|
||||
try {
|
||||
JsonGenerator jg = startMessageObject(requestID);
|
||||
jg.writeStringField("method","executeJSCall");
|
||||
jg.writeStringField("moduleName", moduleName);
|
||||
jg.writeStringField("moduleMethod", methodName);
|
||||
jg.writeStringField("method", methodName);
|
||||
jg.writeFieldName("arguments");
|
||||
jg.writeRawValue(jsonArgsArray);
|
||||
sendMessage(requestID, endMessageObject(jg));
|
||||
|
||||
@@ -40,13 +40,12 @@ public interface JavaJSExecutor {
|
||||
|
||||
/**
|
||||
* Execute javascript method within js context
|
||||
* @param modulename name of the common-js like module to execute the method from
|
||||
* @param methodName name of the method to be executed
|
||||
* @param jsonArgsArray json encoded array of arguments provided for the method call
|
||||
* @return json encoded value returned from the method call
|
||||
*/
|
||||
@DoNotStrip
|
||||
String executeJSCall(String modulename, String methodName, String jsonArgsArray)
|
||||
String executeJSCall(String methodName, String jsonArgsArray)
|
||||
throws ProxyExecutorException;
|
||||
|
||||
@DoNotStrip
|
||||
|
||||
@@ -160,11 +160,10 @@ public class WebsocketJavaScriptExecutor implements JavaJSExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String executeJSCall(String moduleName, String methodName, String jsonArgsArray)
|
||||
public @Nullable String executeJSCall(String methodName, String jsonArgsArray)
|
||||
throws ProxyExecutorException {
|
||||
JSExecutorCallbackFuture callback = new JSExecutorCallbackFuture();
|
||||
Assertions.assertNotNull(mWebSocketClient).executeJSCall(
|
||||
moduleName,
|
||||
methodName,
|
||||
jsonArgsArray,
|
||||
callback);
|
||||
|
||||
@@ -18,4 +18,6 @@ import com.facebook.react.bridge.WritableMap;
|
||||
public interface AppRegistry extends JavaScriptModule {
|
||||
|
||||
void runApplication(String appKey, WritableMap appParameters);
|
||||
void unmountApplicationComponentAtRootTag(int rootNodeTag);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.uimanager;
|
||||
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
|
||||
/**
|
||||
* JS module interface - used by UIManager to communicate with main React JS module methods
|
||||
*/
|
||||
public interface ReactNative extends JavaScriptModule {
|
||||
void unmountComponentAtNodeAndRemoveContainer(int rootNodeTag);
|
||||
}
|
||||
@@ -27,11 +27,18 @@ public:
|
||||
m_jsExecutor->executeApplicationScript(script, sourceURL);
|
||||
}
|
||||
|
||||
void executeJSCall(
|
||||
const std::string& moduleName,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) {
|
||||
auto returnedJSON = m_jsExecutor->executeJSCall(moduleName, methodName, arguments);
|
||||
void flush() {
|
||||
auto returnedJSON = m_jsExecutor->flush();
|
||||
m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */);
|
||||
}
|
||||
|
||||
void callFunction(const double moduleId, const double methodId, const folly::dynamic& arguments) {
|
||||
auto returnedJSON = m_jsExecutor->callFunction(moduleId, methodId, arguments);
|
||||
m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */);
|
||||
}
|
||||
|
||||
void invokeCallback(const double callbackId, const folly::dynamic& arguments) {
|
||||
auto returnedJSON = m_jsExecutor->invokeCallback(callbackId, arguments);
|
||||
m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */);
|
||||
}
|
||||
|
||||
@@ -88,17 +95,31 @@ void Bridge::executeApplicationScript(const std::string& script, const std::stri
|
||||
m_threadState->executeApplicationScript(script, sourceURL);
|
||||
}
|
||||
|
||||
void Bridge::executeJSCall(
|
||||
const std::string& script,
|
||||
const std::string& sourceURL,
|
||||
const std::vector<folly::dynamic>& arguments) {
|
||||
void Bridge::flush() {
|
||||
if (*m_destroyed) {
|
||||
return;
|
||||
}
|
||||
m_threadState->flush();
|
||||
}
|
||||
|
||||
void Bridge::callFunction(const double moduleId, const double methodId, const folly::dynamic& arguments) {
|
||||
if (*m_destroyed) {
|
||||
return;
|
||||
}
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "Bridge.executeJSCall");
|
||||
FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "Bridge.callFunction");
|
||||
#endif
|
||||
m_threadState->executeJSCall(script, sourceURL, arguments);
|
||||
m_threadState->callFunction(moduleId, methodId, arguments);
|
||||
}
|
||||
|
||||
void Bridge::invokeCallback(const double callbackId, const folly::dynamic& arguments) {
|
||||
if (*m_destroyed) {
|
||||
return;
|
||||
}
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "Bridge.invokeCallback");
|
||||
#endif
|
||||
m_threadState->invokeCallback(callbackId, arguments);
|
||||
}
|
||||
|
||||
void Bridge::setGlobalVariable(const std::string& propName, const std::string& jsonValue) {
|
||||
|
||||
@@ -29,10 +29,22 @@ public:
|
||||
Bridge(const RefPtr<JSExecutorFactory>& jsExecutorFactory, Callback callback);
|
||||
virtual ~Bridge();
|
||||
|
||||
void executeJSCall(
|
||||
const std::string& moduleName,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& values);
|
||||
/**
|
||||
* Flush get the next queue of changes.
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Executes a function with the module ID and method ID and any additional
|
||||
* arguments in JS.
|
||||
*/
|
||||
void callFunction(const double moduleId, const double methodId, const folly::dynamic& args);
|
||||
|
||||
/**
|
||||
* Invokes a callback with the cbID, and optional additional arguments in JS.
|
||||
*/
|
||||
void invokeCallback(const double callbackId, const folly::dynamic& args);
|
||||
|
||||
void executeApplicationScript(const std::string& script, const std::string& sourceURL);
|
||||
void setGlobalVariable(const std::string& propName, const std::string& jsonValue);
|
||||
bool supportsProfiling();
|
||||
|
||||
@@ -28,13 +28,31 @@ public:
|
||||
|
||||
class JSExecutor {
|
||||
public:
|
||||
/**
|
||||
* Execute an application script bundle in the JS context.
|
||||
*/
|
||||
virtual void executeApplicationScript(
|
||||
const std::string& script,
|
||||
const std::string& sourceURL) = 0;
|
||||
virtual std::string executeJSCall(
|
||||
const std::string& moduleName,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) = 0;
|
||||
|
||||
/**
|
||||
* Executes BatchedBridge.flushedQueue in JS to get the next queue of changes.
|
||||
*/
|
||||
virtual std::string flush() = 0;
|
||||
|
||||
/**
|
||||
* Executes BatchedBridge.callFunctionReturnFlushedQueue with the module ID,
|
||||
* method ID and optional additional arguments in JS, and returns the next
|
||||
* queue.
|
||||
*/
|
||||
virtual std::string callFunction(const double moduleId, const double methodId, const folly::dynamic& arguments) = 0;
|
||||
|
||||
/**
|
||||
* Executes BatchedBridge.invokeCallbackAndReturnFlushedQueue with the cbID,
|
||||
* and optional additional arguments in JS and returns the next queue.
|
||||
*/
|
||||
virtual std::string invokeCallback(const double callbackId, const folly::dynamic& arguments) = 0;
|
||||
|
||||
virtual void setGlobalVariable(
|
||||
const std::string& propName,
|
||||
const std::string& jsonValue) = 0;
|
||||
|
||||
@@ -80,6 +80,26 @@ static JSValueRef evaluateScriptWithJSC(
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string executeJSCallWithJSC(
|
||||
JSGlobalContextRef ctx,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) {
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
FbSystraceSection s(
|
||||
TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.executeJSCall",
|
||||
"method", methodName);
|
||||
#endif
|
||||
|
||||
// Evaluate script with JSC
|
||||
folly::dynamic jsonArgs(arguments.begin(), arguments.end());
|
||||
auto js = folly::to<folly::fbstring>(
|
||||
"__fbBatchedBridge.", methodName, ".apply(null, ",
|
||||
folly::toJson(jsonArgs), ")");
|
||||
auto result = evaluateScriptWithJSC(ctx, String(js.c_str()), nullptr);
|
||||
JSValueProtect(ctx, result);
|
||||
return Value(ctx, result).toJSONString();
|
||||
}
|
||||
|
||||
std::unique_ptr<JSExecutor> JSCExecutorFactory::createJSExecutor(FlushImmediateCallback cb) {
|
||||
return std::unique_ptr<JSExecutor>(new JSCExecutor(cb));
|
||||
}
|
||||
@@ -130,25 +150,28 @@ void JSCExecutor::executeApplicationScript(
|
||||
evaluateScriptWithJSC(m_context, jsScript, jsSourceURL);
|
||||
}
|
||||
|
||||
std::string JSCExecutor::executeJSCall(
|
||||
const std::string& moduleName,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) {
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
FbSystraceSection s(
|
||||
TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.executeJSCall",
|
||||
"module", moduleName,
|
||||
"method", methodName);
|
||||
#endif
|
||||
std::string JSCExecutor::flush() {
|
||||
// TODO: Make this a first class function instead of evaling. #9317773
|
||||
return executeJSCallWithJSC(m_context, "flushedQueue", std::vector<folly::dynamic>());
|
||||
}
|
||||
|
||||
// Evaluate script with JSC
|
||||
folly::dynamic jsonArgs(arguments.begin(), arguments.end());
|
||||
auto js = folly::to<folly::fbstring>(
|
||||
"require('", moduleName, "').", methodName, ".apply(null, ",
|
||||
folly::toJson(jsonArgs), ")");
|
||||
auto result = evaluateScriptWithJSC(m_context, String(js.c_str()), nullptr);
|
||||
JSValueProtect(m_context, result);
|
||||
return Value(m_context, result).toJSONString();
|
||||
std::string JSCExecutor::callFunction(const double moduleId, const double methodId, const folly::dynamic& arguments) {
|
||||
// TODO: Make this a first class function instead of evaling. #9317773
|
||||
std::vector<folly::dynamic> call{
|
||||
(double) moduleId,
|
||||
(double) methodId,
|
||||
std::move(arguments),
|
||||
};
|
||||
return executeJSCallWithJSC(m_context, "callFunctionReturnFlushedQueue", std::move(call));
|
||||
}
|
||||
|
||||
std::string JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) {
|
||||
// TODO: Make this a first class function instead of evaling. #9317773
|
||||
std::vector<folly::dynamic> call{
|
||||
(double) callbackId,
|
||||
std::move(arguments)
|
||||
};
|
||||
return executeJSCallWithJSC(m_context, "invokeCallbackAndReturnFlushedQueue", std::move(call));
|
||||
}
|
||||
|
||||
void JSCExecutor::setGlobalVariable(const std::string& propName, const std::string& jsonValue) {
|
||||
|
||||
@@ -18,13 +18,18 @@ class JSCExecutor : public JSExecutor {
|
||||
public:
|
||||
explicit JSCExecutor(FlushImmediateCallback flushImmediateCallback);
|
||||
~JSCExecutor() override;
|
||||
|
||||
virtual void executeApplicationScript(
|
||||
const std::string& script,
|
||||
const std::string& sourceURL) override;
|
||||
virtual std::string executeJSCall(
|
||||
const std::string& moduleName,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) override;
|
||||
virtual std::string flush() override;
|
||||
virtual std::string callFunction(
|
||||
const double moduleId,
|
||||
const double methodId,
|
||||
const folly::dynamic& arguments) override;
|
||||
virtual std::string invokeCallback(
|
||||
const double callbackId,
|
||||
const folly::dynamic& arguments) override;
|
||||
virtual void setGlobalVariable(
|
||||
const std::string& propName,
|
||||
const std::string& jsonValue) override;
|
||||
|
||||
@@ -628,7 +628,7 @@ static void executeApplicationScript(
|
||||
try {
|
||||
// Execute the application script and collect/dispatch any native calls that might have occured
|
||||
bridge->executeApplicationScript(script, sourceUri);
|
||||
bridge->executeJSCall("BatchedBridge", "flushedQueue", std::vector<folly::dynamic>());
|
||||
bridge->flush();
|
||||
} catch (...) {
|
||||
translatePendingCppExceptionToJavaException();
|
||||
}
|
||||
@@ -682,13 +682,12 @@ static void callFunction(JNIEnv* env, jobject obj, jint moduleId, jint methodId,
|
||||
NativeArray::jhybridobject args) {
|
||||
auto bridge = extractRefPtr<Bridge>(env, obj);
|
||||
auto arguments = cthis(wrap_alias(args));
|
||||
std::vector<folly::dynamic> call{
|
||||
(double) moduleId,
|
||||
(double) methodId,
|
||||
std::move(arguments->array),
|
||||
};
|
||||
try {
|
||||
bridge->executeJSCall("BatchedBridge", "callFunctionReturnFlushedQueue", std::move(call));
|
||||
bridge->callFunction(
|
||||
(double) moduleId,
|
||||
(double) methodId,
|
||||
std::move(arguments->array)
|
||||
);
|
||||
} catch (...) {
|
||||
translatePendingCppExceptionToJavaException();
|
||||
}
|
||||
@@ -698,12 +697,11 @@ static void invokeCallback(JNIEnv* env, jobject obj, jint callbackId,
|
||||
NativeArray::jhybridobject args) {
|
||||
auto bridge = extractRefPtr<Bridge>(env, obj);
|
||||
auto arguments = cthis(wrap_alias(args));
|
||||
std::vector<folly::dynamic> call{
|
||||
(double) callbackId,
|
||||
std::move(arguments->array)
|
||||
};
|
||||
try {
|
||||
bridge->executeJSCall("BatchedBridge", "invokeCallbackAndReturnFlushedQueue", std::move(call));
|
||||
bridge->invokeCallback(
|
||||
(double) callbackId,
|
||||
std::move(arguments->array)
|
||||
);
|
||||
} catch (...) {
|
||||
translatePendingCppExceptionToJavaException();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,20 @@ namespace react {
|
||||
|
||||
const auto EXECUTOR_BASECLASS = "com/facebook/react/bridge/JavaJSExecutor";
|
||||
|
||||
static std::string executeJSCallWithProxy(
|
||||
jobject executor,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) {
|
||||
static auto executeJSCall =
|
||||
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<jstring(jstring, jstring)>("executeJSCall");
|
||||
|
||||
auto result = executeJSCall(
|
||||
executor,
|
||||
jni::make_jstring(methodName).get(),
|
||||
jni::make_jstring(folly::toJson(arguments).c_str()).get());
|
||||
return result->toString();
|
||||
}
|
||||
|
||||
std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor(FlushImmediateCallback ignoredCallback) {
|
||||
FBASSERTMSGF(
|
||||
m_executor.get() != nullptr,
|
||||
@@ -36,19 +50,26 @@ void ProxyExecutor::executeApplicationScript(
|
||||
jni::make_jstring(sourceURL).get());
|
||||
}
|
||||
|
||||
std::string ProxyExecutor::executeJSCall(
|
||||
const std::string& moduleName,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) {
|
||||
static auto executeJSCall =
|
||||
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<jstring(jstring, jstring, jstring)>("executeJSCall");
|
||||
|
||||
auto result = executeJSCall(
|
||||
m_executor.get(),
|
||||
jni::make_jstring(moduleName).get(),
|
||||
jni::make_jstring(methodName).get(),
|
||||
jni::make_jstring(folly::toJson(arguments).c_str()).get());
|
||||
return result->toString();
|
||||
std::string ProxyExecutor::flush() {
|
||||
return executeJSCallWithProxy(m_executor.get(), "flushedQueue", std::vector<folly::dynamic>());
|
||||
}
|
||||
|
||||
std::string ProxyExecutor::callFunction(const double moduleId, const double methodId, const folly::dynamic& arguments) {
|
||||
std::vector<folly::dynamic> call{
|
||||
(double) moduleId,
|
||||
(double) methodId,
|
||||
std::move(arguments),
|
||||
};
|
||||
return executeJSCallWithProxy(m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call));
|
||||
}
|
||||
|
||||
std::string ProxyExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) {
|
||||
std::vector<folly::dynamic> call{
|
||||
(double) callbackId,
|
||||
std::move(arguments)
|
||||
};
|
||||
return executeJSCallWithProxy(m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call));
|
||||
}
|
||||
|
||||
void ProxyExecutor::setGlobalVariable(const std::string& propName, const std::string& jsonValue) {
|
||||
|
||||
@@ -32,10 +32,14 @@ public:
|
||||
virtual void executeApplicationScript(
|
||||
const std::string& script,
|
||||
const std::string& sourceURL) override;
|
||||
virtual std::string executeJSCall(
|
||||
const std::string& moduleName,
|
||||
const std::string& methodName,
|
||||
const std::vector<folly::dynamic>& arguments) override;
|
||||
virtual std::string flush() override;
|
||||
virtual std::string callFunction(
|
||||
const double moduleId,
|
||||
const double methodId,
|
||||
const folly::dynamic& arguments) override;
|
||||
virtual std::string invokeCallback(
|
||||
const double callbackId,
|
||||
const folly::dynamic& arguments) override;
|
||||
virtual void setGlobalVariable(
|
||||
const std::string& propName,
|
||||
const std::string& jsonValue) override;
|
||||
|
||||
@@ -20,17 +20,13 @@ static std::vector<MethodCall> executeForMethodCalls(
|
||||
int moduleId,
|
||||
int methodId,
|
||||
std::vector<MethodArgument> args = std::vector<MethodArgument>()) {
|
||||
std::vector<MethodArgument> call;
|
||||
call.emplace_back((double) moduleId);
|
||||
call.emplace_back((double) methodId);
|
||||
call.emplace_back(std::move(args));
|
||||
return parseMethodCalls(e.executeJSCall("Bridge", "callFunction", call));
|
||||
return parseMethodCalls(e.callFunction(moduleId, methodId, std::move(args)));
|
||||
}
|
||||
|
||||
TEST(JSCExecutor, CallFunction) {
|
||||
auto jsText = ""
|
||||
"var Bridge = {"
|
||||
" callFunction: function (module, method, args) {"
|
||||
" callFunctionReturnFlushedQueue: function (module, method, args) {"
|
||||
" return [[module + 1], [method + 1], [args]];"
|
||||
" },"
|
||||
"};"
|
||||
@@ -58,7 +54,7 @@ TEST(JSCExecutor, CallFunction) {
|
||||
TEST(JSCExecutor, CallFunctionWithMap) {
|
||||
auto jsText = ""
|
||||
"var Bridge = {"
|
||||
" callFunction: function (module, method, args) {"
|
||||
" callFunctionReturnFlushedQueue: function (module, method, args) {"
|
||||
" var s = args[0].foo + args[0].bar + args[0].baz;"
|
||||
" return [[module], [method], [[s]]];"
|
||||
" },"
|
||||
@@ -85,7 +81,7 @@ TEST(JSCExecutor, CallFunctionWithMap) {
|
||||
TEST(JSCExecutor, CallFunctionReturningMap) {
|
||||
auto jsText = ""
|
||||
"var Bridge = {"
|
||||
" callFunction: function (module, method, args) {"
|
||||
" callFunctionReturnFlushedQueue: function (module, method, args) {"
|
||||
" var s = { foo: 4, bar: true };"
|
||||
" return [[module], [method], [[s]]];"
|
||||
" },"
|
||||
@@ -111,7 +107,7 @@ TEST(JSCExecutor, CallFunctionReturningMap) {
|
||||
TEST(JSCExecutor, CallFunctionWithArray) {
|
||||
auto jsText = ""
|
||||
"var Bridge = {"
|
||||
" callFunction: function (module, method, args) {"
|
||||
" callFunctionReturnFlushedQueue: function (module, method, args) {"
|
||||
" var s = args[0][0]+ args[0][1] + args[0][2] + args[0].length;"
|
||||
" return [[module], [method], [[s]]];"
|
||||
" },"
|
||||
@@ -138,7 +134,7 @@ TEST(JSCExecutor, CallFunctionWithArray) {
|
||||
TEST(JSCExecutor, CallFunctionReturningNumberArray) {
|
||||
auto jsText = ""
|
||||
"var Bridge = {"
|
||||
" callFunction: function (module, method, args) {"
|
||||
" callFunctionReturnFlushedQueue: function (module, method, args) {"
|
||||
" var s = [3, 1, 4];"
|
||||
" return [[module], [method], [[s]]];"
|
||||
" },"
|
||||
@@ -162,7 +158,7 @@ TEST(JSCExecutor, CallFunctionReturningNumberArray) {
|
||||
TEST(JSCExecutor, SetSimpleGlobalVariable) {
|
||||
auto jsText = ""
|
||||
"var Bridge = {"
|
||||
" callFunction: function (module, method, args) {"
|
||||
" callFunctionReturnFlushedQueue: function (module, method, args) {"
|
||||
" return [[module], [method], [[__foo]]];"
|
||||
" },"
|
||||
"};"
|
||||
@@ -182,7 +178,7 @@ TEST(JSCExecutor, SetSimpleGlobalVariable) {
|
||||
TEST(JSCExecutor, SetObjectGlobalVariable) {
|
||||
auto jsText = ""
|
||||
"var Bridge = {"
|
||||
" callFunction: function (module, method, args) {"
|
||||
" callFunctionReturnFlushedQueue: function (module, method, args) {"
|
||||
" return [[module], [method], [[__foo]]];"
|
||||
" },"
|
||||
"};"
|
||||
|
||||
Reference in New Issue
Block a user