From 6e2350a872850b2e966db4935a935f6dcd724434 Mon Sep 17 00:00:00 2001 From: zongor Date: Mon, 27 May 2024 18:12:34 -0400 Subject: [PATCH] move to tools, add transpiler --- client/main.c | 1 - .../test/schema.json | 165 ++++++++++++++++ .../js-class-c-struct-transpiler/transpile.js | 181 ++++++++++++++++++ .../test-js-c-interop}/build.sh | 0 .../test-js-c-interop}/index.html | 0 .../test-js-c-interop}/index.js | 0 .../test-js-c-interop}/index.wasm | Bin .../test-js-c-interop}/test.c | 0 .../test-js-c-interop}/test.js | 0 9 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 tools/js-class-c-struct-transpiler/test/schema.json create mode 100644 tools/js-class-c-struct-transpiler/transpile.js rename {test-js-c-interop => tools/test-js-c-interop}/build.sh (100%) rename {test-js-c-interop => tools/test-js-c-interop}/index.html (100%) rename {test-js-c-interop => tools/test-js-c-interop}/index.js (100%) rename {test-js-c-interop => tools/test-js-c-interop}/index.wasm (100%) rename {test-js-c-interop => tools/test-js-c-interop}/test.c (100%) rename {test-js-c-interop => tools/test-js-c-interop}/test.js (100%) diff --git a/client/main.c b/client/main.c index e36b509..e5ffeac 100644 --- a/client/main.c +++ b/client/main.c @@ -1,5 +1,4 @@ #include "raylib.h" -#include "rcamera.h" #include #include #include diff --git a/tools/js-class-c-struct-transpiler/test/schema.json b/tools/js-class-c-struct-transpiler/test/schema.json new file mode 100644 index 0000000..5a59822 --- /dev/null +++ b/tools/js-class-c-struct-transpiler/test/schema.json @@ -0,0 +1,165 @@ +{ + "Vector3": { + "x": { + "type": "f32", + "kind": "scalar" + }, + "y": { + "type": "f32", + "kind": "scalar" + }, + "z": { + "type": "f32", + "kind": "scalar" + } + }, + "Entity": { + "Name": { + "type": "string", + "kind": "string", + "size": "24" + }, + "Strength": { + "type": "i32", + "kind": "scalar" + }, + "Endurance": { + "type": "i32", + "kind": "scalar" + }, + "Intelligence": { + "type": "i32", + "kind": "scalar" + }, + "Wisdom": { + "type": "i32", + "kind": "scalar" + }, + "Charisma": { + "type": "i32", + "kind": "scalar" + }, + "Faith": { + "type": "i32", + "kind": "scalar" + }, + "Artisan": { + "type": "i32", + "kind": "scalar" + }, + "Metalworking": { + "type": "i32", + "kind": "scalar" + }, + "Alchemy": { + "type": "i32", + "kind": "scalar" + }, + "Engineering": { + "type": "i32", + "kind": "scalar" + }, + "Culinary": { + "type": "i32", + "kind": "scalar" + }, + "Ranged": { + "type": "i32", + "kind": "scalar" + }, + "Melee": { + "type": "i32", + "kind": "scalar" + }, + "Acrobatics": { + "type": "i32", + "kind": "scalar" + }, + "Prestidigitation": { + "type": "i32", + "kind": "scalar" + }, + "Language": { + "type": "i32", + "kind": "scalar" + }, + "Medicine": { + "type": "i32", + "kind": "scalar" + }, + "Thaumitology": { + "type": "i32", + "kind": "scalar" + }, + "Theology": { + "type": "i32", + "kind": "scalar" + }, + "Fishing": { + "type": "i32", + "kind": "scalar" + }, + "Mining": { + "type": "i32", + "kind": "scalar" + }, + "Survival": { + "type": "i32", + "kind": "scalar" + }, + "Gardening": { + "type": "i32", + "kind": "scalar" + }, + "History": { + "type": "i32", + "kind": "scalar" + }, + "Perception": { + "type": "i32", + "kind": "scalar" + }, + "Luck": { + "type": "i32", + "kind": "scalar" + }, + "Stealth": { + "type": "i32", + "kind": "scalar" + }, + "Attractiveness": { + "type": "i32", + "kind": "scalar" + }, + "Affluence": { + "type": "i32", + "kind": "scalar" + }, + "Notoriety": { + "type": "i32", + "kind": "scalar" + } + }, + "Camera3D": { + "position": { + "type": "Vector3", + "kind": "struct" + }, + "target": { + "type": "Vector3", + "kind": "struct" + }, + "up": { + "type": "Vector3", + "kind": "struct" + }, + "fovy": { + "type": "f32", + "kind": "scalar" + }, + "projection": { + "type": "f32", + "kind": "scalar" + } + } +} diff --git a/tools/js-class-c-struct-transpiler/transpile.js b/tools/js-class-c-struct-transpiler/transpile.js new file mode 100644 index 0000000..e10ce86 --- /dev/null +++ b/tools/js-class-c-struct-transpiler/transpile.js @@ -0,0 +1,181 @@ +import { parseArgs } from "util"; + +let types = { + u8: { + c: "uint8_t", + js: "Uint8", + size: 1, + }, + i8: { + c: "int8_t", + js: "Int8", + size: 1, + }, + u16: { + c: "uint16_t", + js: "Uint16", + size: 2, + }, + i16: { + c: "int16_t", + js: "Int16", + size: 2, + }, + u32: { + c: "uint32_t", + js: "Uint32", + size: 4, + }, + i32: { + c: "int32_t", + js: "Int32", + size: 4, + }, + f32: { + c: "float", + js: "Float32", + size: 4, + }, + f64: { + c: "double", + js: "Float64", + size: 8, + }, +}; + +const { values } = parseArgs({ + args: Bun.argv, + options: { + schema: { + type: "string", + short: "S", + }, + out: { + type: "string", + short: "o" + } + }, + strict: true, + allowPositionals: true, +}); + +function jsStructConstructor(size, containsString) { + return ` + get bytes() { + return new Uint8Array(this._ptr); + } + + constructor(init = {}, ptr = undefined) { + this._size = ${size}; + this._ptr = ptr.buffer || new ArrayBuffer(this._size); + this._data = new DataView(this._ptr); + ${ + containsString + ? ` + this._encoder = new TextEncoder(); + this._decoder = new TextDecoder();` + : "" + } + for (const key of Object.keys(init)) { + this[key] = init[key]; + } + }`; +} + +const sFile = Bun.file(values.schema); +const schema = await sFile.json(); +let cData = ""; + +for (const type of Object.keys(schema)) { + let containsString = false; + let offset = 0; + let size = 0; + let jsData = ""; + const props = schema[type]; + cData += `typedef struct ${type} {`; + jsData += `class ${type} {`; + for (const prop of Object.keys(props)) { + const propType = props[prop].type; + const kind = props[prop].kind; + let typeSize = parseInt(types[propType]?.size); + + switch (kind) { + case "string": + containsString = true; + typeSize = props[prop].size; + const iSize = parseInt(offset) + parseInt(typeSize); + jsData += ` + get ${prop}() { + return this._decoder.decode(new Uint8Array(this._ptr.slice(${parseInt( + offset + )}, ${iSize}))); + } + set ${prop}(v) { + this._data.set(this._encoder.encode(v), ${parseInt(offset)}); + } + `; + + cData += ` + char ${prop}[${iSize}];`; + break; + case "scalar": + typeSize = types[propType].size; + jsData += ` + get ${prop}() { + return this._data.get${types[propType].js}(${parseInt(offset)}, true); + } + set ${prop}(v) { + return this._data.set${types[propType].js}(${parseInt( + offset + )}, v, true); + } + `; + + cData += ` + ${types[propType].c} ${prop};`; + + break; + case "struct": + const jsSize = parseInt(offset) + parseInt(types[propType].size); + jsData += ` + get ${prop}() { + return new ${propType}({}, new Uint8Array(this._ptr.slice(${offset}, ${jsSize}))); + } + set ${prop}(v) { + this._data.set(v.bytes(), ${offset}); + } + `; + + cData += ` + ${types[propType].c} ${prop};`; + break; + case "array": + break; + default: + break; + } + + size += parseInt(typeSize); + offset += parseInt(typeSize); + } + + /** + * add the new type to the list so we can use it for structs later. + */ + types[type] = { + c: type, + js: type, + size: parseInt(size), + }; + + jsData += jsStructConstructor(size, containsString); + jsData += ` +}`; + cData += ` +} ${type}; + +`; + + await Bun.write(Bun.file(values.out + type + ".js"), jsData); +} +await Bun.write(Bun.file(values.out + "types.h"), cData); diff --git a/test-js-c-interop/build.sh b/tools/test-js-c-interop/build.sh similarity index 100% rename from test-js-c-interop/build.sh rename to tools/test-js-c-interop/build.sh diff --git a/test-js-c-interop/index.html b/tools/test-js-c-interop/index.html similarity index 100% rename from test-js-c-interop/index.html rename to tools/test-js-c-interop/index.html diff --git a/test-js-c-interop/index.js b/tools/test-js-c-interop/index.js similarity index 100% rename from test-js-c-interop/index.js rename to tools/test-js-c-interop/index.js diff --git a/test-js-c-interop/index.wasm b/tools/test-js-c-interop/index.wasm similarity index 100% rename from test-js-c-interop/index.wasm rename to tools/test-js-c-interop/index.wasm diff --git a/test-js-c-interop/test.c b/tools/test-js-c-interop/test.c similarity index 100% rename from test-js-c-interop/test.c rename to tools/test-js-c-interop/test.c diff --git a/test-js-c-interop/test.js b/tools/test-js-c-interop/test.js similarity index 100% rename from test-js-c-interop/test.js rename to tools/test-js-c-interop/test.js