2015-02-20 04:10:52 +00:00
|
|
|
/**
|
2015-03-23 20:35:08 +00:00
|
|
|
* 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.
|
2015-02-20 04:10:52 +00:00
|
|
|
*
|
|
|
|
* @providesModule MessageQueue
|
|
|
|
*/
|
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
/*eslint no-bitwise: 0*/
|
2015-02-20 04:10:52 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
'use strict';
|
2015-04-29 18:54:26 +00:00
|
|
|
|
2015-12-11 11:49:15 +00:00
|
|
|
let Systrace = require('Systrace');
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
let ErrorUtils = require('ErrorUtils');
|
|
|
|
let JSTimersExecution = require('JSTimersExecution');
|
2016-01-21 16:07:01 +00:00
|
|
|
let Platform = require('Platform');
|
2015-03-24 00:09:14 +00:00
|
|
|
|
2016-03-02 12:27:13 +00:00
|
|
|
let invariant = require('fbjs/lib/invariant');
|
|
|
|
let keyMirror = require('fbjs/lib/keyMirror');
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
let stringifySafe = require('stringifySafe');
|
2015-03-24 00:09:14 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
let MODULE_IDS = 0;
|
|
|
|
let METHOD_IDS = 1;
|
|
|
|
let PARAMS = 2;
|
2016-01-04 10:15:19 +00:00
|
|
|
let CALL_IDS = 3;
|
2015-10-13 15:00:36 +00:00
|
|
|
let MIN_TIME_BETWEEN_FLUSHES_MS = 5;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2016-01-04 10:15:19 +00:00
|
|
|
let TRACE_TAG_REACT_APPS = 1 << 17;
|
|
|
|
|
2015-07-09 16:12:53 +00:00
|
|
|
let SPY_MODE = false;
|
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
let MethodTypes = keyMirror({
|
|
|
|
remote: null,
|
|
|
|
remoteAsync: null,
|
|
|
|
});
|
2015-02-20 04:10:52 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
var guard = (fn) => {
|
2015-05-13 17:56:09 +00:00
|
|
|
try {
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
fn();
|
|
|
|
} catch (error) {
|
|
|
|
ErrorUtils.reportFatalError(error);
|
2015-05-13 17:56:09 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
class MessageQueue {
|
|
|
|
|
2015-12-08 23:57:34 +00:00
|
|
|
constructor(remoteModules, localModules) {
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
this.RemoteModules = {};
|
|
|
|
|
2015-12-08 23:57:34 +00:00
|
|
|
this._callableModules = {};
|
2016-01-04 10:15:19 +00:00
|
|
|
this._queue = [[], [], [], 0];
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
this._moduleTable = {};
|
|
|
|
this._methodTable = {};
|
|
|
|
this._callbacks = [];
|
|
|
|
this._callbackID = 0;
|
2016-01-04 10:15:19 +00:00
|
|
|
this._callID = 0;
|
2015-10-13 15:00:36 +00:00
|
|
|
this._lastFlush = 0;
|
Add yieldy, chained async task support to InteractionManager
Summary:
Default behavior should be unchanged.
If we queue up a bunch of expensive tasks during an interaction, the default
`InteractionManager` behavior would execute them all in one synchronous loop at
the end the JS event loop via one `setImmediate` call, blocking the JS thread
the entire time.
The `setDeadline` addition in this diff enables an option to only execute tasks
until the `eventLoopRunningTime` is hit (added to MessageQueue/BatchedBridge),
allowing the queue execution to be paused if an interaction starts in between
tasks, making the app more responsive.
Additionally, if a task ends up generating a bunch of additional tasks
asynchronously, the previous implementation would execute these new tasks after
already scheduled tasks. This is often fine, but I want it to fully resolve
async tasks and all their dependencies before making progress in the rest of the
queue, so I added support for `type PromiseTask = {gen: () => Promise}` to do
just this. It works by building a stack of queues each time a `PromiseTask` is
started, and pops them off the stack once they are resolved and the queues are
processed.
I also pulled all of the actual queue logic out of `InteractionManager` and into
a new `TaskQueue` class to isolate concerns a bit.
public
Reviewed By: josephsavona
Differential Revision: D2754311
fb-gh-sync-id: bfd6d0c54e6410cb261aa1d2c5024dd91a3959e6
2015-12-24 00:10:39 +00:00
|
|
|
this._eventLoopStartTime = new Date().getTime();
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
|
|
|
|
[
|
|
|
|
'invokeCallbackAndReturnFlushedQueue',
|
|
|
|
'callFunctionReturnFlushedQueue',
|
|
|
|
'flushedQueue',
|
|
|
|
].forEach((fn) => this[fn] = this[fn].bind(this));
|
|
|
|
|
2015-10-29 01:41:49 +00:00
|
|
|
let modulesConfig = this._genModulesConfig(remoteModules);
|
|
|
|
this._genModules(modulesConfig);
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
localModules && this._genLookupTables(
|
2015-10-29 01:41:49 +00:00
|
|
|
this._genModulesConfig(localModules),this._moduleTable, this._methodTable
|
|
|
|
);
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
|
2015-08-27 18:02:42 +00:00
|
|
|
this._debugInfo = {};
|
|
|
|
this._remoteModuleTable = {};
|
|
|
|
this._remoteMethodTable = {};
|
|
|
|
this._genLookupTables(
|
2015-10-29 01:41:49 +00:00
|
|
|
modulesConfig, this._remoteModuleTable, this._remoteMethodTable
|
|
|
|
);
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
* Public APIs
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-10-13 10:22:40 +00:00
|
|
|
callFunctionReturnFlushedQueue(module, method, args) {
|
2015-06-25 16:38:54 +00:00
|
|
|
guard(() => {
|
2015-10-13 10:22:40 +00:00
|
|
|
this.__callFunction(module, method, args);
|
|
|
|
this.__callImmediates();
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
});
|
2015-09-29 10:14:14 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
return this.flushedQueue();
|
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
invokeCallbackAndReturnFlushedQueue(cbID, args) {
|
2015-10-13 10:22:40 +00:00
|
|
|
guard(() => {
|
|
|
|
this.__invokeCallback(cbID, args);
|
|
|
|
this.__callImmediates();
|
|
|
|
});
|
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
return this.flushedQueue();
|
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
flushedQueue() {
|
2015-09-29 10:14:14 +00:00
|
|
|
this.__callImmediates();
|
2015-10-13 10:22:40 +00:00
|
|
|
|
|
|
|
let queue = this._queue;
|
2016-01-04 10:15:19 +00:00
|
|
|
this._queue = [[], [], [], this._callID];
|
2015-10-13 10:22:40 +00:00
|
|
|
return queue[0].length ? queue : null;
|
2015-09-29 10:14:14 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
processModuleConfig(config, moduleID) {
|
|
|
|
const module = this._genModule(config, moduleID);
|
2016-01-18 22:27:51 +00:00
|
|
|
this._genLookup(config, moduleID, this._remoteModuleTable, this._remoteMethodTable);
|
2015-12-10 12:27:45 +00:00
|
|
|
return module;
|
|
|
|
}
|
|
|
|
|
Add yieldy, chained async task support to InteractionManager
Summary:
Default behavior should be unchanged.
If we queue up a bunch of expensive tasks during an interaction, the default
`InteractionManager` behavior would execute them all in one synchronous loop at
the end the JS event loop via one `setImmediate` call, blocking the JS thread
the entire time.
The `setDeadline` addition in this diff enables an option to only execute tasks
until the `eventLoopRunningTime` is hit (added to MessageQueue/BatchedBridge),
allowing the queue execution to be paused if an interaction starts in between
tasks, making the app more responsive.
Additionally, if a task ends up generating a bunch of additional tasks
asynchronously, the previous implementation would execute these new tasks after
already scheduled tasks. This is often fine, but I want it to fully resolve
async tasks and all their dependencies before making progress in the rest of the
queue, so I added support for `type PromiseTask = {gen: () => Promise}` to do
just this. It works by building a stack of queues each time a `PromiseTask` is
started, and pops them off the stack once they are resolved and the queues are
processed.
I also pulled all of the actual queue logic out of `InteractionManager` and into
a new `TaskQueue` class to isolate concerns a bit.
public
Reviewed By: josephsavona
Differential Revision: D2754311
fb-gh-sync-id: bfd6d0c54e6410cb261aa1d2c5024dd91a3959e6
2015-12-24 00:10:39 +00:00
|
|
|
getEventLoopRunningTime() {
|
|
|
|
return new Date().getTime() - this._eventLoopStartTime;
|
|
|
|
}
|
|
|
|
|
2015-09-29 10:14:14 +00:00
|
|
|
/**
|
|
|
|
* "Private" methods
|
|
|
|
*/
|
|
|
|
|
|
|
|
__callImmediates() {
|
2015-12-11 11:49:15 +00:00
|
|
|
Systrace.beginEvent('JSTimersExecution.callImmediates()');
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
guard(() => JSTimersExecution.callImmediates());
|
2015-12-11 11:49:15 +00:00
|
|
|
Systrace.endEvent();
|
2015-09-29 10:14:14 +00:00
|
|
|
}
|
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
__nativeCall(module, method, params, onFail, onSucc) {
|
|
|
|
if (onFail || onSucc) {
|
2015-08-27 18:02:42 +00:00
|
|
|
// eventually delete old debug info
|
|
|
|
(this._callbackID > (1 << 5)) &&
|
|
|
|
(this._debugInfo[this._callbackID >> 5] = null);
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2015-08-27 18:02:42 +00:00
|
|
|
this._debugInfo[this._callbackID >> 1] = [module, method];
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
onFail && params.push(this._callbackID);
|
|
|
|
this._callbacks[this._callbackID++] = onFail;
|
|
|
|
onSucc && params.push(this._callbackID);
|
|
|
|
this._callbacks[this._callbackID++] = onSucc;
|
2015-06-15 20:01:39 +00:00
|
|
|
}
|
2016-01-04 10:15:19 +00:00
|
|
|
|
|
|
|
global.nativeTraceBeginAsyncFlow &&
|
|
|
|
global.nativeTraceBeginAsyncFlow(TRACE_TAG_REACT_APPS, 'native', this._callID);
|
|
|
|
this._callID++;
|
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
this._queue[MODULE_IDS].push(module);
|
|
|
|
this._queue[METHOD_IDS].push(method);
|
|
|
|
this._queue[PARAMS].push(params);
|
2015-10-13 15:00:36 +00:00
|
|
|
|
|
|
|
var now = new Date().getTime();
|
|
|
|
if (global.nativeFlushQueueImmediate &&
|
|
|
|
now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS) {
|
|
|
|
global.nativeFlushQueueImmediate(this._queue);
|
2016-01-04 10:15:19 +00:00
|
|
|
this._queue = [[], [], [], this._callID];
|
2015-10-13 15:00:36 +00:00
|
|
|
this._lastFlush = now;
|
|
|
|
}
|
2015-12-30 07:36:34 +00:00
|
|
|
Systrace.counterEvent('pending_js_to_native_queue', this._queue[0].length);
|
2015-07-13 16:37:05 +00:00
|
|
|
if (__DEV__ && SPY_MODE && isFinite(module)) {
|
|
|
|
console.log('JS->N : ' + this._remoteModuleTable[module] + '.' +
|
|
|
|
this._remoteMethodTable[module][method] + '(' + JSON.stringify(params) + ')');
|
|
|
|
}
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
__callFunction(module, method, args) {
|
2015-10-13 15:00:36 +00:00
|
|
|
this._lastFlush = new Date().getTime();
|
Add yieldy, chained async task support to InteractionManager
Summary:
Default behavior should be unchanged.
If we queue up a bunch of expensive tasks during an interaction, the default
`InteractionManager` behavior would execute them all in one synchronous loop at
the end the JS event loop via one `setImmediate` call, blocking the JS thread
the entire time.
The `setDeadline` addition in this diff enables an option to only execute tasks
until the `eventLoopRunningTime` is hit (added to MessageQueue/BatchedBridge),
allowing the queue execution to be paused if an interaction starts in between
tasks, making the app more responsive.
Additionally, if a task ends up generating a bunch of additional tasks
asynchronously, the previous implementation would execute these new tasks after
already scheduled tasks. This is often fine, but I want it to fully resolve
async tasks and all their dependencies before making progress in the rest of the
queue, so I added support for `type PromiseTask = {gen: () => Promise}` to do
just this. It works by building a stack of queues each time a `PromiseTask` is
started, and pops them off the stack once they are resolved and the queues are
processed.
I also pulled all of the actual queue logic out of `InteractionManager` and into
a new `TaskQueue` class to isolate concerns a bit.
public
Reviewed By: josephsavona
Differential Revision: D2754311
fb-gh-sync-id: bfd6d0c54e6410cb261aa1d2c5024dd91a3959e6
2015-12-24 00:10:39 +00:00
|
|
|
this._eventLoopStartTime = this._lastFlush;
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
if (isFinite(module)) {
|
|
|
|
method = this._methodTable[module][method];
|
|
|
|
module = this._moduleTable[module];
|
2015-04-29 18:54:26 +00:00
|
|
|
}
|
2015-12-16 10:12:33 +00:00
|
|
|
Systrace.beginEvent(`${module}.${method}()`);
|
2015-07-09 16:12:53 +00:00
|
|
|
if (__DEV__ && SPY_MODE) {
|
|
|
|
console.log('N->JS : ' + module + '.' + method + '(' + JSON.stringify(args) + ')');
|
|
|
|
}
|
2015-12-08 23:57:34 +00:00
|
|
|
var moduleMethods = this._callableModules[module];
|
2015-12-11 07:15:38 +00:00
|
|
|
invariant(
|
|
|
|
!!moduleMethods,
|
|
|
|
'Module %s is not a registered callable module.',
|
|
|
|
module
|
|
|
|
);
|
2015-12-08 23:57:34 +00:00
|
|
|
moduleMethods[method].apply(moduleMethods, args);
|
2015-12-11 11:49:15 +00:00
|
|
|
Systrace.endEvent();
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
__invokeCallback(cbID, args) {
|
2015-10-13 15:00:36 +00:00
|
|
|
this._lastFlush = new Date().getTime();
|
Add yieldy, chained async task support to InteractionManager
Summary:
Default behavior should be unchanged.
If we queue up a bunch of expensive tasks during an interaction, the default
`InteractionManager` behavior would execute them all in one synchronous loop at
the end the JS event loop via one `setImmediate` call, blocking the JS thread
the entire time.
The `setDeadline` addition in this diff enables an option to only execute tasks
until the `eventLoopRunningTime` is hit (added to MessageQueue/BatchedBridge),
allowing the queue execution to be paused if an interaction starts in between
tasks, making the app more responsive.
Additionally, if a task ends up generating a bunch of additional tasks
asynchronously, the previous implementation would execute these new tasks after
already scheduled tasks. This is often fine, but I want it to fully resolve
async tasks and all their dependencies before making progress in the rest of the
queue, so I added support for `type PromiseTask = {gen: () => Promise}` to do
just this. It works by building a stack of queues each time a `PromiseTask` is
started, and pops them off the stack once they are resolved and the queues are
processed.
I also pulled all of the actual queue logic out of `InteractionManager` and into
a new `TaskQueue` class to isolate concerns a bit.
public
Reviewed By: josephsavona
Differential Revision: D2754311
fb-gh-sync-id: bfd6d0c54e6410cb261aa1d2c5024dd91a3959e6
2015-12-24 00:10:39 +00:00
|
|
|
this._eventLoopStartTime = this._lastFlush;
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
let callback = this._callbacks[cbID];
|
2016-01-04 10:15:19 +00:00
|
|
|
let debug = this._debugInfo[cbID >> 1];
|
|
|
|
let module = debug && this._remoteModuleTable[debug[0]];
|
|
|
|
let method = debug && this._remoteMethodTable[debug[0]][debug[1]];
|
2016-03-23 17:07:45 +00:00
|
|
|
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.`;
|
|
|
|
}
|
|
|
|
invariant(
|
|
|
|
callback,
|
|
|
|
errorMessage
|
|
|
|
);
|
|
|
|
}
|
2016-01-04 10:15:19 +00:00
|
|
|
let profileName = debug ? '<callback for ' + module + '.' + method + '>' : cbID;
|
|
|
|
if (callback && SPY_MODE && __DEV__) {
|
|
|
|
console.log('N->JS : ' + profileName + '(' + JSON.stringify(args) + ')');
|
2015-02-20 04:10:52 +00:00
|
|
|
}
|
2016-01-04 10:15:19 +00:00
|
|
|
Systrace.beginEvent(
|
|
|
|
`MessageQueue.invokeCallback(${profileName}, ${stringifySafe(args)})`);
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
this._callbacks[cbID & ~1] = null;
|
|
|
|
this._callbacks[cbID | 1] = null;
|
|
|
|
callback.apply(null, args);
|
2015-12-11 11:49:15 +00:00
|
|
|
Systrace.endEvent();
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
* Private helper methods
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-10-28 15:26:50 +00:00
|
|
|
|
2015-10-29 01:41:49 +00:00
|
|
|
/**
|
|
|
|
* Converts the old, object-based module structure to the new
|
|
|
|
* array-based structure. TODO (t8823865) Removed this
|
|
|
|
* function once Android has been updated.
|
|
|
|
*/
|
|
|
|
_genModulesConfig(modules /* array or object */) {
|
|
|
|
if (Array.isArray(modules)) {
|
|
|
|
return modules;
|
|
|
|
} else {
|
|
|
|
let moduleArray = [];
|
|
|
|
let 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];
|
|
|
|
if (moduleConfig.constants) {
|
|
|
|
module.push(moduleConfig.constants);
|
|
|
|
}
|
|
|
|
let methodsConfig = moduleConfig.methods;
|
|
|
|
if (methodsConfig) {
|
|
|
|
let methods = [];
|
|
|
|
let asyncMethods = [];
|
|
|
|
let methodNames = Object.keys(methodsConfig);
|
|
|
|
for (var j = 0, ll = methodNames.length; j < ll; j++) {
|
|
|
|
let methodName = methodNames[j];
|
|
|
|
let methodConfig = methodsConfig[methodName];
|
|
|
|
methods[methodConfig.methodID] = methodName;
|
|
|
|
if (methodConfig.type === MethodTypes.remoteAsync) {
|
|
|
|
asyncMethods.push(methodConfig.methodID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (methods.length) {
|
|
|
|
module.push(methods);
|
|
|
|
if (asyncMethods.length) {
|
|
|
|
module.push(asyncMethods);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
moduleArray[moduleConfig.moduleID] = module;
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
2015-10-29 01:41:49 +00:00
|
|
|
return moduleArray;
|
2015-02-20 04:10:52 +00:00
|
|
|
}
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2015-10-29 01:41:49 +00:00
|
|
|
_genLookupTables(modulesConfig, moduleTable, methodTable) {
|
2015-12-10 12:27:45 +00:00
|
|
|
modulesConfig.forEach((config, moduleID) => {
|
|
|
|
this._genLookup(config, moduleID, moduleTable, methodTable);
|
2015-10-29 01:41:49 +00:00
|
|
|
});
|
|
|
|
}
|
2015-12-11 11:49:15 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
_genLookup(config, moduleID, moduleTable, methodTable) {
|
|
|
|
if (!config) {
|
|
|
|
return;
|
|
|
|
}
|
2015-10-29 01:41:49 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
let moduleName, methods;
|
|
|
|
if (moduleHasConstants(config)) {
|
|
|
|
[moduleName, , methods] = config;
|
|
|
|
} else {
|
|
|
|
[moduleName, methods] = config;
|
|
|
|
}
|
2015-10-29 01:41:49 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
moduleTable[moduleID] = moduleName;
|
|
|
|
methodTable[moduleID] = Object.assign({}, methods);
|
|
|
|
}
|
2015-10-29 01:41:49 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
_genModules(remoteModules) {
|
|
|
|
remoteModules.forEach((config, moduleID) => {
|
|
|
|
this._genModule(config, moduleID);
|
2015-10-29 01:41:49 +00:00
|
|
|
});
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
_genModule(config, moduleID) {
|
|
|
|
if (!config) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let moduleName, constants, methods, asyncMethods;
|
|
|
|
if (moduleHasConstants(config)) {
|
|
|
|
[moduleName, constants, methods, asyncMethods] = config;
|
|
|
|
} else {
|
|
|
|
[moduleName, methods, asyncMethods] = config;
|
|
|
|
}
|
2015-10-29 01:41:49 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
let module = {};
|
|
|
|
methods && methods.forEach((methodName, methodID) => {
|
2015-10-29 01:41:49 +00:00
|
|
|
const methodType =
|
2015-12-10 12:27:45 +00:00
|
|
|
asyncMethods && arrayContains(asyncMethods, methodID) ?
|
2015-10-29 01:41:49 +00:00
|
|
|
MethodTypes.remoteAsync : MethodTypes.remote;
|
|
|
|
module[methodName] = this._genMethod(moduleID, methodID, methodType);
|
|
|
|
});
|
|
|
|
Object.assign(module, constants);
|
2015-12-11 11:49:15 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
if (!constants && !methods && !asyncMethods) {
|
|
|
|
module.moduleID = moduleID;
|
|
|
|
}
|
2015-12-11 11:49:15 +00:00
|
|
|
|
2015-12-10 12:27:45 +00:00
|
|
|
this.RemoteModules[moduleName] = module;
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
return module;
|
|
|
|
}
|
2015-12-11 11:49:15 +00:00
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
_genMethod(module, method, type) {
|
2015-08-11 20:18:08 +00:00
|
|
|
let fn = null;
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
let self = this;
|
|
|
|
if (type === MethodTypes.remoteAsync) {
|
2015-08-11 20:18:08 +00:00
|
|
|
fn = function(...args) {
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
return new Promise((resolve, reject) => {
|
2016-01-21 16:07:01 +00:00
|
|
|
self.__nativeCall(
|
|
|
|
module,
|
|
|
|
method,
|
|
|
|
args,
|
|
|
|
(data) => {
|
2016-02-10 15:24:38 +00:00
|
|
|
resolve(data);
|
2016-01-21 16:07:01 +00:00
|
|
|
},
|
|
|
|
(errorData) => {
|
|
|
|
var error = createErrorFromErrorData(errorData);
|
|
|
|
reject(error);
|
|
|
|
});
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
} else {
|
2015-08-11 20:18:08 +00:00
|
|
|
fn = function(...args) {
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
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';
|
|
|
|
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;
|
|
|
|
args = args.slice(0, args.length - numCBs);
|
|
|
|
return self.__nativeCall(module, method, args, onFail, onSucc);
|
|
|
|
};
|
2015-02-20 04:10:52 +00:00
|
|
|
}
|
2015-08-11 20:18:08 +00:00
|
|
|
fn.type = type;
|
|
|
|
return fn;
|
2015-02-20 04:10:52 +00:00
|
|
|
}
|
|
|
|
|
2015-12-08 23:57:34 +00:00
|
|
|
registerCallableModule(name, methods) {
|
|
|
|
this._callableModules[name] = methods;
|
|
|
|
}
|
|
|
|
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
}
|
|
|
|
|
2015-10-29 01:41:49 +00:00
|
|
|
function moduleHasConstants(moduleArray: Array<Object|Array<>>): boolean {
|
|
|
|
return !Array.isArray(moduleArray[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
function arrayContains<T>(array: Array<T>, value: T): boolean {
|
|
|
|
return array.indexOf(value) !== -1;
|
|
|
|
}
|
|
|
|
|
2015-10-22 12:51:21 +00:00
|
|
|
function createErrorFromErrorData(errorData: {message: string}): Error {
|
[ReactNative] Refactor BatchedBridge and MessageQueue
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
2015-06-17 14:51:48 +00:00
|
|
|
var {
|
|
|
|
message,
|
|
|
|
...extraErrorInfo,
|
|
|
|
} = errorData;
|
|
|
|
var error = new Error(message);
|
|
|
|
error.framesToPop = 1;
|
|
|
|
return Object.assign(error, extraErrorInfo);
|
|
|
|
}
|
|
|
|
|
2015-02-20 04:10:52 +00:00
|
|
|
module.exports = MessageQueue;
|