Maki progress page

This commit is contained in:
Jordan Eldredge 2021-07-04 22:43:44 -07:00
parent 3ff0d3bc46
commit fee323d302
3 changed files with 168 additions and 2 deletions

View file

@ -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(
/(........)(....)(....)(..)(..)(..)(..)(..)(..)(..)(..)/,

View file

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Webamp Modern" />
<link rel="shortcut icon" type="image/x-icon" href="assets/favicon.ico"/>
<title>Progress</title>
<style>
h1 {
text-align: center;
}
table {
max-width: 800px;
margin: 0 auto;
font-family: monospace;
}
table th {
font-size: 20px;
text-align: left;
}
.method {
width: 20px;
height: 20px;
display: inline-block;
overflow: hidden;
text-indent: -99999px;
border: 1px solid grey;
margin: 1px;
}
.expanded .method {
width: auto;
height: 20px;
display: block;
overflow: hidden;
text-indent: 0;
border: none;
margin: 1px;
padding-left: 3px;
}
.class-name {
white-space: nowrap;
font-weight: bold;
display: block;
cursor: pointer;
text-align: right;
margin-right: 4px;
}
</style>
</head>
<body>
<h1>Maki Implementation Progress</h1>
<script type="module" src="./progress.js"></script>
</body>
</html>

View file

@ -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)`;