Skip to content

Commit

Permalink
fix: fix a possible failure when writing config files
Browse files Browse the repository at this point in the history
  • Loading branch information
arianrhodsandlot committed Oct 16, 2023
1 parent f75919d commit ee924cf
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 38 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "nostalgist",
"description": "Nostalgist.js is a JavaScript library that allows you to run emulators of retro consoles within web browsers.",
"version": "0.4.1",
"version": "0.4.2",
"author": {
"name": "arianrhodsandlot",
"email": "theguidanceofawhitetower@gmail.com"
Expand Down
3 changes: 2 additions & 1 deletion src/emscripten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export function getEmscriptenModuleOverrides(overrides: RetroArchEmscriptenModul
}
},

async monitorRunDependencies(left: number) {
// the return value of `monitorRunDependencies` seems to be misused here, but it works for now
async monitorRunDependencies(left?: number) {
if (left === 0) {
resolveRunDependenciesPromise()
}
Expand Down
47 changes: 12 additions & 35 deletions src/emulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { createEmscriptenFS, getEmscriptenModuleOverrides } from './emscripten'
import type { EmulatorOptions } from './types/emulator-options'
import type { RetroArchCommand } from './types/retroarch-command'
import type { RetroArchEmscriptenModule } from './types/retroarch-emscripten'
import { blobToBuffer, delay, updateStyle } from './utils'
import { blobToBuffer, delay, importCoreJsAsESM, updateStyle } from './utils'

const encoder = new TextEncoder()

Expand Down Expand Up @@ -239,46 +239,23 @@ export class Emulator {
}

private async setupEmscripten() {
const { element, core, emscriptenModule } = this.options
const { js, wasm } = core
if (typeof window === 'object') {
// @ts-expect-error for retroarch fast forward
window.setImmediate ??= window.setTimeout
}

const jsContent = js.startsWith('var Module')
? `export function getEmscripten({ Module }) {
${js};
return { PATH, FS, ERRNO_CODES, JSEvents, ENV, Module, exit: _emscripten_force_exit
}}`
: js
const jsBlob = new Blob([jsContent], { type: 'application/javascript' })
const jsBlobUrl = URL.createObjectURL(jsBlob)
if (!jsBlobUrl) {
return
}
const { getEmscripten } = await (async () => {
try {
return await import(/* @vite-ignore */ /* webpackIgnore: true */ jsBlobUrl)
} catch {
// a dirty hack for using with SystemJS, for example, in StackBlitz
// eslint-disable-next-line no-eval
return await eval('import(jsBlobUrl)')
}
})()
URL.revokeObjectURL(jsBlobUrl)

const initialModule = getEmscriptenModuleOverrides({
wasmBinary: wasm,
canvas: element,
preRun: [],
...emscriptenModule,
})
this.emscripten = getEmscripten({ Module: initialModule })

const { Module, FS } = this.getEmscripten()
const { element, core, emscriptenModule } = this.options
const { js, wasm } = core
const moduleOptions = { wasmBinary: wasm, canvas: element, preRun: [], ...emscriptenModule }
const initialModule = getEmscriptenModuleOverrides(moduleOptions)
const { getEmscripten } = await importCoreJsAsESM(js)
const emscripten: EmulatorEmscripten = getEmscripten({ Module: initialModule })
this.emscripten = emscripten

const { Module, FS } = emscripten
initialModule.preRun?.push(() => FS.init(() => this.stdin()))
await Promise.all([await this.setupFileSystem(), await Module.monitorRunDependencies()])
await Module.monitorRunDependencies()
await this.setupFileSystem()
}

private sendCommand(msg: RetroArchCommand) {
Expand Down
2 changes: 1 addition & 1 deletion src/types/retroarch-emscripten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export interface RetroArchEmscriptenModule extends EmscriptenModule {
canvas: HTMLCanvasElement
setCanvasSize: (width: number, height: number) => void
preRun: ((...args: any) => void)[]
monitorRunDependencies: any
monitorRunDependencies: (left?: number) => void | Promise<void>
callMain: (args: string[]) => void
}

Expand Down
25 changes: 25 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,28 @@ export function delay(time: number) {
setTimeout(resolve, time)
})
}

export async function importCoreJsAsESM(js: string) {
const jsContent = js.startsWith('var Module')
? `export function getEmscripten({ Module }) {
${js};
return { PATH, FS, ERRNO_CODES, JSEvents, ENV, Module, exit: _emscripten_force_exit }
}`
: js

const jsBlob = new Blob([jsContent], { type: 'application/javascript' })
const jsBlobUrl = URL.createObjectURL(jsBlob)
if (!jsBlobUrl) {
throw new Error('invalid jsBlob')
}

try {
return await import(/* @vite-ignore */ /* webpackIgnore: true */ jsBlobUrl)
} catch {
// a dirty hack for using with SystemJS, for example, in StackBlitz
// eslint-disable-next-line no-eval
return await eval('import(jsBlobUrl)')
} finally {
URL.revokeObjectURL(jsBlobUrl)
}
}

0 comments on commit ee924cf

Please sign in to comment.