From fee323d302227cc9f13c0368fd959add8e07b1ee Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 4 Jul 2021 22:43:44 -0700 Subject: [PATCH] Maki progress page --- packages/webamp-modern-2/src/maki/objects.ts | 4 +- packages/webamp-modern-2/src/progress.html | 57 ++++++++++ packages/webamp-modern-2/src/progress.ts | 109 +++++++++++++++++++ 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 packages/webamp-modern-2/src/progress.html create mode 100644 packages/webamp-modern-2/src/progress.ts diff --git a/packages/webamp-modern-2/src/maki/objects.ts b/packages/webamp-modern-2/src/maki/objects.ts index 41b8b8f7..adb8ba35 100644 --- a/packages/webamp-modern-2/src/maki/objects.ts +++ b/packages/webamp-modern-2/src/maki/objects.ts @@ -57,7 +57,7 @@ export function getMethod( // TODO: We could probably just fix the keys used in this file to already be normalized // We might even want to normalize the to match the formatting we get out the file. That could // avoid the awkward regex inside `getClass()`. -const normalizedObjects: { [key: string]: ObjectDefinition } = {}; +export const normalizedObjects: { [key: string]: ObjectDefinition } = {}; Object.keys(objects).forEach((key) => { normalizedObjects[key.toLowerCase()] = objects[key]; }); @@ -78,7 +78,7 @@ Object.values(normalizedObjects).forEach((object) => { object.parentClass = parentClass; }); -function getFormattedId(id: string): string { +export function getFormattedId(id: string): string { // https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding const formattedId = id.replace( /(........)(....)(....)(..)(..)(..)(..)(..)(..)(..)(..)/, diff --git a/packages/webamp-modern-2/src/progress.html b/packages/webamp-modern-2/src/progress.html new file mode 100644 index 00000000..a92eb2f5 --- /dev/null +++ b/packages/webamp-modern-2/src/progress.html @@ -0,0 +1,57 @@ + + + + + + + + Progress + + + +

Maki Implementation Progress

+ + + \ No newline at end of file diff --git a/packages/webamp-modern-2/src/progress.ts b/packages/webamp-modern-2/src/progress.ts new file mode 100644 index 00000000..dc77f254 --- /dev/null +++ b/packages/webamp-modern-2/src/progress.ts @@ -0,0 +1,109 @@ +// This module is imported early here in order to avoid a circular dependency. +import { classResolver } from "./skin/resolver"; +import { normalizedObjects, getFormattedId } from "./maki/objects"; +import BaseObject from "./skin/BaseObject"; + +function hack() { + // Without this Snowpack will try to treeshake out resolver causing a circular + // dependency. + classResolver("A funny joke about why this is needed."); +} + +function getClass(guid: string): typeof BaseObject | null { + try { + return classResolver(guid); + } catch (e) { + return null; + } +} + +const totals = document.createElement("div"); +document.body.appendChild(totals); +const table = document.createElement("table"); +document.body.appendChild(table); + +const header = document.createElement("tr"); +const nameHeader = document.createElement("th"); +nameHeader.innerText = "Class Name"; +header.appendChild(nameHeader); +const methodHeader = document.createElement("th"); +methodHeader.innerText = "Methods"; +header.appendChild(methodHeader); + +table.appendChild(header); + +const classes = []; +for (const [key, obj] of Object.entries(normalizedObjects)) { + const name = obj.name; + const methods = []; + const klass = getClass(getFormattedId(key.toLowerCase())); + for (const method of obj.functions) { + const params = method.parameters.map(([type, name]) => name); + const methodName = `${method.name}(${params.join(", ")})`; + const hook = method.name.toLowerCase().startsWith("on"); + if (hook) { + methods.push({ name: methodName, hook: true }); + continue; + } else if (klass == null) { + methods.push({ name: methodName, status: "missing" }); + } else { + const impl = klass.prototype[method.name.toLowerCase()]; + if (impl == null) { + methods.push({ name: methodName, status: "missing" }); + } else if (impl.length !== method.parameters.length) { + methods.push({ name: methodName, status: "wrong" }); + } else { + methods.push({ name: methodName, status: "found" }); + } + } + } + classes.push({ name, methods }); +} + +let total = 0; +let found = 0; + +for (const cls of classes) { + const classRow = document.createElement("tr"); + classRow.addEventListener("click", () => { + classRow.classList.toggle("expanded"); + }); + const className = document.createElement("td"); + className.classList.add("class-name"); + const totalCount = cls.methods.filter((m) => !m.hook).length; + const foundCount = cls.methods.filter((m) => !m.hook && m.status === "found") + .length; + total += totalCount; + found += foundCount; + className.innerText = `${cls.name} (${foundCount}/${totalCount})`; + classRow.appendChild(className); + const methodsCell = document.createElement("td"); + classRow.appendChild(methodsCell); + for (const method of cls.methods) { + if (method.hook) { + continue; + } + const methodDiv = document.createElement("span"); + methodDiv.classList.add("method"); + methodDiv.innerText = method.name; + methodDiv.title = method.name; + switch (method.status) { + case "missing": + methodDiv.style.backgroundColor = "pink"; + break; + case "found": + methodDiv.style.backgroundColor = "lightgreen"; + break; + case "wrong": + methodDiv.style.backgroundColor = "red"; + break; + } + methodsCell.appendChild(methodDiv); + } + + table.appendChild(classRow); +} + +methodHeader.innerText += ` (${found}/${total}, ${Math.round( + (found / total) * 100 +)}% Complete)`;