diff --git a/experiments/modern/src/App.js b/experiments/modern/src/App.js index e5d96147..94dff260 100644 --- a/experiments/modern/src/App.js +++ b/experiments/modern/src/App.js @@ -2,6 +2,8 @@ import React from "react"; import JSZip from "jszip"; import "./App.css"; import * as Utils from "./utils"; +import initialize from "./initialize"; + // const runtime = require("./maki-interpreter/runtime"); // const System = require("./maki-interpreter/runtime/System"); // const interpret = require("./maki-interpreter/interpreter"); @@ -42,11 +44,14 @@ async function loadImage(imgUrl) { } async function getSkin() { - const resp = await fetch( - process.env.PUBLIC_URL + "/skins/CornerAmp_Redux.wal" - ); + const resp = await fetch(process.env.PUBLIC_URL + "/skins/simple.wal"); const blob = await resp.blob(); - const zip = await JSZip.loadAsync(blob); + const zip = null; + + const registry = { scripts: [] }; + await initialize(registry, blob); + console.log("registry: ", registry); + throw new Error("done"); const skinXml = await Utils.inlineIncludes( await Utils.readXml(zip, "skin.xml"), zip diff --git a/experiments/modern/src/initialize.js b/experiments/modern/src/initialize.js new file mode 100644 index 00000000..a226983a --- /dev/null +++ b/experiments/modern/src/initialize.js @@ -0,0 +1,162 @@ +import * as Utils from "./utils"; +import JSZip from "jszip"; + +const schema = { + groupdef: [ + "layer", + "layoutstatus", + "hideobject", + "button", + "wasabi:titlebar", + "group", + "script", + "sendparams", + "eqvis", + "slider", + "component", + "colorthemes:list", + "wasabi:button", + "text", + "vis", + ], + layout: [ + "wasabi:standardframe:status", + "text", + "wasabi:standardframe:nostatus", + "layer", + "button", + "togglebutton", + "status", + "slider", + "group", + ], + container: ["groupdef", "layout", "scripts"], + scripts: ["script"], + elements: ["color", "bitmap", "bitmapfont", "truetypefont"], + skininfo: [ + "version", + "name", + "author", + "comment", + "email", + "homepage", + "screenshot", + ], + wasabixml: ["skininfo", "scripts", "elements", "groupdef", "container"], + // same as above, wa3 vs wa5 + winampabstractionlayer: [ + "skininfo", + "scripts", + "elements", + "groupdef", + "container", + ], + gammaset: ["gammagroup"], +}; + +const parsers = { + groupdef(node, parent, registry, zip) {}, + skininfo: () => {}, + version: () => {}, + name: () => {}, + comment: () => {}, + author: () => {}, + email: () => {}, + homepage: () => {}, + screenshot: () => {}, + container: () => {}, + scripts: () => {}, + gammaset: () => {}, + color: () => {}, + layer: () => {}, + layoutstatus: () => {}, + hideobject: () => {}, + button: () => {}, + group: () => {}, + layout: () => {}, + sendparams: () => {}, + elements: () => {}, + bitmap: () => {}, + eqvis: () => {}, + slider: () => {}, + gammagroup: () => {}, + truetypefont: () => {}, + component: () => {}, + text: () => {}, + layer: () => {}, + button: () => {}, + togglebutton: () => {}, + status: () => {}, + slider: () => {}, + bitmapfont: () => {}, + vis: () => {}, + "wasabi:titlebar": () => {}, + "colorthemes:list": () => {}, + "wasabi:standardframe:status": () => {}, + "wasabi:standardframe:nostatus": () => {}, + "wasabi:button": () => {}, + async script(node, parent, registry, zip) { + const { id, file, param } = node.attributes; + const script = await Utils.readUint8array(zip, file); + registry.scripts.push({ parent, id, param, script }); + }, +}; + +async function parseChildren(node, parsedParent, registry, zip) { + if (node.type === "comment") { + return; + } + if (node.name == null) { + console.error(node); + throw new Error("Unknown node"); + } + + const validChildren = new Set(schema[node.name.toLowerCase()]); + await Promise.all( + node.children.map(async child => { + if (child.type === "comment") { + return; + } + if (child.type === "text") { + // TODO: Handle text + return; + } + if (child.name == null) { + console.error(child); + throw new Error("Unknown node"); + } + const childName = child.name.toLowerCase(); + if (childName == null) { + console.error(node); + throw new Error("Unknown node"); + } + + if (!validChildren.has(childName)) { + debugger; + throw new Error(`Invalid child of a ${node.name}: ${childName}`); + } + + const childParser = parsers[childName]; + if (childParser == null) { + throw new Error(`Missing parser for ${childName}`); + return; + } + const parsedChild = await childParser(child, node, registry, zip); + if (child.children != null) { + await parseChildren(child, parsedChild, registry, zip); + } + }) + ); +} + +async function initialize(registry, skinBlob) { + const zip = await JSZip.loadAsync(skinBlob); + const skinXml = await Utils.inlineIncludes( + await Utils.readXml(zip, "skin.xml"), + zip + ); + + await parseChildren(skinXml.children[0], null, registry, zip); +} + +export default initialize; diff --git a/experiments/modern/src/utils.js b/experiments/modern/src/utils.js index b8c69678..20daf977 100644 --- a/experiments/modern/src/utils.js +++ b/experiments/modern/src/utils.js @@ -91,7 +91,7 @@ export async function inlineIncludes(xml, zip) { node.attributes.file }` ); - return node; + return []; } return includedFile.children; });