From 3d5029173fdeb32e4acdcc528b2210e144a2f601 Mon Sep 17 00:00:00 2001 From: He4eT Date: Wed, 24 Feb 2021 20:50:22 +0500 Subject: [PATCH] Implement VM preparation --- src/common/engines.js | 44 +++++++++++++++++++++++++++++++++++++ src/common/if.js | 45 ++++++++++++++++++++++++++++++++++++++ src/views/Player.jsx | 51 +++++++++++++++++-------------------------- 3 files changed, 109 insertions(+), 31 deletions(-) create mode 100644 src/common/engines.js create mode 100644 src/common/if.js diff --git a/src/common/engines.js b/src/common/engines.js new file mode 100644 index 0000000..b4d7b37 --- /dev/null +++ b/src/common/engines.js @@ -0,0 +1,44 @@ +import bocfel from 'emglken/src/bocfel.js' +import glulxe from 'emglken/src/glulxe.js' +import git from 'emglken/src/git.js' +import hugo from 'emglken/src/hugo.js' +import tads from 'emglken/src/tads.js' + +const formats = [ + { + id: 'bocfel', + extensions: /z([3458]|blorb)$/, + engine: bocfel + }, + { + id: 'glulxe', + extensions: /(gblorb|ulx)$/, + engine: glulxe + }, + { + id: 'git', + extensions: /(gblorb|ulx)$/, + engine: git + }, + { + id: 'hugo', + extensions: /hex$/, + engine: hugo + }, + { + id: 'tads', + extensions: /(gam|t3)$/, + engine: tads + } +] + +export const engineByFilename = filename => { + const format = formats.find(x => + x.extensions.test(filename)) + + if (format) { + return format.engine + } else { + throw new Error(`Unsupported file type: ${filename}`) + } +} diff --git a/src/common/if.js b/src/common/if.js new file mode 100644 index 0000000..137c9eb --- /dev/null +++ b/src/common/if.js @@ -0,0 +1,45 @@ +// import CheapGlkOte from 'cheap-glkote' +// import engine from 'emglken/src/tads.js' + +import { engineByFilename } from '~/src/common/engines' + +export const prepareVM = ({ url, setStatus, setVM }) => _ => { + const st = (step, details) => args => { + setStatus({ step, details }) + return args + } + + return Promise.resolve() + .then(st('loading', 'Downloading file...')) + .then(_ => fetch(url)) + .then(st('loading', 'Processing file...')) + .then(response => response.arrayBuffer()) + .then(arrayBuffer => new Uint8Array(arrayBuffer)) + .then(st('loading', 'Downloading engine...')) + .then(file => setVM({ + file, + engine: engineByFilename(url) + })) + .then(st('loading', 'Running...')) + .catch(e => { + console.error(e) + setStatus({ level: 'fail', details: e.message }) + }) +} + +// export const fetchGameFile = url => fetch(url) +// .then(response => (console.log(response), response)) +// .then(response => response.blob()) +// .then(blob => new Response(blob).arrayBuffer()) +// .then(buffer => new Uint8Array(buffer)) +// .then(file => { +// const { glkInterface, sendFn } = CheapGlkOte({ +// onUpdateContent: messages => console.log(messages) +// }) +// window.send = sendFn + +// const vm = new engine() +// vm.prepare(file, glkInterface) +// vm.start() +// }) +// .catch(console.log) diff --git a/src/views/Player.jsx b/src/views/Player.jsx index b8feb5a..abf3b9b 100644 --- a/src/views/Player.jsx +++ b/src/views/Player.jsx @@ -1,42 +1,31 @@ import { h } from 'preact' -import { getFileExtension } from '~/src/utils/utils.routing' +import { useState, useEffect } from 'preact/hooks' +import { prepareVM } from '~/src/common/if' -import CheapGlkOte from 'cheap-glkote' -import engine from 'emglken/src/tads.js' - -const blobToFile = fileName => theBlob =>{ - return new File([theBlob], fileName) +const INITIAL_STATUS = { + level: 'loading', + details: 'Loading...' } export default function ({setTheme, theme, encodedUrl}) { - setTheme(theme) + const [url] = useState(decodeURIComponent(encodedUrl)) + const [status, setStatus] = useState(INITIAL_STATUS) - const url = decodeURIComponent(encodedUrl) - const type = getFileExtension(url) + const [vm, setVM] = useState(null) - const fetchGameFile = fetch(url) - .then(response => (console.log(response), response)) - .then(response => response.blob()) - .then(blob => new Response(blob).arrayBuffer()) - .then(buffer => new Uint8Array(buffer)) - .then(file => { - console.log(file) - const {glkInterface, sendFn} = CheapGlkOte({ - onUpdateContent: messages => console.log(messages) - }) - window.send = sendFn - - const vm = new engine() - vm.prepare(file, glkInterface) - vm.start() - }) - .catch(console.log) + useEffect(() => setTheme(theme), [theme]) + useEffect(prepareVM({ + url, + setStatus, + setVM + }), [url]) + useEffect(() => { + if (vm) console.log('success', vm) + }, [vm]) return ( -
- {theme}
- {type}
- {url} -
) +
+ {status.details} +
) }