From 078d7cfdd3773c5a7c0b37509cbbe1339b94d48e Mon Sep 17 00:00:00 2001 From: Julien Loir <6706489+Namaneo@users.noreply.github.com> Date: Mon, 11 Sep 2023 02:14:53 +0200 Subject: [PATCH] Another try of Core in Parallel --- ui/sources/services/core.js | 37 +++++++++++++++++++++++++-------- ui/sources/services/interop.js | 18 +++++++++------- ui/sources/services/parallel.js | 10 +++++++++ 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/ui/sources/services/core.js b/ui/sources/services/core.js index 4002ae8..0e13de7 100644 --- a/ui/sources/services/core.js +++ b/ui/sources/services/core.js @@ -1,6 +1,8 @@ import { Cheat } from '../entities/cheat'; import { Settings } from '../entities/settings'; import { Variable } from '../entities/variable'; +import { Video } from '../entities/video'; +import { Audio } from '../entities/audio'; import Files from './files'; import Parallel from './parallel'; import AudioPlayer from './audio'; @@ -36,6 +38,9 @@ export default class Core { /** @type {Parallel[]} */ #threads = []; + /** @type {Graphics} */ + #graphics = null; + /** * @param {string} name */ @@ -54,7 +59,7 @@ export default class Core { await Core.#running; Core.#running = new Promise(resolve => Core.#stop = resolve); - const graphics = new Graphics(canvas); + this.#graphics = new Graphics(canvas); const origin = location.origin + location.pathname.substring(0, location.pathname.lastIndexOf('/')); const config = { core: this.#name, system, rom, origin, memory: Core.#memory }; @@ -65,15 +70,9 @@ export default class Core { case 'thread': const thread = new Parallel(Interop, false, handler); const core = await thread.create(this.#name, script); - await core.init(await Files.clone(), { ...config, ...message.data }); + await core.init(Parallel.instrument(this), await Files.clone(), { ...config, ...message.data }); this.#threads.push(thread); break; - case 'video': - graphics.draw(message.data.view, message.data.video); - break; - case 'audio': - AudioPlayer.queue(message.data.view, message.data.sample_rate); - break; case 'variables': on_variables(message.data.variables); break; @@ -82,7 +81,7 @@ export default class Core { this.#parallel = new Parallel(Interop, false, handler); this.#interop = await this.#parallel.create(this.#name, script); - await this.#interop.init(await Files.clone(), config); + await this.#interop.init(Parallel.instrument(this), await Files.clone(), config); } /** @@ -119,6 +118,26 @@ export default class Core { Core.#stop(); } + /** + * @param {Video} video + * @returns {void} + */ + draw(video) { + const video_view = video.format == 1 + ? new Uint8Array(Core.#memory.buffer, video.data, video.pitch * video.height) + : new Uint16Array(Core.#memory.buffer, video.data, (video.pitch * video.height) / 2); + this.#graphics.draw(video_view, video); + } + + /** + * @param {Audio} audio + * @returns + */ + play(audio) { + const audio_view = new Float32Array(Core.#memory.buffer, audio.data, audio.frames * 2); + AudioPlayer.queue(audio_view.slice(), audio.rate); + } + /** @param {Settings} settings @returns {Promise} */ async settings(settings) { await this.#interop?.variables(settings.variables); } diff --git a/ui/sources/services/interop.js b/ui/sources/services/interop.js index 6793a19..4dbf9f1 100644 --- a/ui/sources/services/interop.js +++ b/ui/sources/services/interop.js @@ -4,6 +4,7 @@ import { Video } from '../entities/video'; import { Audio } from '../entities/audio'; import Parallel from './parallel'; import Filesystem from './filesystem'; +import Core from './core'; import WASI from './wasi'; class InteropConfig { @@ -36,6 +37,9 @@ export default class Interop { /** @type {TextDecoder} */ static #decoder = new TextDecoder(); + /** @type {Core} */ + #core = null; + /** @type {WASI} */ #wasi = null; @@ -108,11 +112,15 @@ export default class Interop { }; /** + * @param {CorePort} core_port * @param {MessagePort} fs_port * @param {InteropConfig} config * @returns {Promise} */ - async init(fs_port, config) { + async init(core_port, fs_port, config) { + const core_parallel = new Parallel(Core, true); + this.#core = core_parallel.link(core_port); + const fs_parallel = new Parallel(Filesystem, true); const filesystem = fs_parallel.link(fs_port); this.#wasi = new WASI(config.memory, filesystem, config.fds); @@ -122,10 +130,7 @@ export default class Interop { if (!video.data) return; - const video_view = video.format == 1 - ? new Uint8Array(config.memory.buffer, video.data, video.pitch * video.height).slice() - : new Uint16Array(config.memory.buffer, video.data, (video.pitch * video.height) / 2).slice(); - postMessage({ type: 'video', view: video_view, video }, [video_view.buffer]); + this.#core.draw(video); }; const junie_interop_audio = (audio_c) => { @@ -133,8 +138,7 @@ export default class Interop { if (!audio.frames) return; - const audio_view = new Float32Array(config.memory.buffer, audio.data, audio.frames * 2).slice(); - postMessage({ type: 'audio', view: audio_view, sample_rate: audio.rate }, [audio_view.buffer]); + this.#core.play(audio); }; const junie_interop_variables = (variables_c) => { diff --git a/ui/sources/services/parallel.js b/ui/sources/services/parallel.js index 729a783..7ae1783 100644 --- a/ui/sources/services/parallel.js +++ b/ui/sources/services/parallel.js @@ -175,6 +175,16 @@ export default class Parallel { if (worker.close) worker.close(); } + /** + * @param {any} context + * @returns {MessagePort} + */ + static instrument(context) { + const channel = new MessageChannel(); + channel.port1.onmessage = instrumentContext(context); + return channel.port2; + } + /** * @param {any} obj * @returns {boolean}