mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-03-30 09:23:22 +08:00
Make MessageQueue module/method tables DEV-only
Reviewed By: lexs Differential Revision: D3431065 fbshipit-source-id: fcb90bd53460064f8a0efee346ed3b87886e7b60
This commit is contained in:
committed by
Facebook Github Bot 5
parent
b98a05ebd3
commit
979d1c7e71
@@ -13,32 +13,30 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
let Systrace = require('Systrace');
|
||||
let ErrorUtils = require('ErrorUtils');
|
||||
let JSTimersExecution = require('JSTimersExecution');
|
||||
let Platform = require('Platform');
|
||||
const Systrace = require('Systrace');
|
||||
const ErrorUtils = require('ErrorUtils');
|
||||
const JSTimersExecution = require('JSTimersExecution');
|
||||
|
||||
let invariant = require('fbjs/lib/invariant');
|
||||
let keyMirror = require('fbjs/lib/keyMirror');
|
||||
let stringifySafe = require('stringifySafe');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
const keyMirror = require('fbjs/lib/keyMirror');
|
||||
const stringifySafe = require('stringifySafe');
|
||||
|
||||
let MODULE_IDS = 0;
|
||||
let METHOD_IDS = 1;
|
||||
let PARAMS = 2;
|
||||
let CALL_IDS = 3;
|
||||
let MIN_TIME_BETWEEN_FLUSHES_MS = 5;
|
||||
const MODULE_IDS = 0;
|
||||
const METHOD_IDS = 1;
|
||||
const PARAMS = 2;
|
||||
const MIN_TIME_BETWEEN_FLUSHES_MS = 5;
|
||||
|
||||
let TRACE_TAG_REACT_APPS = 1 << 17;
|
||||
const TRACE_TAG_REACT_APPS = 1 << 17;
|
||||
|
||||
let SPY_MODE = false;
|
||||
const SPY_MODE = false;
|
||||
|
||||
let MethodTypes = keyMirror({
|
||||
const MethodTypes = keyMirror({
|
||||
remote: null,
|
||||
remoteAsync: null,
|
||||
syncHook: null,
|
||||
});
|
||||
|
||||
var guard = (fn) => {
|
||||
const guard = (fn) => {
|
||||
try {
|
||||
fn();
|
||||
} catch (error) {
|
||||
@@ -51,7 +49,6 @@ type Config = {
|
||||
};
|
||||
|
||||
class MessageQueue {
|
||||
|
||||
constructor(configProvider: () => Config) {
|
||||
this._callableModules = {};
|
||||
this._queue = [[], [], [], 0];
|
||||
@@ -61,24 +58,28 @@ class MessageQueue {
|
||||
this._lastFlush = 0;
|
||||
this._eventLoopStartTime = new Date().getTime();
|
||||
|
||||
this._debugInfo = {};
|
||||
this._remoteModuleTable = {};
|
||||
this._remoteMethodTable = {};
|
||||
if (__DEV__) {
|
||||
this._debugInfo = {};
|
||||
this._remoteModuleTable = {};
|
||||
this._remoteMethodTable = {};
|
||||
}
|
||||
|
||||
[
|
||||
'invokeCallbackAndReturnFlushedQueue',
|
||||
'callFunctionReturnFlushedQueue',
|
||||
'flushedQueue',
|
||||
].forEach((fn) => this[fn] = this[fn].bind(this));
|
||||
].forEach((fn) => (this[fn] = this[fn].bind(this)));
|
||||
|
||||
lazyProperty(this, 'RemoteModules', () => {
|
||||
let {remoteModuleConfig} = configProvider();
|
||||
let modulesConfig = this._genModulesConfig(remoteModuleConfig);
|
||||
let modules = this._genModules(modulesConfig);
|
||||
const {remoteModuleConfig} = configProvider();
|
||||
const modulesConfig = this._genModulesConfig(remoteModuleConfig);
|
||||
const modules = this._genModules(modulesConfig);
|
||||
|
||||
this._genLookupTables(
|
||||
modulesConfig, this._remoteModuleTable, this._remoteMethodTable
|
||||
);
|
||||
if (__DEV__) {
|
||||
this._genLookupTables(
|
||||
modulesConfig, this._remoteModuleTable, this._remoteMethodTable
|
||||
);
|
||||
}
|
||||
|
||||
return modules;
|
||||
});
|
||||
@@ -108,7 +109,7 @@ class MessageQueue {
|
||||
flushedQueue() {
|
||||
this.__callImmediates();
|
||||
|
||||
let queue = this._queue;
|
||||
const queue = this._queue;
|
||||
this._queue = [[], [], [], this._callID];
|
||||
return queue[0].length ? queue : null;
|
||||
}
|
||||
@@ -116,7 +117,9 @@ class MessageQueue {
|
||||
processModuleConfig(config, moduleID) {
|
||||
const info = this._genModule(config, moduleID);
|
||||
this.RemoteModules[info.name] = info.module;
|
||||
this._genLookup(config, moduleID, this._remoteModuleTable, this._remoteMethodTable);
|
||||
if (__DEV__) {
|
||||
this._genLookup(config, moduleID, this._remoteModuleTable, this._remoteMethodTable);
|
||||
}
|
||||
return info.module;
|
||||
}
|
||||
|
||||
@@ -136,11 +139,12 @@ class MessageQueue {
|
||||
|
||||
__nativeCall(module, method, params, onFail, onSucc) {
|
||||
if (onFail || onSucc) {
|
||||
// eventually delete old debug info
|
||||
(this._callbackID > (1 << 5)) &&
|
||||
(this._debugInfo[this._callbackID >> 5] = null);
|
||||
|
||||
this._debugInfo[this._callbackID >> 1] = [module, method];
|
||||
if (__DEV__) {
|
||||
// eventually delete old debug info
|
||||
(this._callbackID > (1 << 5)) &&
|
||||
(this._debugInfo[this._callbackID >> 5] = null);
|
||||
this._debugInfo[this._callbackID >> 1] = [module, method];
|
||||
}
|
||||
onFail && params.push(this._callbackID);
|
||||
this._callbacks[this._callbackID++] = onFail;
|
||||
onSucc && params.push(this._callbackID);
|
||||
@@ -155,7 +159,7 @@ class MessageQueue {
|
||||
this._queue[METHOD_IDS].push(method);
|
||||
this._queue[PARAMS].push(params);
|
||||
|
||||
var now = new Date().getTime();
|
||||
const now = new Date().getTime();
|
||||
if (global.nativeFlushQueueImmediate &&
|
||||
now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS) {
|
||||
global.nativeFlushQueueImmediate(this._queue);
|
||||
@@ -176,7 +180,7 @@ class MessageQueue {
|
||||
if (__DEV__ && SPY_MODE) {
|
||||
console.log('N->JS : ' + module + '.' + method + '(' + JSON.stringify(args) + ')');
|
||||
}
|
||||
var moduleMethods = this._callableModules[module];
|
||||
const moduleMethods = this._callableModules[module];
|
||||
invariant(
|
||||
!!moduleMethods,
|
||||
'Module %s is not a registered callable module.',
|
||||
@@ -189,31 +193,42 @@ class MessageQueue {
|
||||
__invokeCallback(cbID, args) {
|
||||
this._lastFlush = new Date().getTime();
|
||||
this._eventLoopStartTime = this._lastFlush;
|
||||
let callback = this._callbacks[cbID];
|
||||
let debug = this._debugInfo[cbID >> 1];
|
||||
let module = debug && this._remoteModuleTable[debug[0]];
|
||||
let method = debug && this._remoteMethodTable[debug[0]][debug[1]];
|
||||
if (!callback) {
|
||||
let errorMessage = `Callback with id ${cbID}: ${module}.${method}() not found`;
|
||||
if (method) {
|
||||
errorMessage = `The callback ${method}() exists in module ${module}, `
|
||||
+ `but only one callback may be registered to a function in a native module.`;
|
||||
const callback = this._callbacks[cbID];
|
||||
|
||||
if (__DEV__) {
|
||||
const debug = this._debugInfo[cbID >> 1];
|
||||
const module = debug && this._remoteModuleTable[debug[0]];
|
||||
const method = debug && this._remoteMethodTable[debug[0]][debug[1]];
|
||||
if (!callback) {
|
||||
const errorMessage = `Callback with id ${cbID}: ${module}.${method}() not found`;
|
||||
if (method) {
|
||||
errorMessage = `The callback ${method}() exists in module ${module}, `
|
||||
+ `but only one callback may be registered to a function in a native module.`;
|
||||
}
|
||||
invariant(
|
||||
callback,
|
||||
errorMessage
|
||||
);
|
||||
}
|
||||
const profileName = debug ? '<callback for ' + module + '.' + method + '>' : cbID;
|
||||
if (callback && SPY_MODE && __DEV__) {
|
||||
console.log('N->JS : ' + profileName + '(' + JSON.stringify(args) + ')');
|
||||
}
|
||||
Systrace.beginEvent(
|
||||
`MessageQueue.invokeCallback(${profileName}, ${stringifySafe(args)})`);
|
||||
} else {
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
invariant(
|
||||
callback,
|
||||
errorMessage
|
||||
);
|
||||
}
|
||||
let profileName = debug ? '<callback for ' + module + '.' + method + '>' : cbID;
|
||||
if (callback && SPY_MODE && __DEV__) {
|
||||
console.log('N->JS : ' + profileName + '(' + JSON.stringify(args) + ')');
|
||||
}
|
||||
Systrace.beginEvent(
|
||||
`MessageQueue.invokeCallback(${profileName}, ${stringifySafe(args)})`);
|
||||
|
||||
this._callbacks[cbID & ~1] = null;
|
||||
this._callbacks[cbID | 1] = null;
|
||||
callback.apply(null, args);
|
||||
Systrace.endEvent();
|
||||
|
||||
if (__DEV__) {
|
||||
Systrace.endEvent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,24 +244,24 @@ class MessageQueue {
|
||||
if (Array.isArray(modules)) {
|
||||
return modules;
|
||||
} else {
|
||||
let moduleArray = [];
|
||||
let moduleNames = Object.keys(modules);
|
||||
const moduleArray = [];
|
||||
const moduleNames = Object.keys(modules);
|
||||
for (var i = 0, l = moduleNames.length; i < l; i++) {
|
||||
let moduleName = moduleNames[i];
|
||||
let moduleConfig = modules[moduleName];
|
||||
let module = [moduleName];
|
||||
const moduleName = moduleNames[i];
|
||||
const moduleConfig = modules[moduleName];
|
||||
const module = [moduleName];
|
||||
if (moduleConfig.constants) {
|
||||
module.push(moduleConfig.constants);
|
||||
}
|
||||
let methodsConfig = moduleConfig.methods;
|
||||
const methodsConfig = moduleConfig.methods;
|
||||
if (methodsConfig) {
|
||||
let methods = [];
|
||||
let asyncMethods = [];
|
||||
let syncHooks = [];
|
||||
let methodNames = Object.keys(methodsConfig);
|
||||
const methods = [];
|
||||
const asyncMethods = [];
|
||||
const syncHooks = [];
|
||||
const methodNames = Object.keys(methodsConfig);
|
||||
for (var j = 0, ll = methodNames.length; j < ll; j++) {
|
||||
let methodName = methodNames[j];
|
||||
let methodConfig = methodsConfig[methodName];
|
||||
const methodName = methodNames[j];
|
||||
const methodConfig = methodsConfig[methodName];
|
||||
methods[methodConfig.methodID] = methodName;
|
||||
if (methodConfig.type === MethodTypes.remoteAsync) {
|
||||
asyncMethods.push(methodConfig.methodID);
|
||||
@@ -289,10 +304,10 @@ class MessageQueue {
|
||||
}
|
||||
|
||||
_genModules(remoteModules) {
|
||||
let modules = {};
|
||||
const modules = {};
|
||||
|
||||
remoteModules.forEach((config, moduleID) => {
|
||||
let info = this._genModule(config, moduleID);
|
||||
const info = this._genModule(config, moduleID);
|
||||
if (info) {
|
||||
modules[info.name] = info.module;
|
||||
}
|
||||
@@ -313,7 +328,7 @@ class MessageQueue {
|
||||
[moduleName, methods, asyncMethods, syncHooks] = config;
|
||||
}
|
||||
|
||||
let module = {};
|
||||
const module = {};
|
||||
methods && methods.forEach((methodName, methodID) => {
|
||||
const isAsync = asyncMethods && arrayContains(asyncMethods, methodID);
|
||||
const isSyncHook = syncHooks && arrayContains(syncHooks, methodID);
|
||||
@@ -334,7 +349,7 @@ class MessageQueue {
|
||||
|
||||
_genMethod(module, method, type) {
|
||||
let fn = null;
|
||||
let self = this;
|
||||
const self = this;
|
||||
if (type === MethodTypes.remoteAsync) {
|
||||
fn = function(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -354,20 +369,20 @@ class MessageQueue {
|
||||
} else if (type === MethodTypes.syncHook) {
|
||||
return function(...args) {
|
||||
return global.nativeCallSyncHook(module, method, args);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
fn = function(...args) {
|
||||
let lastArg = args.length > 0 ? args[args.length - 1] : null;
|
||||
let secondLastArg = args.length > 1 ? args[args.length - 2] : null;
|
||||
let hasSuccCB = typeof lastArg === 'function';
|
||||
let hasErrorCB = typeof secondLastArg === 'function';
|
||||
const lastArg = args.length > 0 ? args[args.length - 1] : null;
|
||||
const secondLastArg = args.length > 1 ? args[args.length - 2] : null;
|
||||
const hasSuccCB = typeof lastArg === 'function';
|
||||
const hasErrorCB = typeof secondLastArg === 'function';
|
||||
hasErrorCB && invariant(
|
||||
hasSuccCB,
|
||||
'Cannot have a non-function arg after a function arg.'
|
||||
);
|
||||
let numCBs = hasSuccCB + hasErrorCB;
|
||||
let onSucc = hasSuccCB ? lastArg : null;
|
||||
let onFail = hasErrorCB ? secondLastArg : null;
|
||||
const numCBs = hasSuccCB + hasErrorCB;
|
||||
const onSucc = hasSuccCB ? lastArg : null;
|
||||
const onFail = hasErrorCB ? secondLastArg : null;
|
||||
args = args.slice(0, args.length - numCBs);
|
||||
return self.__nativeCall(module, method, args, onFail, onSucc);
|
||||
};
|
||||
@@ -391,11 +406,11 @@ function arrayContains<T>(array: Array<T>, value: T): boolean {
|
||||
}
|
||||
|
||||
function createErrorFromErrorData(errorData: {message: string}): Error {
|
||||
var {
|
||||
const {
|
||||
message,
|
||||
...extraErrorInfo,
|
||||
} = errorData;
|
||||
var error = new Error(message);
|
||||
const error = new Error(message);
|
||||
error.framesToPop = 1;
|
||||
return Object.assign(error, extraErrorInfo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user