From a4362262661d38a23034d8336b099899ef5d1b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 30 Jul 2020 18:41:11 +0200 Subject: [PATCH] scripting: Switch to standard async/await pattern The original scripting framework was based on SpiderMonkey's pre-standard generators, and was simply translated to the corresponding standard syntax when updating it to work with recent JS versions. We can do even better by using the standard async/await pattern instead of generators/yield. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1396 --- js/perf/core.js | 32 +++++++++++++++------------- js/perf/hwtest.js | 52 ++++++++++++++++++++++++---------------------- js/ui/scripting.js | 21 +++++++------------ 3 files changed, 52 insertions(+), 53 deletions(-) diff --git a/js/perf/core.js b/js/perf/core.js index deebe1939..f3f496b03 100644 --- a/js/perf/core.js +++ b/js/perf/core.js @@ -70,7 +70,8 @@ let WINDOW_CONFIGS = [ { width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' }, ]; -function *run() { +async function run() { + /* eslint-disable no-await-in-loop */ Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview"); Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview"); @@ -84,7 +85,7 @@ function *run() { Scripting.scriptEvent('overviewShowDone'); }); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); for (let i = 0; i < 2 * WINDOW_CONFIGS.length; i++) { // We go to the overview twice for each configuration; the first time @@ -92,49 +93,50 @@ function *run() { // a clean set of numbers. if ((i % 2) == 0) { let config = WINDOW_CONFIGS[i / 2]; - yield Scripting.destroyTestWindows(); + await Scripting.destroyTestWindows(); for (let k = 0; k < config.count; k++) { - yield Scripting.createTestWindow({ width: config.width, + await Scripting.createTestWindow({ width: config.width, height: config.height, alpha: config.alpha, maximized: config.maximized }); } - yield Scripting.waitTestWindows(); - yield Scripting.sleep(1000); - yield Scripting.waitLeisure(); + await Scripting.waitTestWindows(); + await Scripting.sleep(1000); + await Scripting.waitLeisure(); } Scripting.scriptEvent('overviewShowStart'); Main.overview.show(); - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); Main.overview.hide(); - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); System.gc(); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); Scripting.collectStatistics(); Scripting.scriptEvent('afterShowHide'); } - yield Scripting.destroyTestWindows(); - yield Scripting.sleep(1000); + await Scripting.destroyTestWindows(); + await Scripting.sleep(1000); Main.overview.show(); - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); for (let i = 0; i < 2; i++) { Scripting.scriptEvent('applicationsShowStart'); // eslint-disable-next-line require-atomic-updates Main.overview.dash.showAppsButton.checked = true; - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); Scripting.scriptEvent('applicationsShowDone'); // eslint-disable-next-line require-atomic-updates Main.overview.dash.showAppsButton.checked = false; - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); } + /* eslint-enable no-await-in-loop */ } let showingOverview = false; diff --git a/js/perf/hwtest.js b/js/perf/hwtest.js index 17b7cdb71..0f396acd3 100644 --- a/js/perf/hwtest.js +++ b/js/perf/hwtest.js @@ -94,7 +94,8 @@ function extractBootTimestamp() { return result; } -function *run() { +async function run() { + /* eslint-disable no-await-in-loop */ Scripting.defineScriptEvent("desktopShown", "Finished initial animation"); Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview"); Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); @@ -110,7 +111,7 @@ function *run() { Scripting.defineScriptEvent("geditLaunch", "gedit application launch"); Scripting.defineScriptEvent("geditFirstFrame", "first frame of gedit window drawn"); - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); Scripting.scriptEvent('desktopShown'); let interfaceSettings = new Gio.Settings({ @@ -120,22 +121,22 @@ function *run() { Scripting.scriptEvent('overviewShowStart'); Main.overview.show(); - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); Scripting.scriptEvent('overviewShowDone'); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); Scripting.scriptEvent('applicationsShowStart'); // eslint-disable-next-line require-atomic-updates Main.overview.dash.showAppsButton.checked = true; - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); Scripting.scriptEvent('applicationsShowDone'); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); Main.overview.hide(); - yield Scripting.waitLeisure(); + await Scripting.waitLeisure(); // --------------------- // // Tests of redraw speed // @@ -145,46 +146,46 @@ function *run() { global.frame_finish_timestamp = true; for (let k = 0; k < 5; k++) - yield Scripting.createTestWindow({ maximized: true }); - yield Scripting.waitTestWindows(); + await Scripting.createTestWindow({ maximized: true }); + await Scripting.waitTestWindows(); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); Scripting.scriptEvent('mainViewDrawStart'); - yield waitAndDraw(1000); + await waitAndDraw(1000); Scripting.scriptEvent('mainViewDrawDone'); Main.overview.show(); Scripting.waitLeisure(); - yield Scripting.sleep(1500); + await Scripting.sleep(1500); Scripting.scriptEvent('overviewDrawStart'); - yield waitAndDraw(1000); + await waitAndDraw(1000); Scripting.scriptEvent('overviewDrawDone'); - yield Scripting.destroyTestWindows(); + await Scripting.destroyTestWindows(); Main.overview.hide(); - yield Scripting.createTestWindow({ maximized: true, + await Scripting.createTestWindow({ maximized: true, redraws: true }); - yield Scripting.waitTestWindows(); + await Scripting.waitTestWindows(); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); Scripting.scriptEvent('redrawTestStart'); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); Scripting.scriptEvent('redrawTestDone'); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); Scripting.scriptEvent('collectTimings'); - yield Scripting.destroyTestWindows(); + await Scripting.destroyTestWindows(); global.frame_timestamps = false; global.frame_finish_timestamp = false; - yield Scripting.sleep(1000); + await Scripting.sleep(1000); let appSys = Shell.AppSystem.get_default(); let app = appSys.lookup_app('org.gnome.gedit.desktop'); @@ -197,21 +198,22 @@ function *run() { throw new Error('gedit was already running'); while (windows.length == 0) { - yield waitSignal(global.display, 'window-created'); + await waitSignal(global.display, 'window-created'); windows = app.get_windows(); } let actor = windows[0].get_compositor_private(); - yield waitSignal(actor, 'first-frame'); + await waitSignal(actor, 'first-frame'); Scripting.scriptEvent('geditFirstFrame'); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); windows[0].delete(global.get_current_time()); - yield Scripting.sleep(1000); + await Scripting.sleep(1000); interfaceSettings.set_boolean('enable-animations', true); + /* eslint-enable no-await-in-loop */ } let overviewShowStart; diff --git a/js/ui/scripting.js b/js/ui/scripting.js index b93de7196..e4b29a4cc 100644 --- a/js/ui/scripting.js +++ b/js/ui/scripting.js @@ -21,16 +21,13 @@ const { loadInterfaceXML } = imports.misc.fileUtils; // When scripting an automated test we want to make a series of calls // in a linear fashion, but we also want to be able to let the main // loop run so actions can finish. For this reason we write the script -// as a generator function that yields when it want to let the main +// as an async function that uses await when it wants to let the main // loop run. // -// yield Scripting.sleep(1000); +// await Scripting.sleep(1000); // main.overview.show(); -// yield Scripting.waitLeisure(); +// await Scripting.waitLeisure(); // -// While it isn't important to the person writing the script, the actual -// yielded result is a function that the caller uses to provide the -// callback for resuming the script. /** * sleep: @@ -285,13 +282,11 @@ function _collect(scriptModule, outputFile) { } async function _runPerfScript(scriptModule, outputFile) { - for (let step of scriptModule.run()) { - try { - await step; // eslint-disable-line no-await-in-loop - } catch (err) { - log(`Script failed: ${err}\n${err.stack}`); - Meta.exit(Meta.ExitCode.ERROR); - } + try { + await scriptModule.run(); + } catch (err) { + log(`Script failed: ${err}\n${err.stack}`); + Meta.exit(Meta.ExitCode.ERROR); } try {