-
Notifications
You must be signed in to change notification settings - Fork 24.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RN: Feature Flag to Disable
InteractionManager
Summary: Creates a feature flag to evalute the impact of disabling `InteractionManager` and replacing its scheduling behavior with `setImmediate`. Changelog: [Internal] Differential Revision: D65577455
- Loading branch information
1 parent
e6090df
commit 3a7303a
Showing
4 changed files
with
198 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
176 changes: 176 additions & 0 deletions
176
packages/react-native/Libraries/Interaction/InteractionManagerStub.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow strict | ||
* @format | ||
*/ | ||
|
||
import type {EventSubscription} from '../vendor/emitter/EventEmitter'; | ||
|
||
const invariant = require('invariant'); | ||
|
||
export type Handle = number; | ||
|
||
type Task = | ||
| { | ||
name: string, | ||
run: () => void, | ||
} | ||
| { | ||
name: string, | ||
gen: () => Promise<void>, | ||
} | ||
| (() => void); | ||
|
||
/** | ||
* InteractionManager allows long-running work to be scheduled after any | ||
* interactions/animations have completed. In particular, this allows JavaScript | ||
* animations to run smoothly. | ||
* | ||
* Applications can schedule tasks to run after interactions with the following: | ||
* | ||
* ``` | ||
* InteractionManager.runAfterInteractions(() => { | ||
* // ...long-running synchronous task... | ||
* }); | ||
* ``` | ||
* | ||
* Compare this to other scheduling alternatives: | ||
* | ||
* - requestAnimationFrame(): for code that animates a view over time. | ||
* - setImmediate/setTimeout(): run code later, note this may delay animations. | ||
* - runAfterInteractions(): run code later, without delaying active animations. | ||
* | ||
* The touch handling system considers one or more active touches to be an | ||
* 'interaction' and will delay `runAfterInteractions()` callbacks until all | ||
* touches have ended or been cancelled. | ||
* | ||
* InteractionManager also allows applications to register animations by | ||
* creating an interaction 'handle' on animation start, and clearing it upon | ||
* completion: | ||
* | ||
* ``` | ||
* var handle = InteractionManager.createInteractionHandle(); | ||
* // run animation... (`runAfterInteractions` tasks are queued) | ||
* // later, on animation completion: | ||
* InteractionManager.clearInteractionHandle(handle); | ||
* // queued tasks run if all handles were cleared | ||
* ``` | ||
* | ||
* `runAfterInteractions` takes either a plain callback function, or a | ||
* `PromiseTask` object with a `gen` method that returns a `Promise`. If a | ||
* `PromiseTask` is supplied, then it is fully resolved (including asynchronous | ||
* dependencies that also schedule more tasks via `runAfterInteractions`) before | ||
* starting on the next task that might have been queued up synchronously | ||
* earlier. | ||
* | ||
* By default, queued tasks are executed together in a loop in one | ||
* `setImmediate` batch. If `setDeadline` is called with a positive number, then | ||
* tasks will only be executed until the deadline (in terms of js event loop run | ||
* time) approaches, at which point execution will yield via setTimeout, | ||
* allowing events such as touches to start interactions and block queued tasks | ||
* from executing, making apps more responsive. | ||
* | ||
* @deprecated | ||
*/ | ||
const InteractionManagerStub = { | ||
Events: { | ||
interactionStart: 'interactionStart', | ||
interactionComplete: 'interactionComplete', | ||
}, | ||
|
||
/** | ||
* Schedule a function to run after all interactions have completed. Returns a cancellable | ||
* "promise". | ||
* | ||
* @deprecated | ||
*/ | ||
runAfterInteractions(task: ?Task): { | ||
then: <U>( | ||
onFulfill?: ?(void) => ?(Promise<U> | U), | ||
onReject?: ?(error: mixed) => ?(Promise<U> | U), | ||
) => Promise<U>, | ||
cancel: () => void, | ||
... | ||
} { | ||
let immediateID: ?$FlowIssue; | ||
const promise = new Promise((resolve, reject) => { | ||
immediateID = setImmediate(() => { | ||
if (typeof task === 'object' && task !== null) { | ||
if (typeof task.gen === 'function') { | ||
task.gen().then(resolve, reject); | ||
} else if (typeof task.run === 'function') { | ||
try { | ||
task.run(); | ||
resolve(); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
} else { | ||
reject(new TypeError(`Task "${task.name}" missing gen or run.`)); | ||
} | ||
} else if (typeof task === 'function') { | ||
try { | ||
task(); | ||
resolve(); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
} else { | ||
reject(new TypeError('Invalid task of type: ' + typeof task)); | ||
} | ||
}); | ||
}); | ||
|
||
return { | ||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters | ||
then: promise.then.bind(promise), | ||
cancel() { | ||
clearImmediate(immediateID); | ||
}, | ||
}; | ||
}, | ||
|
||
/** | ||
* Notify manager that an interaction has started. | ||
* | ||
* @deprecated | ||
*/ | ||
createInteractionHandle(): Handle { | ||
return -1; | ||
}, | ||
|
||
/** | ||
* Notify manager that an interaction has completed. | ||
* | ||
* @deprecated | ||
*/ | ||
clearInteractionHandle(handle: Handle) { | ||
invariant(!!handle, 'InteractionManager: Must provide a handle to clear.'); | ||
}, | ||
|
||
/** | ||
* @deprecated | ||
*/ | ||
addListener(): EventSubscription { | ||
return { | ||
remove() {}, | ||
}; | ||
}, | ||
|
||
/** | ||
* A positive number will use setTimeout to schedule any tasks after the | ||
* eventLoopRunningTime hits the deadline value, otherwise all tasks will be | ||
* executed in one setImmediate batch (default). | ||
* | ||
* @deprecated | ||
*/ | ||
setDeadline(deadline: number) { | ||
// Do nothing. | ||
}, | ||
}; | ||
|
||
module.exports = InteractionManagerStub; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters