From 34fcb412977263ba2824dc8e8941a9aa910d70e7 Mon Sep 17 00:00:00 2001 From: Tom Duncalf Date: Thu, 10 Feb 2022 11:51:20 +0000 Subject: [PATCH] Flush the React Native UI task queue whenever we call from C++ to JS by calling jsCallInvoker->invokeAsync. React Native has its own JS "microtask" queue, implemented in https://github.com/facebook/react-native/blob/main/Libraries/Core/Timers/JSTimers.js. Any asynchronous work, e.g. `setTimeout` or `setImmediate`, is added to this queue, and the queue is flushed whenever a message is sent from React Native's native core to JS: https://github.com/facebook/react-native/blob/main/Libraries/BatchedBridge/MessageQueue.js#L108. However, our native to JS messages are not being passed via this abstraction - instead, we hook directly into the JS engine. This means that React Native is not aware that when Realm has done some async work, we might need to update the UI (and therefore flush the task queue), and this can result in Realm-related UI updates not showing until some action is taken which causes React Native to send a message from the core to JS (e.g. touching the screen), which flushes this task queue, resolving pending promises and updating the UI. This commit calls the React Native jsCallInvoker->invokeAsync method, which internally flushes the task queue. As this method is async, we wait for any current pending invocation to complete before triggering another one (using a flag, so the call is "debounced") --- .../react-native/package-lock.json | 204 +++++++++++++----- react-native/ios/RealmReact/RealmReact.mm | 24 ++- src/jsc/jsc_class.hpp | 5 +- src/jsc/jsc_function.hpp | 9 + src/jsc/jsc_init.cpp | 8 +- src/jsc/jsc_init.h | 3 +- src/jsc/rpc.cpp | 2 +- 7 files changed, 193 insertions(+), 62 deletions(-) diff --git a/integration-tests/environments/react-native/package-lock.json b/integration-tests/environments/react-native/package-lock.json index 1cc11eb5eaa..4c009262f65 100644 --- a/integration-tests/environments/react-native/package-lock.json +++ b/integration-tests/environments/react-native/package-lock.json @@ -11,7 +11,7 @@ "@react-native-community/art": "^1.2.0", "mocha": "^8.3.2", "mocha-junit-reporter": "^2.0.0", - "mocha-remote-client": "^1.4.3", + "mocha-remote-client": "^1.5.0", "path-browserify": "^1.0.1", "react": "17.0.2", "react-native": "0.66.2", @@ -24,7 +24,7 @@ "concurrently": "^6.0.2", "metro-react-native-babel-preset": "^0.66.2", "mocha-github-actions-reporter": "^0.2.3", - "mocha-remote-cli": "^1.4.3", + "mocha-remote-cli": "^1.5.0", "pod-install": "^0.1.23", "puppeteer": "^9.0.0" } @@ -3238,9 +3238,9 @@ } }, "node_modules/fast-equals": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.3.tgz", - "integrity": "sha512-0EMw4TTUxsMDpDkCg0rXor2gsg+npVrMIHbEhvD0HZyIhUX6AktC/yasm+qKwfyswd06Qy95ZKk8p2crTo0iPA==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz", + "integrity": "sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==" }, "node_modules/fb-watchman": { "version": "2.0.1", @@ -3332,9 +3332,9 @@ } }, "node_modules/flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, "node_modules/flow-parser": { @@ -5447,14 +5447,14 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/mocha-remote-cli": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-cli/-/mocha-remote-cli-1.4.3.tgz", - "integrity": "sha512-shlGi8M0ZHOdNgPOwsoxQ4v1bnlFFqAPLgmfR3EoEPmCQ3vln7EBI+7NHa+I+AHs5B6tkrk4Ym3BCcFHNaEccw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-cli/-/mocha-remote-cli-1.5.0.tgz", + "integrity": "sha512-knim6jsUpzDdjJOTI/76TawFAa7PXlM02BjK/vzWcQvq/Bnrxx2ySvSZIEpXlmlC4mZ96Ntw7hB1tPH2H063RQ==", "dev": true, "dependencies": { "chalk": "^4.1.0", "debug": "^4.3.1", - "mocha-remote-server": "^1.4.3", + "mocha-remote-server": "^1.5.0", "yargs": "^16.2.0" }, "bin": { @@ -5465,39 +5465,103 @@ } }, "node_modules/mocha-remote-client": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-client/-/mocha-remote-client-1.4.3.tgz", - "integrity": "sha512-736U8wl6vJu/HS8TkbsaXtpWIwwa8WOQuQZB/4DrkW6ovmi5jQEPf8MNTkF0qHriXvsn1djytQmVyEkV1AoKSQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-client/-/mocha-remote-client-1.5.0.tgz", + "integrity": "sha512-BmywhIZDJkErLRoa5D2/QpMCyq5iSsLyXN+2CCPo5sY4z+DMWyu+YCuZIae+z+7AupJYMm3U6xw8o969ea4jZg==", "dependencies": { "debug": "^4.3.1", - "fast-equals": "^2.0.3", - "mocha-remote-common": "^1.4.3", - "ws": "^7.4.4" + "fast-equals": "^2.0.4", + "mocha-remote-common": "^1.5.0", + "ws": "^8.4.2" + } + }, + "node_modules/mocha-remote-client/node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/mocha-remote-common": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-common/-/mocha-remote-common-1.4.3.tgz", - "integrity": "sha512-4+XSpIl2NCiBgpBesFByRiglkrlbT6UbdWzssHelUXRD2hR9VbPjyQBjhab4+H98/zLoK5BBEagPGMAfKqk+7Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-common/-/mocha-remote-common-1.5.0.tgz", + "integrity": "sha512-d/E0Vnr8xw02gjPGqMwlppl+WdBLtYLgGndbDQMYyqFBP1eNd9kqSDNZn58cUp3pCuEThB5eOZPK92FS1OSUWA==", "dependencies": { "debug": "^4.3.1" } }, "node_modules/mocha-remote-server": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-server/-/mocha-remote-server-1.4.3.tgz", - "integrity": "sha512-me6CvUOmVENEN+We8Nn3kO4qbqrmY+fHLEMe5tHtC9oSE9lYeAfWzQDtJTV7HyoU1iIVRIM590CdeeHscrEx7w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-server/-/mocha-remote-server-1.5.0.tgz", + "integrity": "sha512-xZRkhhHHYJDLWOy9LQDWT2DONnkQFRWwDTCxrDiEtv3YoE/U5ZmYo5xseqWL9fpuvx/IelzEMkoz/kc/XTPePA==", "dev": true, "dependencies": { - "debug": "^4.3.1", - "flatted": "^3.1.1", - "mocha-remote-common": "^1.4.3", - "ws": "^7.4.4" + "debug": "^4.3.3", + "flatted": "^3.2.5", + "mocha-remote-common": "^1.5.0", + "ws": "^8.4.2" }, "peerDependencies": { "mocha": "^8" } }, + "node_modules/mocha-remote-server/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha-remote-server/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha-remote-server/node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/ms": { "version": "2.1.3", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" @@ -10557,9 +10621,9 @@ } }, "fast-equals": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.3.tgz", - "integrity": "sha512-0EMw4TTUxsMDpDkCg0rXor2gsg+npVrMIHbEhvD0HZyIhUX6AktC/yasm+qKwfyswd06Qy95ZKk8p2crTo0iPA==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz", + "integrity": "sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==" }, "fb-watchman": { "version": "2.0.1", @@ -10635,9 +10699,9 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" }, "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, "flow-parser": { @@ -12296,46 +12360,78 @@ } }, "mocha-remote-cli": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-cli/-/mocha-remote-cli-1.4.3.tgz", - "integrity": "sha512-shlGi8M0ZHOdNgPOwsoxQ4v1bnlFFqAPLgmfR3EoEPmCQ3vln7EBI+7NHa+I+AHs5B6tkrk4Ym3BCcFHNaEccw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-cli/-/mocha-remote-cli-1.5.0.tgz", + "integrity": "sha512-knim6jsUpzDdjJOTI/76TawFAa7PXlM02BjK/vzWcQvq/Bnrxx2ySvSZIEpXlmlC4mZ96Ntw7hB1tPH2H063RQ==", "dev": true, "requires": { "chalk": "^4.1.0", "debug": "^4.3.1", - "mocha-remote-server": "^1.4.3", + "mocha-remote-server": "^1.5.0", "yargs": "^16.2.0" } }, "mocha-remote-client": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-client/-/mocha-remote-client-1.4.3.tgz", - "integrity": "sha512-736U8wl6vJu/HS8TkbsaXtpWIwwa8WOQuQZB/4DrkW6ovmi5jQEPf8MNTkF0qHriXvsn1djytQmVyEkV1AoKSQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-client/-/mocha-remote-client-1.5.0.tgz", + "integrity": "sha512-BmywhIZDJkErLRoa5D2/QpMCyq5iSsLyXN+2CCPo5sY4z+DMWyu+YCuZIae+z+7AupJYMm3U6xw8o969ea4jZg==", "requires": { "debug": "^4.3.1", - "fast-equals": "^2.0.3", - "mocha-remote-common": "^1.4.3", - "ws": "^7.4.4" + "fast-equals": "^2.0.4", + "mocha-remote-common": "^1.5.0", + "ws": "^8.4.2" + }, + "dependencies": { + "ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "requires": {} + } } }, "mocha-remote-common": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-common/-/mocha-remote-common-1.4.3.tgz", - "integrity": "sha512-4+XSpIl2NCiBgpBesFByRiglkrlbT6UbdWzssHelUXRD2hR9VbPjyQBjhab4+H98/zLoK5BBEagPGMAfKqk+7Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-common/-/mocha-remote-common-1.5.0.tgz", + "integrity": "sha512-d/E0Vnr8xw02gjPGqMwlppl+WdBLtYLgGndbDQMYyqFBP1eNd9kqSDNZn58cUp3pCuEThB5eOZPK92FS1OSUWA==", "requires": { "debug": "^4.3.1" } }, "mocha-remote-server": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/mocha-remote-server/-/mocha-remote-server-1.4.3.tgz", - "integrity": "sha512-me6CvUOmVENEN+We8Nn3kO4qbqrmY+fHLEMe5tHtC9oSE9lYeAfWzQDtJTV7HyoU1iIVRIM590CdeeHscrEx7w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mocha-remote-server/-/mocha-remote-server-1.5.0.tgz", + "integrity": "sha512-xZRkhhHHYJDLWOy9LQDWT2DONnkQFRWwDTCxrDiEtv3YoE/U5ZmYo5xseqWL9fpuvx/IelzEMkoz/kc/XTPePA==", "dev": true, "requires": { - "debug": "^4.3.1", - "flatted": "^3.1.1", - "mocha-remote-common": "^1.4.3", - "ws": "^7.4.4" + "debug": "^4.3.3", + "flatted": "^3.2.5", + "mocha-remote-common": "^1.5.0", + "ws": "^8.4.2" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "requires": {} + } } }, "ms": { diff --git a/react-native/ios/RealmReact/RealmReact.mm b/react-native/ios/RealmReact/RealmReact.mm index 4bcc1dee973..4d5a6f6fc88 100644 --- a/react-native/ios/RealmReact/RealmReact.mm +++ b/react-native/ios/RealmReact/RealmReact.mm @@ -22,6 +22,7 @@ #import #import +#include #import #import @@ -51,6 +52,7 @@ - (JSContext *)context; @interface RCTBridge (Realm_RCTCxxBridge) - (JSGlobalContextRef)jsContextRef; - (void *)runtime; +- (std::shared_ptr)jsCallInvoker; @end extern "C" JSGlobalContextRef RealmReactGetJSGlobalContextForExecutor(id executor, bool create) { @@ -83,6 +85,7 @@ @interface RealmReact () @implementation RealmReact { NSMutableDictionary *_eventHandlers; + bool waitingForFlush; #if DEBUG GCDWebServer *_webServer; @@ -108,6 +111,7 @@ - (instancetype)init { self = [super init]; if (self) { _eventHandlers = [[NSMutableDictionary alloc] init]; + waitingForFlush = false; } return self; } @@ -274,7 +278,7 @@ - (void)dealloc { typedef JSGlobalContextRef (^JSContextRefExtractor)(); -void _initializeOnJSThread(JSContextRefExtractor jsContextExtractor) { +void _initializeOnJSThread(JSContextRefExtractor jsContextExtractor, std::function flushUiQueue) { // Make sure the previous JS thread is completely finished before continuing. static __weak NSThread *s_currentJSThread; while (s_currentJSThread && !s_currentJSThread.finished) { @@ -282,7 +286,7 @@ void _initializeOnJSThread(JSContextRefExtractor jsContextExtractor) { } s_currentJSThread = [NSThread currentThread]; - RJSInitializeInContext(jsContextExtractor()); + RJSInitializeInContext(jsContextExtractor(), flushUiQueue); } - (void)setBridge:(RCTBridge *)bridge { @@ -310,7 +314,7 @@ - (void)setBridge:(RCTBridge *)bridge { if (!self || !bridge) { return; } - + _initializeOnJSThread(^{ // RN < 0.58 has a private method that returns the js context if ([bridge respondsToSelector:@selector(jsContextRef)]) { @@ -325,6 +329,18 @@ - (void)setBridge:(RCTBridge *)bridge { JSGlobalContextRef ctx_; }; return static_cast(bridge.runtime)->ctx_; + }, ^{ + // This calls into JSIExecutor::flush() inside React Native to flush any pending UI + // updates after we have called into JS from C++ + // + // TODO add a bit more info + if (!waitingForFlush) { + waitingForFlush = true; + [bridge jsCallInvoker]->invokeAsync([&](){ + printf("flush\n"); + waitingForFlush = false; + }); + } }); } queue:RCTJSThread]; } else { // React Native 0.44 and older @@ -341,6 +357,8 @@ - (void)setBridge:(RCTBridge *)bridge { _initializeOnJSThread(^ { return RealmReactGetJSGlobalContextForExecutor(executor, true); + }, [&]() { + // jsCallInvoker does not exist on older RN }); }]; } diff --git a/src/jsc/jsc_class.hpp b/src/jsc/jsc_class.hpp index 984bf554548..8d9d6337946 100644 --- a/src/jsc/jsc_class.hpp +++ b/src/jsc/jsc_class.hpp @@ -19,6 +19,7 @@ #pragma once #include "jsc_types.hpp" +#include "jsc_function.hpp" #include "js_class.hpp" #include "js_util.hpp" @@ -41,7 +42,7 @@ extern js::Protected FunctionPrototype; extern js::Protected RealmObjectClassConstructor; extern js::Protected RealmObjectClassConstructorPrototype; -static inline void jsc_class_init(JSContextRef ctx, JSObjectRef globalObject) +static inline void jsc_class_init(JSContextRef ctx, JSObjectRef globalObject, std::function flushUiQueue) { // handle ReactNative app refresh by reseting the cached constructor values if (RealmObjectClassConstructor) { @@ -63,6 +64,8 @@ static inline void jsc_class_init(JSContextRef ctx, JSObjectRef globalObject) JSObjectRef globalFunction = jsc::Value::to_object(ctx, value); value = jsc::Object::get_property(ctx, globalFunction, "prototype"); FunctionPrototype = js::Protected(ctx, Value::to_object(ctx, value)); + + js::flush_ui_queue = flushUiQueue; } template diff --git a/src/jsc/jsc_function.hpp b/src/jsc/jsc_function.hpp index d2f99d5c1e0..d920009eac0 100644 --- a/src/jsc/jsc_function.hpp +++ b/src/jsc/jsc_function.hpp @@ -23,12 +23,18 @@ namespace realm { namespace js { +// TODO +extern std::function flush_ui_queue; + template <> inline JSValueRef jsc::Function::call(JSContextRef ctx, const JSObjectRef& function, const JSObjectRef& this_object, size_t argc, const JSValueRef arguments[]) { JSValueRef exception = nullptr; JSValueRef result = JSObjectCallAsFunction(ctx, function, this_object, argc, arguments, &exception); + + flush_ui_queue(); + if (exception) { throw jsc::Exception(ctx, exception); } @@ -48,6 +54,9 @@ inline JSObjectRef jsc::Function::construct(JSContextRef ctx, const JSObjectRef& { JSValueRef exception = nullptr; JSObjectRef result = JSObjectCallAsConstructor(ctx, function, argc, arguments, &exception); + + flush_ui_queue(); + if (exception) { throw jsc::Exception(ctx, exception); } diff --git a/src/jsc/jsc_init.cpp b/src/jsc/jsc_init.cpp index ba290616b7e..63d3070f982 100644 --- a/src/jsc/jsc_init.cpp +++ b/src/jsc/jsc_init.cpp @@ -31,6 +31,10 @@ js::Protected FunctionPrototype; js::Protected RealmObjectClassConstructor; js::Protected RealmObjectClassConstructorPrototype; } // namespace jsc + +namespace js { +std::function flush_ui_queue; +} // namespace js } // namespace realm extern "C" { @@ -43,13 +47,13 @@ JSObjectRef RJSConstructorCreate(JSContextRef ctx) return js::RealmClass::create_constructor(ctx); } -void RJSInitializeInContext(JSContextRef ctx) +void RJSInitializeInContext(JSContextRef ctx, std::function flush_ui_queue) { static const jsc::String realm_string = "Realm"; JSObjectRef global_object = JSContextGetGlobalObject(ctx); - jsc_class_init(ctx, global_object); + jsc_class_init(ctx, global_object, flush_ui_queue); JSObjectRef realm_constructor = RJSConstructorCreate(ctx); diff --git a/src/jsc/jsc_init.h b/src/jsc/jsc_init.h index 8521abef9dd..8d88e4d4624 100644 --- a/src/jsc/jsc_init.h +++ b/src/jsc/jsc_init.h @@ -19,13 +19,14 @@ #pragma once #include +#include #ifdef __cplusplus extern "C" { #endif JSObjectRef RJSConstructorCreate(JSContextRef ctx); -void RJSInitializeInContext(JSContextRef ctx); +void RJSInitializeInContext(JSContextRef ctx, std::function send_dummy_event); void RJSInvalidateCaches(); #ifdef __cplusplus diff --git a/src/jsc/rpc.cpp b/src/jsc/rpc.cpp index 9940ea3011c..1b963a5d896 100644 --- a/src/jsc/rpc.cpp +++ b/src/jsc/rpc.cpp @@ -387,7 +387,7 @@ RPCServerImpl::RPCServerImpl() } m_requests["/create_session"] = [this](const json dict) { - RJSInitializeInContext(m_context); + RJSInitializeInContext(m_context, []() {}); jsc::String realm_string = "Realm"; JSObjectRef realm_constructor =