mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Change wasm/js/runtime.mjs to a normal .js file; Add interfaces and functions to a global odin variable
This commit is contained in:
+346
-289
@@ -1,7 +1,9 @@
|
|||||||
|
(function() {
|
||||||
class WasmMemoryInterface {
|
class WasmMemoryInterface {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.memory = null;
|
this.memory = null;
|
||||||
this.exports = null;
|
this.exports = null;
|
||||||
|
this.listenerMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
setMemory(memory) {
|
setMemory(memory) {
|
||||||
@@ -10,7 +12,6 @@ class WasmMemoryInterface {
|
|||||||
|
|
||||||
setExports(exports) {
|
setExports(exports) {
|
||||||
this.exports = exports;
|
this.exports = exports;
|
||||||
this.listenerMap = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get mem() {
|
get mem() {
|
||||||
@@ -90,292 +91,8 @@ class WasmMemoryInterface {
|
|||||||
storeUint(addr, value) { this.mem.setUint32 (addr, value, true); }
|
storeUint(addr, value) { this.mem.setUint32 (addr, value, true); }
|
||||||
};
|
};
|
||||||
|
|
||||||
function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
|
|
||||||
const MAX_INFO_CONSOLE_LINES = 512;
|
|
||||||
let infoConsoleLines = new Array();
|
|
||||||
const addConsoleLine = (line) => {
|
|
||||||
if (!line) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (line.endsWith("\n")) {
|
|
||||||
line = line.substring(0, line.length-1);
|
|
||||||
} else if (infoConsoleLines.length > 0) {
|
|
||||||
let prev_line = infoConsoleLines.pop();
|
|
||||||
line = prev_line.concat(line);
|
|
||||||
}
|
|
||||||
infoConsoleLines.push(line);
|
|
||||||
|
|
||||||
if (infoConsoleLines.length > MAX_INFO_CONSOLE_LINES) {
|
|
||||||
infoConsoleLines.shift();
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = "";
|
|
||||||
for (let i = 0; i < infoConsoleLines.length; i++) {
|
|
||||||
if (i != 0) {
|
|
||||||
data = data.concat("\n");
|
|
||||||
}
|
|
||||||
data = data.concat(infoConsoleLines[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consoleElement) {
|
|
||||||
let info = consoleElement;
|
|
||||||
info.innerHTML = data;
|
|
||||||
info.scrollTop = info.scrollHeight;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let event_temp_data = {};
|
|
||||||
|
|
||||||
return {
|
|
||||||
"env": {},
|
|
||||||
"odin_env": {
|
|
||||||
write: (fd, ptr, len) => {
|
|
||||||
const str = wasmMemoryInterface.loadString(ptr, len);
|
|
||||||
if (fd == 1) {
|
|
||||||
addConsoleLine(str);
|
|
||||||
return;
|
|
||||||
} else if (fd == 2) {
|
|
||||||
addConsoleLine(str);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
throw new Error("Invalid fd to 'write'" + stripNewline(str));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trap: () => { throw new Error() },
|
|
||||||
alert: (ptr, len) => { alert(wasmMemoryInterface.loadString(ptr, len)) },
|
|
||||||
abort: () => { Module.abort() },
|
|
||||||
evaluate: (str_ptr, str_len) => { eval.call(null, wasmMemoryInterface.loadString(str_ptr, str_len)); },
|
|
||||||
|
|
||||||
time_now: () => {
|
|
||||||
return performance.now() * 1e6;
|
|
||||||
},
|
|
||||||
|
|
||||||
sqrt: (x) => Math.sqrt(x),
|
|
||||||
sin: (x) => Math.sin(x),
|
|
||||||
cos: (x) => Math.cos(x),
|
|
||||||
pow: (x) => Math.pow(x),
|
|
||||||
fmuladd: (x, y, z) => x*y + z,
|
|
||||||
ln: (x) => Math.log(x),
|
|
||||||
exp: (x) => Math.exp(x),
|
|
||||||
ldexp: (x) => Math.ldexp(x),
|
|
||||||
},
|
|
||||||
"odin_dom": {
|
|
||||||
init_event_raw: (ep) => {
|
|
||||||
const W = 4;
|
|
||||||
let offset = ep;
|
|
||||||
let off = (amount, alignment) => {
|
|
||||||
if (alignment === undefined) {
|
|
||||||
alignment = Math.min(amount, W);
|
|
||||||
}
|
|
||||||
if (offset % alignment != 0) {
|
|
||||||
offset += alignment - (offset%alignment);
|
|
||||||
}
|
|
||||||
let x = offset;
|
|
||||||
offset += amount;
|
|
||||||
return x;
|
|
||||||
};
|
|
||||||
|
|
||||||
let wmi = wasmMemoryInterface;
|
|
||||||
|
|
||||||
let e = event_temp_data.event;
|
|
||||||
|
|
||||||
wmi.storeU32(off(4), event_temp_data.name_code);
|
|
||||||
if (e.target == document) {
|
|
||||||
wmi.storeU32(off(4), 1);
|
|
||||||
} else if (e.target == window) {
|
|
||||||
wmi.storeU32(off(4), 2);
|
|
||||||
} else {
|
|
||||||
wmi.storeU32(off(4), 0);
|
|
||||||
}
|
|
||||||
if (e.currentTarget == document) {
|
|
||||||
wmi.storeU32(off(4), 1);
|
|
||||||
} else if (e.currentTarget == window) {
|
|
||||||
wmi.storeU32(off(4), 2);
|
|
||||||
} else {
|
|
||||||
wmi.storeU32(off(4), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
wmi.storeUint(off(W), event_temp_data.id_ptr);
|
|
||||||
wmi.storeUint(off(W), event_temp_data.id_len);
|
|
||||||
|
|
||||||
wmi.storeF64(off(8), e.timeStamp*1e-3);
|
|
||||||
|
|
||||||
wmi.storeU8(off(1), e.eventPhase);
|
|
||||||
wmi.storeU8(off(1), !!e.bubbles);
|
|
||||||
wmi.storeU8(off(1), !!e.cancelable);
|
|
||||||
wmi.storeU8(off(1), !!e.composed);
|
|
||||||
wmi.storeU8(off(1), !!e.isComposing);
|
|
||||||
wmi.storeU8(off(1), !!e.isTrusted);
|
|
||||||
|
|
||||||
let base = off(0, 8);
|
|
||||||
if (e instanceof MouseEvent) {
|
|
||||||
wmi.storeI64(off(8), e.screenX);
|
|
||||||
wmi.storeI64(off(8), e.screenY);
|
|
||||||
wmi.storeI64(off(8), e.clientX);
|
|
||||||
wmi.storeI64(off(8), e.clientY);
|
|
||||||
wmi.storeI64(off(8), e.offsetX);
|
|
||||||
wmi.storeI64(off(8), e.offsetY);
|
|
||||||
wmi.storeI64(off(8), e.pageX);
|
|
||||||
wmi.storeI64(off(8), e.pageY);
|
|
||||||
wmi.storeI64(off(8), e.movementX);
|
|
||||||
wmi.storeI64(off(8), e.movementY);
|
|
||||||
|
|
||||||
wmi.storeU8(off(1), !!e.ctrlKey);
|
|
||||||
wmi.storeU8(off(1), !!e.shiftKey);
|
|
||||||
wmi.storeU8(off(1), !!e.altKey);
|
|
||||||
wmi.storeU8(off(1), !!e.metaKey);
|
|
||||||
|
|
||||||
wmi.storeI16(off(2), e.button);
|
|
||||||
wmi.storeU16(off(2), e.buttons);
|
|
||||||
} else if (e instanceof KeyboardEvent) {
|
|
||||||
let keyOffset = off(W*2, W);
|
|
||||||
let codeOffet = off(W*2, W);
|
|
||||||
wmi.storeU8(off(1), e.location);
|
|
||||||
|
|
||||||
wmi.storeU8(off(1), !!e.ctrlKey);
|
|
||||||
wmi.storeU8(off(1), !!e.shiftKey);
|
|
||||||
wmi.storeU8(off(1), !!e.altKey);
|
|
||||||
wmi.storeU8(off(1), !!e.metaKey);
|
|
||||||
|
|
||||||
wmi.storeU8(off(1), !!e.repeat);
|
|
||||||
} else if (e instanceof WheelEvent) {
|
|
||||||
wmi.storeF64(off(8), e.deltaX);
|
|
||||||
wmi.storeF64(off(8), e.deltaY);
|
|
||||||
wmi.storeF64(off(8), e.deltaZ);
|
|
||||||
wmi.storeU32(off(4), e.deltaMode);
|
|
||||||
} else if (e instanceof Event) {
|
|
||||||
if ('scrollX' in e) {
|
|
||||||
wmi.storeF64(off(8), e.scrollX);
|
|
||||||
wmi.storeF64(off(8), e.scrollY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
add_event_listener: (id_ptr, id_len, name_ptr, name_len, name_code, data, callback, use_capture) => {
|
|
||||||
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
|
||||||
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
|
||||||
let element = document.getElementById(id);
|
|
||||||
if (element == undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let listener = (e) => {
|
|
||||||
const odin_ctx = wasmMemoryInterface.exports.default_context_ptr();
|
|
||||||
event_temp_data.id_ptr = id_ptr;
|
|
||||||
event_temp_data.id_len = id_len;
|
|
||||||
event_temp_data.event = e;
|
|
||||||
event_temp_data.name_code = name_code;
|
|
||||||
// console.log(e);
|
|
||||||
wasmMemoryInterface.exports.odin_dom_do_event_callback(data, callback, odin_ctx);
|
|
||||||
};
|
|
||||||
wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener;
|
|
||||||
element.addEventListener(name, listener, !!use_capture);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
remove_event_listener: (id_ptr, id_len, name_ptr, name_len, data, callback) => {
|
|
||||||
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
|
||||||
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
|
||||||
let element = document.getElementById(id);
|
|
||||||
if (element == undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let listener = wasmMemoryInterface.listenerMap[{data: data, callback: callback}];
|
|
||||||
if (listener == undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
element.removeEventListener(name, listener);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
add_window_event_listener: (name_ptr, name_len, name_code, data, callback, use_capture) => {
|
|
||||||
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
|
||||||
let element = window;
|
|
||||||
let listener = (e) => {
|
|
||||||
const odin_ctx = wasmMemoryInterface.exports.default_context_ptr();
|
|
||||||
event_temp_data.id_ptr = 0;
|
|
||||||
event_temp_data.id_len = 0;
|
|
||||||
event_temp_data.event = e;
|
|
||||||
event_temp_data.name_code = name_code;
|
|
||||||
// console.log(e);
|
|
||||||
wasmMemoryInterface.exports.odin_dom_do_event_callback(data, callback, odin_ctx);
|
|
||||||
};
|
|
||||||
wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener;
|
|
||||||
element.addEventListener(name, listener, !!use_capture);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
remove_window_event_listener: (name_ptr, name_len, data, callback) => {
|
|
||||||
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
|
||||||
let element = window;
|
|
||||||
let listener = wasmMemoryInterface.listenerMap[{data: data, callback: callback}];
|
|
||||||
if (listener == undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
element.removeEventListener(name, listener);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
event_stop_propagation: () => {
|
|
||||||
if (event_temp_data && event_temp_data.event) {
|
|
||||||
event_temp_data.event.eventStopPropagation();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event_stop_immediate_propagation: () => {
|
|
||||||
if (event_temp_data && event_temp_data.event) {
|
|
||||||
event_temp_data.event.eventStopImmediatePropagation();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event_prevent_default: () => {
|
|
||||||
if (event_temp_data && event_temp_data.event) {
|
|
||||||
event_temp_data.event.eventPreventDefault();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get_element_value_f64: (id_ptr, id_len) => {
|
|
||||||
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
|
||||||
let element = document.getElementById(id);
|
|
||||||
return element ? element.value : 0;
|
|
||||||
},
|
|
||||||
get_element_value_string: (id_ptr, id_len, buf_ptr, buf_len) => {
|
|
||||||
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
|
||||||
let element = document.getElementById(id);
|
|
||||||
if (element) {
|
|
||||||
let str = element.value;
|
|
||||||
if (buf_len > 0 && buf_ptr) {
|
|
||||||
let n = Math.min(buf_len, str.length);
|
|
||||||
str = str.substring(0, n);
|
|
||||||
this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(str))
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
get_element_min_max: (ptr_array2_f64, id_ptr, id_len) => {
|
|
||||||
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
|
||||||
let element = document.getElementById(id);
|
|
||||||
if (element) {
|
|
||||||
let values = wasmMemoryInterface.loadF64Array(ptr_array2_f64, 2);
|
|
||||||
values[0] = element.min;
|
|
||||||
values[1] = element.max;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set_element_value: (id_ptr, id_len, value) => {
|
|
||||||
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
|
||||||
let element = document.getElementById(id);
|
|
||||||
if (element) {
|
|
||||||
element.value = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class WebGLInterface {
|
class WebGLInterface {
|
||||||
constructor(wasmMemoryInterface, canvasElement, contextSettings) {
|
constructor(wasmMemoryInterface) {
|
||||||
this.wasmMemoryInterface = wasmMemoryInterface;
|
this.wasmMemoryInterface = wasmMemoryInterface;
|
||||||
this.ctxElement = null;
|
this.ctxElement = null;
|
||||||
this.ctx = null;
|
this.ctx = null;
|
||||||
@@ -400,8 +117,6 @@ class WebGLInterface {
|
|||||||
this.transformFeedbacks = [];
|
this.transformFeedbacks = [];
|
||||||
this.syncs = [];
|
this.syncs = [];
|
||||||
this.programInfos = {};
|
this.programInfos = {};
|
||||||
|
|
||||||
this.setCurrentContext(canvasElement, contextSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get mem() {
|
get mem() {
|
||||||
@@ -1457,4 +1172,346 @@ class WebGLInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export {WasmMemoryInterface, odinSetupDefaultImports, WebGLInterface};
|
|
||||||
|
function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
|
||||||
|
const MAX_INFO_CONSOLE_LINES = 512;
|
||||||
|
let infoConsoleLines = new Array();
|
||||||
|
const addConsoleLine = (line) => {
|
||||||
|
if (!line) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (line.endsWith("\n")) {
|
||||||
|
line = line.substring(0, line.length-1);
|
||||||
|
} else if (infoConsoleLines.length > 0) {
|
||||||
|
let prev_line = infoConsoleLines.pop();
|
||||||
|
line = prev_line.concat(line);
|
||||||
|
}
|
||||||
|
infoConsoleLines.push(line);
|
||||||
|
|
||||||
|
if (infoConsoleLines.length > MAX_INFO_CONSOLE_LINES) {
|
||||||
|
infoConsoleLines.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = "";
|
||||||
|
for (let i = 0; i < infoConsoleLines.length; i++) {
|
||||||
|
if (i != 0) {
|
||||||
|
data = data.concat("\n");
|
||||||
|
}
|
||||||
|
data = data.concat(infoConsoleLines[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consoleElement) {
|
||||||
|
let info = consoleElement;
|
||||||
|
info.innerHTML = data;
|
||||||
|
info.scrollTop = info.scrollHeight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let event_temp_data = {};
|
||||||
|
|
||||||
|
let webglContext = new WebGLInterface(wasmMemoryInterface);
|
||||||
|
return {
|
||||||
|
"env": {},
|
||||||
|
"odin_env": {
|
||||||
|
write: (fd, ptr, len) => {
|
||||||
|
const str = wasmMemoryInterface.loadString(ptr, len);
|
||||||
|
if (fd == 1) {
|
||||||
|
addConsoleLine(str);
|
||||||
|
return;
|
||||||
|
} else if (fd == 2) {
|
||||||
|
addConsoleLine(str);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
throw new Error("Invalid fd to 'write'" + stripNewline(str));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trap: () => { throw new Error() },
|
||||||
|
alert: (ptr, len) => { alert(wasmMemoryInterface.loadString(ptr, len)) },
|
||||||
|
abort: () => { Module.abort() },
|
||||||
|
evaluate: (str_ptr, str_len) => { eval.call(null, wasmMemoryInterface.loadString(str_ptr, str_len)); },
|
||||||
|
|
||||||
|
time_now: () => {
|
||||||
|
return performance.now() * 1e6;
|
||||||
|
},
|
||||||
|
|
||||||
|
sqrt: (x) => Math.sqrt(x),
|
||||||
|
sin: (x) => Math.sin(x),
|
||||||
|
cos: (x) => Math.cos(x),
|
||||||
|
pow: (x) => Math.pow(x),
|
||||||
|
fmuladd: (x, y, z) => x*y + z,
|
||||||
|
ln: (x) => Math.log(x),
|
||||||
|
exp: (x) => Math.exp(x),
|
||||||
|
ldexp: (x) => Math.ldexp(x),
|
||||||
|
},
|
||||||
|
"odin_dom": {
|
||||||
|
init_event_raw: (ep) => {
|
||||||
|
const W = 4;
|
||||||
|
let offset = ep;
|
||||||
|
let off = (amount, alignment) => {
|
||||||
|
if (alignment === undefined) {
|
||||||
|
alignment = Math.min(amount, W);
|
||||||
|
}
|
||||||
|
if (offset % alignment != 0) {
|
||||||
|
offset += alignment - (offset%alignment);
|
||||||
|
}
|
||||||
|
let x = offset;
|
||||||
|
offset += amount;
|
||||||
|
return x;
|
||||||
|
};
|
||||||
|
|
||||||
|
let wmi = wasmMemoryInterface;
|
||||||
|
|
||||||
|
let e = event_temp_data.event;
|
||||||
|
|
||||||
|
wmi.storeU32(off(4), event_temp_data.name_code);
|
||||||
|
if (e.target == document) {
|
||||||
|
wmi.storeU32(off(4), 1);
|
||||||
|
} else if (e.target == window) {
|
||||||
|
wmi.storeU32(off(4), 2);
|
||||||
|
} else {
|
||||||
|
wmi.storeU32(off(4), 0);
|
||||||
|
}
|
||||||
|
if (e.currentTarget == document) {
|
||||||
|
wmi.storeU32(off(4), 1);
|
||||||
|
} else if (e.currentTarget == window) {
|
||||||
|
wmi.storeU32(off(4), 2);
|
||||||
|
} else {
|
||||||
|
wmi.storeU32(off(4), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wmi.storeUint(off(W), event_temp_data.id_ptr);
|
||||||
|
wmi.storeUint(off(W), event_temp_data.id_len);
|
||||||
|
|
||||||
|
wmi.storeF64(off(8), e.timeStamp*1e-3);
|
||||||
|
|
||||||
|
wmi.storeU8(off(1), e.eventPhase);
|
||||||
|
wmi.storeU8(off(1), !!e.bubbles);
|
||||||
|
wmi.storeU8(off(1), !!e.cancelable);
|
||||||
|
wmi.storeU8(off(1), !!e.composed);
|
||||||
|
wmi.storeU8(off(1), !!e.isComposing);
|
||||||
|
wmi.storeU8(off(1), !!e.isTrusted);
|
||||||
|
|
||||||
|
let base = off(0, 8);
|
||||||
|
if (e instanceof MouseEvent) {
|
||||||
|
wmi.storeI64(off(8), e.screenX);
|
||||||
|
wmi.storeI64(off(8), e.screenY);
|
||||||
|
wmi.storeI64(off(8), e.clientX);
|
||||||
|
wmi.storeI64(off(8), e.clientY);
|
||||||
|
wmi.storeI64(off(8), e.offsetX);
|
||||||
|
wmi.storeI64(off(8), e.offsetY);
|
||||||
|
wmi.storeI64(off(8), e.pageX);
|
||||||
|
wmi.storeI64(off(8), e.pageY);
|
||||||
|
wmi.storeI64(off(8), e.movementX);
|
||||||
|
wmi.storeI64(off(8), e.movementY);
|
||||||
|
|
||||||
|
wmi.storeU8(off(1), !!e.ctrlKey);
|
||||||
|
wmi.storeU8(off(1), !!e.shiftKey);
|
||||||
|
wmi.storeU8(off(1), !!e.altKey);
|
||||||
|
wmi.storeU8(off(1), !!e.metaKey);
|
||||||
|
|
||||||
|
wmi.storeI16(off(2), e.button);
|
||||||
|
wmi.storeU16(off(2), e.buttons);
|
||||||
|
} else if (e instanceof KeyboardEvent) {
|
||||||
|
let keyOffset = off(W*2, W);
|
||||||
|
let codeOffet = off(W*2, W);
|
||||||
|
wmi.storeU8(off(1), e.location);
|
||||||
|
|
||||||
|
wmi.storeU8(off(1), !!e.ctrlKey);
|
||||||
|
wmi.storeU8(off(1), !!e.shiftKey);
|
||||||
|
wmi.storeU8(off(1), !!e.altKey);
|
||||||
|
wmi.storeU8(off(1), !!e.metaKey);
|
||||||
|
|
||||||
|
wmi.storeU8(off(1), !!e.repeat);
|
||||||
|
} else if (e instanceof WheelEvent) {
|
||||||
|
wmi.storeF64(off(8), e.deltaX);
|
||||||
|
wmi.storeF64(off(8), e.deltaY);
|
||||||
|
wmi.storeF64(off(8), e.deltaZ);
|
||||||
|
wmi.storeU32(off(4), e.deltaMode);
|
||||||
|
} else if (e instanceof Event) {
|
||||||
|
if ('scrollX' in e) {
|
||||||
|
wmi.storeF64(off(8), e.scrollX);
|
||||||
|
wmi.storeF64(off(8), e.scrollY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
add_event_listener: (id_ptr, id_len, name_ptr, name_len, name_code, data, callback, use_capture) => {
|
||||||
|
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
||||||
|
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
||||||
|
let element = document.getElementById(id);
|
||||||
|
if (element == undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let listener = (e) => {
|
||||||
|
const odin_ctx = wasmMemoryInterface.exports.default_context_ptr();
|
||||||
|
event_temp_data.id_ptr = id_ptr;
|
||||||
|
event_temp_data.id_len = id_len;
|
||||||
|
event_temp_data.event = e;
|
||||||
|
event_temp_data.name_code = name_code;
|
||||||
|
// console.log(e);
|
||||||
|
wasmMemoryInterface.exports.odin_dom_do_event_callback(data, callback, odin_ctx);
|
||||||
|
};
|
||||||
|
wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener;
|
||||||
|
element.addEventListener(name, listener, !!use_capture);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
remove_event_listener: (id_ptr, id_len, name_ptr, name_len, data, callback) => {
|
||||||
|
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
||||||
|
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
||||||
|
let element = document.getElementById(id);
|
||||||
|
if (element == undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let listener = wasmMemoryInterface.listenerMap[{data: data, callback: callback}];
|
||||||
|
if (listener == undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
element.removeEventListener(name, listener);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
add_window_event_listener: (name_ptr, name_len, name_code, data, callback, use_capture) => {
|
||||||
|
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
||||||
|
let element = window;
|
||||||
|
let listener = (e) => {
|
||||||
|
const odin_ctx = wasmMemoryInterface.exports.default_context_ptr();
|
||||||
|
event_temp_data.id_ptr = 0;
|
||||||
|
event_temp_data.id_len = 0;
|
||||||
|
event_temp_data.event = e;
|
||||||
|
event_temp_data.name_code = name_code;
|
||||||
|
// console.log(e);
|
||||||
|
wasmMemoryInterface.exports.odin_dom_do_event_callback(data, callback, odin_ctx);
|
||||||
|
};
|
||||||
|
wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener;
|
||||||
|
element.addEventListener(name, listener, !!use_capture);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
remove_window_event_listener: (name_ptr, name_len, data, callback) => {
|
||||||
|
let name = wasmMemoryInterface.loadString(name_ptr, name_len);
|
||||||
|
let element = window;
|
||||||
|
let listener = wasmMemoryInterface.listenerMap[{data: data, callback: callback}];
|
||||||
|
if (listener == undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
element.removeEventListener(name, listener);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
event_stop_propagation: () => {
|
||||||
|
if (event_temp_data && event_temp_data.event) {
|
||||||
|
event_temp_data.event.eventStopPropagation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
event_stop_immediate_propagation: () => {
|
||||||
|
if (event_temp_data && event_temp_data.event) {
|
||||||
|
event_temp_data.event.eventStopImmediatePropagation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
event_prevent_default: () => {
|
||||||
|
if (event_temp_data && event_temp_data.event) {
|
||||||
|
event_temp_data.event.eventPreventDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get_element_value_f64: (id_ptr, id_len) => {
|
||||||
|
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
||||||
|
let element = document.getElementById(id);
|
||||||
|
return element ? element.value : 0;
|
||||||
|
},
|
||||||
|
get_element_value_string: (id_ptr, id_len, buf_ptr, buf_len) => {
|
||||||
|
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
||||||
|
let element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
let str = element.value;
|
||||||
|
if (buf_len > 0 && buf_ptr) {
|
||||||
|
let n = Math.min(buf_len, str.length);
|
||||||
|
str = str.substring(0, n);
|
||||||
|
this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(str))
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
get_element_min_max: (ptr_array2_f64, id_ptr, id_len) => {
|
||||||
|
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
||||||
|
let element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
let values = wasmMemoryInterface.loadF64Array(ptr_array2_f64, 2);
|
||||||
|
values[0] = element.min;
|
||||||
|
values[1] = element.max;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set_element_value: (id_ptr, id_len, value) => {
|
||||||
|
let id = wasmMemoryInterface.loadString(id_ptr, id_len);
|
||||||
|
let element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
element.value = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"webgl": webglContext.getWebGL1Interface(),
|
||||||
|
"webgl2": webglContext.getWebGL2Interface(),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
async function runWasmCanvas(wasmPath, consoleElement, extraForeignImports) {
|
||||||
|
let wasmMemoryInterface = new WasmMemoryInterface();
|
||||||
|
|
||||||
|
let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement);
|
||||||
|
let exports = {};
|
||||||
|
|
||||||
|
if (extraForeignImports !== undefined) {
|
||||||
|
imports = {
|
||||||
|
...imports,
|
||||||
|
...extraForeignImports,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(wasmPath);
|
||||||
|
const file = await response.arrayBuffer();
|
||||||
|
const wasm = await WebAssembly.instantiate(file, imports);
|
||||||
|
exports = wasm.instance.exports;
|
||||||
|
wasmMemoryInterface.setExports(exports);
|
||||||
|
wasmMemoryInterface.setMemory(exports.memory);
|
||||||
|
|
||||||
|
exports._start();
|
||||||
|
|
||||||
|
if (exports.step) {
|
||||||
|
const odin_ctx = exports.default_context_ptr();
|
||||||
|
|
||||||
|
let prevTimeStamp = undefined;
|
||||||
|
const step = (currTimeStamp) => {
|
||||||
|
if (prevTimeStamp == undefined) {
|
||||||
|
prevTimeStamp = currTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dt = (currTimeStamp - prevTimeStamp)*0.001;
|
||||||
|
prevTimeStamp = currTimeStamp;
|
||||||
|
exports.step(dt, odin_ctx);
|
||||||
|
window.requestAnimationFrame(step);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.requestAnimationFrame(step);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports._end();
|
||||||
|
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.odin = {
|
||||||
|
// Interface Types
|
||||||
|
WasmMemoryInterface: WasmMemoryInterface,
|
||||||
|
WebGLInterface: WebGLInterface,
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
setupDefaultImports: odinSetupDefaultImports,
|
||||||
|
runWasmCanvas: runWasmCanvas,
|
||||||
|
};
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user