diff --git a/experiments/maki-interpreter/index.js b/experiments/maki-interpreter/index.js index 1e157499..c966ff5a 100644 --- a/experiments/maki-interpreter/index.js +++ b/experiments/maki-interpreter/index.js @@ -1,5 +1,6 @@ const { COMMANDS } = require("./constants"); const Command = require("./command"); +const { getClass } = require("./objects"); const MAGIC = "FG"; const ENCODING = "binary"; @@ -28,21 +29,29 @@ class Parser { .toString(16) .padStart(8, "0"); } - types.push(identifier); + const klass = getClass(identifier); + if (klass == null) { + throw new Error(`Could not find class for id: ${identifier}`); + } + types.push(klass); } return types; } - _readFunctionsNames() { + _readFunctionsNames({ types }) { let count = this._readUInt32LE(); const functionNames = []; while (count--) { const classCode = this._readUInt16LE(); // Offset into our parsed types - const classType = classCode & 0xff; + const typeOffset = classCode & 0xff; const dummy2 = this._readUInt16LE(); const name = this._readString(); - functionNames.push({ classCode, classType, dummy2, name }); + functionNames.push({ + dummy2, + name, + class: types[typeOffset] + }); } return functionNames; } @@ -195,7 +204,7 @@ class Parser { this._readVersion(); this._readUInt32LE(); // Not sure what we are skipping over here. Just some UInt 32. const types = this._readTypes(); - const functionNames = this._readFunctionsNames(); + const functionNames = this._readFunctionsNames({ types }); const variables = this._readVariables(); const constants = this._readConstants(); const functions = this._readFunctions(); diff --git a/experiments/maki-interpreter/index.test.js b/experiments/maki-interpreter/index.test.js index d59b30ec..70738dd1 100644 --- a/experiments/maki-interpreter/index.test.js +++ b/experiments/maki-interpreter/index.test.js @@ -18,46 +18,44 @@ describe("standardframe.maki", () => { }); test("can read types", () => { - // These values were extracted from what the Perl decompiler gets. - expect(maki.types).toEqual([ - "516549714a510d87b5a6e391e7f33532", - "d6f50f6449b793fa66baf193983eaeef", - "e90dc47b4ae7840d0b042cb0fcf775d2", - "00c074a049a0fea2bbfa8dbe401616db", - "b2023ab54ba1434d6359aebec6f30375", - "3860366542a7461b3fd875aa73bf6766", - "f4787af44ef7b2bb4be7fb9c8da8bea9", - "3a370c02439f3cbf8886f184361ecf5b", - "5d0c5bb64b1f7de1168d0fa741199459", - "4ee3e1994becc636bc78cd97b028869c", - "45be95e5419120725fbb5c93fd17f1f9", - "60906d4e482e537e94cc04b072568861", - "403abcc04bd66f22c810a48b47259329", - "97aa3e4d4fa8f4d0f20a7b818349452a", - "64e4bbfa49d981f45ba8c0b0fdbcc32e", - "62b65e3f408d375e8176ea8d771bb94a", - "ce4f97be4e1977b098d45699276cc933", - "a8c2200d4b2a51eb4b5d7fba714c5dc6", - "8d1eba38483e489e1f8d60b905c4c543", - "0f08c9404b23af39c4b8f38059bb7e8f", - "efaa867241fa310ea985dcb74bcb5b52", - "7dfd32444e7c3751ae8240bf33dc3a5f", - "5ab9fa1545579a7d5765c8aba97cc6a6", - "698eddcd4fec8f1e44f9129b45ff09f9", - "6b64cd274c4b5a26a7e6598c3a49f60c", - "b4dccfff4bcc81fe0f721b96ff0fbed5", - "01e28ce111d5b059dee49f970a76516f", - "80f0f8bd42a61ba5363293a04a8d0ca0", - "cdcb785d425381f2b861058ffa3c2872", - "9b2e341b40fa6c981b0c858b0594e86e", - "36d59b714af803fd020595977a26dbb7", - "7fd5f21048dfacc45154a0a676dc6c57", - "b5baa5354dcb05b318e6c1ad96688fd2" + expect(maki.types.map(klass => klass.name)).toEqual([ + "Object", + "System", + "Container", + "Wac", + "List", + "Map", + "PopupMenu", + "Region", + "Timer", + "GuiObject", + "Group", + "Layout", + "Component", + "ComponentBucket", + "Edit", + "Slider", + "Vis", + "Browser", + "EqVis", + "Status", + "Text", + "Title", + "Layer", + "Button", + "AnimatedLayer", + "ToggleButton", + "GroupList", + "CfgGroup", + "QueryList", + "MouseRedir", + "DropDownList", + "LayoutStatus", + "TabSheet" ]); }); test("can read functionNames", () => { - expect(maki.functionNames.length).toBe(12); expect(maki.functionNames.map(func => func.name)).toEqual([ "onScriptLoaded", "getScriptGroup", @@ -72,9 +70,7 @@ describe("standardframe.maki", () => { "newGroup", "init" ]); - maki.functionNames.forEach(func => { - expect(maki.types[func.classType]).not.toBe(undefined); - }); + expect(maki.functionNames.every(func => func.class != null)).toBe(true); }); test("can read variables", () => { diff --git a/experiments/maki-interpreter/objects.js b/experiments/maki-interpreter/objects.js index 720c11ac..dfa9ecb4 100644 --- a/experiments/maki-interpreter/objects.js +++ b/experiments/maki-interpreter/objects.js @@ -3925,14 +3925,22 @@ const objects = { } }; -function getObject(id) { +// 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 = {}; +Object.keys(objects).forEach(key => { + normalizedObjects[key.toLowerCase()] = objects[key]; +}); + +function getClass(id) { // https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding const formattedId = id.replace( /(........)(....)(....)(..)(..)(..)(..)(..)(..)(..)(..)/, "$1$3$2$7$6$5$4$11$10$9$8" ); - return objects[formattedId.toUpperCase()]; + return normalizedObjects[formattedId.toLowerCase()]; } -module.exports = { getObject }; +module.exports = { getClass };