diff --git a/tools/js-class-c-struct-transpiler/test/build.sh b/tools/js-class-c-struct-transpiler/test/build.sh new file mode 100755 index 0000000..eba6d0b --- /dev/null +++ b/tools/js-class-c-struct-transpiler/test/build.sh @@ -0,0 +1 @@ +emcc -lwebsocket.js -o index.html test_client.c \ No newline at end of file diff --git a/tools/js-class-c-struct-transpiler/test/schema.json b/tools/js-class-c-struct-transpiler/test/schema.json index 5a59822..e392634 100644 --- a/tools/js-class-c-struct-transpiler/test/schema.json +++ b/tools/js-class-c-struct-transpiler/test/schema.json @@ -13,12 +13,38 @@ "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" + } + }, "Entity": { "Name": { "type": "string", "kind": "string", "size": "24" }, + "Camera": { + "type": "Camera3D", + "kind": "struct" + }, "Strength": { "type": "i32", "kind": "scalar" @@ -139,27 +165,5 @@ "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/test/test_client.c b/tools/js-class-c-struct-transpiler/test/test_client.c new file mode 100644 index 0000000..e2efb6d --- /dev/null +++ b/tools/js-class-c-struct-transpiler/test/test_client.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include "out/types.h" + +EM_BOOL WebSocketOpen(int eventType, const EmscriptenWebSocketOpenEvent *e, void *userData) { + printf("open(eventType=%d, userData=%p)\n", eventType, userData); + + Camera3D camera = {0}; + camera.position = (Vector3){-9.0f, 9.0f, 4.0f}; + camera.target = (Vector3){9.0f, 9.0f, 0.0f}; + camera.up = (Vector3){0.0f, 1.0f, 0.0f}; + camera.fovy = 60.0f; + camera.projection = 0; + + emscripten_websocket_send_binary(e->socket, &camera, sizeof(camera)); + + return 0; +} + +EM_BOOL WebSocketClose(int eventType, const EmscriptenWebSocketCloseEvent *e, void *userData) { + printf("close(eventType=%d, wasClean=%d, code=%d, reason=%s, userData=%p)\n", eventType, e->wasClean, e->code, e->reason, userData); + return 0; +} + +EM_BOOL WebSocketError(int eventType, const EmscriptenWebSocketErrorEvent *e, void *userData) { + printf("error(eventType=%d, userData=%p)\n", eventType, userData); + return 0; +} + +EM_BOOL WebSocketMessage(int eventType, const EmscriptenWebSocketMessageEvent *e, void *userData) { + printf("message(eventType=%d, userData=%p data=%p, numBytes=%d, isText=%d)\n", eventType, userData, e->data, e->numBytes, e->isText); + static int text_received = 0; + if (e->isText) { + printf("text data: \"%s\"\n", e->data); + assert(strcmp((const char*)e->data, "hello on the other side") == 0); + text_received = 1; + return 0; + } + + Camera3D camera; + memcpy(&camera, e->data, sizeof camera); + + printf("x: %f", camera.position.x); + printf(" y: %f", camera.position.y); + printf(" z: %f", camera.position.z); + printf(" fovy: %f", camera.fovy); + printf("\n"); + + emscripten_websocket_close(e->socket, 0, 0); + emscripten_websocket_delete(e->socket); + emscripten_force_exit(0); + return 0; +} + +int main() { + assert(emscripten_websocket_is_supported()); + + EmscriptenWebSocketCreateAttributes attr; + emscripten_websocket_init_create_attributes(&attr); + + const char *url = "ws://localhost:8089/"; + attr.url = url; + // We don't really use a special protocol on the server backend in this test, + // but check that it can be passed. + attr.protocols = "binary,base64"; + + EMSCRIPTEN_WEBSOCKET_T socket = emscripten_websocket_new(&attr); + assert(socket >= 0); + + // URL: + int urlLength = 0; + EMSCRIPTEN_RESULT res = emscripten_websocket_get_url_length(socket, &urlLength); + assert(res == EMSCRIPTEN_RESULT_SUCCESS); + assert(urlLength == strlen(url)+1); + + char *url2 = malloc(urlLength); + res = emscripten_websocket_get_url(socket, url2, urlLength); + assert(res == EMSCRIPTEN_RESULT_SUCCESS); + printf("url: %s, verified: %s, length: %d\n", url, url2, urlLength); + assert(!strcmp(url, url2)); + + // Protocol: + int protocolLength = 0; + res = emscripten_websocket_get_protocol_length(socket, &protocolLength); + assert(res == EMSCRIPTEN_RESULT_SUCCESS); + assert(protocolLength == 1); // Null byte + + char *protocol = malloc(protocolLength); + res = emscripten_websocket_get_protocol(socket, protocol, protocolLength); + assert(res == EMSCRIPTEN_RESULT_SUCCESS); + // We don't really use a special protocol on the server backend in this test, + // but test that it comes out as an empty string at least. + assert(!strcmp(protocol, "")); + + // Extensions: + int extensionsLength = 0; + res = emscripten_websocket_get_extensions_length(socket, &extensionsLength); + assert(res == EMSCRIPTEN_RESULT_SUCCESS); + assert(extensionsLength == 1); // Null byte + + char *extensions = malloc(extensionsLength); + res = emscripten_websocket_get_extensions(socket, extensions, extensionsLength); + assert(res == EMSCRIPTEN_RESULT_SUCCESS); + // We don't really use any extensions on the server backend in this test, but + // test that it comes out as an empty string at least. + assert(!strcmp(extensions, "")); + + emscripten_websocket_set_onopen_callback(socket, (void*)0x42, WebSocketOpen); + emscripten_websocket_set_onclose_callback(socket, (void*)0x43, WebSocketClose); + emscripten_websocket_set_onerror_callback(socket, (void*)0x44, WebSocketError); + emscripten_websocket_set_onmessage_callback(socket, (void*)0x45, WebSocketMessage); + emscripten_exit_with_live_runtime(); + return 0; +} \ No newline at end of file diff --git a/tools/js-class-c-struct-transpiler/test/test_server.js b/tools/js-class-c-struct-transpiler/test/test_server.js new file mode 100644 index 0000000..36290f3 --- /dev/null +++ b/tools/js-class-c-struct-transpiler/test/test_server.js @@ -0,0 +1,25 @@ +var decoder = new TextDecoder("utf-8"); +var port = 8089; +var ws = require("ws"); +var wss = new ws.WebSocketServer({ port: port }); +console.log("WebSocket server listening on ws://localhost:" + port + "/"); +wss.on("connection", function (ws) { + console.log("Client connected!"); + ws.on("message", function (message, isBinary) { + if (!isBinary) { + var text = decoder.decode(new Uint8Array(message).buffer); + console.log("received TEXT: " + text.length + " characters:"); + console.log(' "' + text + '"'); + } else { + const camera = new Camera3D({}, new Uint8Array(message)); + console.log(camera.position.x, camera.position.y, camera.position.z); + console.log(camera.target.x, camera.target.y, camera.target.z); + console.log(camera.up.x, camera.up.y, camera.up.z); + console.log(camera.fovy); + console.log(camera.projection); + console.log(camera.bytes); + + ws.send(camera.bytes, { binary: true }); // Echo back the received message + } + }); +}); diff --git a/tools/js-class-c-struct-transpiler/transpile.js b/tools/js-class-c-struct-transpiler/transpile.js index c51b612..6d7235d 100644 --- a/tools/js-class-c-struct-transpiler/transpile.js +++ b/tools/js-class-c-struct-transpiler/transpile.js @@ -170,7 +170,9 @@ for (const type of Object.keys(schema)) { jsData += jsStructConstructor(size, containsString); jsData += ` -}`; +} + +export default ${type}`; cData += ` } ${type};