mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Begin work on Event System for js_wasm32 target
This commit is contained in:
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
//+build js wasm32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import dom_lib "odin_dom"
|
||||
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
get_element_value_f64 :: proc(id: string) -> f64 ---
|
||||
get_element_min_max :: proc(id: string) -> (min, max: f64) ---
|
||||
set_element_value :: proc(id: string, value: f64) ---
|
||||
}
|
||||
|
||||
get_element_value_string :: proc(id: string, buf: []byte) -> string {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_element_value_string")
|
||||
_get_element_value_string :: proc(id: string, buf: []byte) -> int ---
|
||||
}
|
||||
n := _get_element_value_string(id, buf)
|
||||
return string(buf[:n])
|
||||
|
||||
}
|
||||
Vendored
+320
@@ -0,0 +1,320 @@
|
||||
//+build js wasm32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import dom_lib "odin_dom"
|
||||
|
||||
Event_Kind :: enum u32 {
|
||||
Invalid,
|
||||
|
||||
Load,
|
||||
Unload,
|
||||
Error,
|
||||
Resize,
|
||||
Visibility_Change,
|
||||
Fullscreen_Change,
|
||||
Fullscreen_Error,
|
||||
|
||||
Click,
|
||||
Double_Click,
|
||||
Mouse_Move,
|
||||
Mouse_Over,
|
||||
Mouse_Out,
|
||||
Mouse_Up,
|
||||
Mouse_Down,
|
||||
|
||||
Key_Up,
|
||||
Key_Down,
|
||||
Key_Press,
|
||||
|
||||
Scroll,
|
||||
Wheel,
|
||||
|
||||
Focus,
|
||||
Submit,
|
||||
Blur,
|
||||
Change,
|
||||
Select,
|
||||
|
||||
Animation_Start,
|
||||
Animation_End,
|
||||
Animation_Iteration,
|
||||
Animation_Cancel,
|
||||
|
||||
Copy,
|
||||
Cut,
|
||||
Paste,
|
||||
|
||||
// Drag,
|
||||
// Drag_Start,
|
||||
// Drag_End,
|
||||
// Drag_Enter,
|
||||
// Drag_Leave,
|
||||
// Drag_Over,
|
||||
// Drop,
|
||||
|
||||
Pointer_Cancel,
|
||||
Pointer_Down,
|
||||
Pointer_Enter,
|
||||
Pointer_Leave,
|
||||
Pointer_Move,
|
||||
Pointer_Over,
|
||||
Pointer_Up,
|
||||
Got_Pointer_Capture,
|
||||
Lost_Pointer_Capture,
|
||||
Pointer_Lock_Change,
|
||||
Pointer_Lock_Error,
|
||||
|
||||
Selection_Change,
|
||||
Selection_Start,
|
||||
|
||||
Touch_Cancel,
|
||||
Touch_End,
|
||||
Touch_Move,
|
||||
Touch_Start,
|
||||
|
||||
Transition_Start,
|
||||
Transition_End,
|
||||
Transition_Run,
|
||||
Transition_Cancel,
|
||||
|
||||
}
|
||||
event_kind_string := [Event_Kind]string{
|
||||
.Invalid = "",
|
||||
|
||||
.Load = "load",
|
||||
.Unload = "unload",
|
||||
.Error = "error",
|
||||
.Resize = "resize",
|
||||
.Visibility_Change = "visibilitychange",
|
||||
.Fullscreen_Change = "fullscreenchange",
|
||||
.Fullscreen_Error = "fullscreenerror",
|
||||
|
||||
.Click = "click",
|
||||
.Double_Click = "dblclick",
|
||||
.Mouse_Move = "mousemove",
|
||||
.Mouse_Over = "mouseover",
|
||||
.Mouse_Out = "mouseout",
|
||||
.Mouse_Up = "mouseup",
|
||||
.Mouse_Down = "mousedown",
|
||||
|
||||
.Key_Up = "keyup",
|
||||
.Key_Down = "keydown",
|
||||
.Key_Press = "keypress",
|
||||
|
||||
.Scroll = "scroll",
|
||||
.Wheel = "wheel",
|
||||
|
||||
.Focus = "focus",
|
||||
.Submit = "submit",
|
||||
.Blur = "blur",
|
||||
.Change = "change",
|
||||
.Select = "select",
|
||||
|
||||
.Animation_Start = "animationstart",
|
||||
.Animation_End = "animationend",
|
||||
.Animation_Iteration = "animationiteration",
|
||||
.Animation_Cancel = "animationcancel",
|
||||
|
||||
.Copy = "copy",
|
||||
.Cut = "cut",
|
||||
.Paste = "paste",
|
||||
|
||||
// .Drag, = "drag",
|
||||
// .Drag_Start, = "dragstart",
|
||||
// .Drag_End, = "dragend",
|
||||
// .Drag_Enter, = "dragenter",
|
||||
// .Drag_Leave, = "dragleave",
|
||||
// .Drag_Over, = "dragover",
|
||||
// .Drop, = "drop",
|
||||
|
||||
.Pointer_Cancel = "pointercancel",
|
||||
.Pointer_Down = "pointerdown",
|
||||
.Pointer_Enter = "pointerenter",
|
||||
.Pointer_Leave = "pointerleave",
|
||||
.Pointer_Move = "pointermove",
|
||||
.Pointer_Over = "pointerover",
|
||||
.Pointer_Up = "pointerup",
|
||||
.Got_Pointer_Capture = "gotpointercapture",
|
||||
.Lost_Pointer_Capture = "lostpointercapture",
|
||||
.Pointer_Lock_Change = "pointerlockchange",
|
||||
.Pointer_Lock_Error = "pointerlockerror",
|
||||
|
||||
.Selection_Change = "selectionchange",
|
||||
.Selection_Start = "selectionstart",
|
||||
|
||||
.Transition_Start = "transitionstart",
|
||||
.Transition_End = "transitionend",
|
||||
.Transition_Run = "transitionrun",
|
||||
.Transition_Cancel = "transitioncancel",
|
||||
|
||||
.Touch_Cancel = "touchcancel",
|
||||
.Touch_End = "touchend",
|
||||
.Touch_Move = "touchmove",
|
||||
.Touch_Start = "touchstart",
|
||||
}
|
||||
|
||||
Delta_Mode :: enum u32 {
|
||||
Pixel = 0,
|
||||
Line = 1,
|
||||
Page = 2,
|
||||
}
|
||||
|
||||
Key_Location :: enum u8 {
|
||||
Standard = 0,
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
Numpad = 3,
|
||||
}
|
||||
|
||||
KEYBOARD_MAX_KEY_SIZE :: 16
|
||||
KEYBOARD_MAX_CODE_SIZE :: 16
|
||||
|
||||
Event_Target_Kind :: enum u32 {
|
||||
Element = 0,
|
||||
Document = 1,
|
||||
Window = 2,
|
||||
}
|
||||
|
||||
Event_Phase :: enum u8 {
|
||||
None = 0,
|
||||
Capturing_Phase = 1,
|
||||
At_Target = 2,
|
||||
Bubbling_Phase = 3,
|
||||
}
|
||||
|
||||
|
||||
Event :: struct {
|
||||
kind: Event_Kind,
|
||||
target_kind: Event_Target_Kind,
|
||||
current_target_kind: Event_Target_Kind,
|
||||
id: string,
|
||||
timestamp: f64,
|
||||
|
||||
phase: Event_Phase,
|
||||
bubbles: bool,
|
||||
cancelable: bool,
|
||||
composed: bool,
|
||||
is_composing: bool,
|
||||
is_trusted: bool,
|
||||
|
||||
using data: struct #raw_union #align 8 {
|
||||
scroll: struct {
|
||||
delta: [2]f64,
|
||||
},
|
||||
visibility_change: struct {
|
||||
is_visible: bool,
|
||||
},
|
||||
wheel: struct {
|
||||
delta: [3]f64,
|
||||
delta_mode: Delta_Mode,
|
||||
},
|
||||
|
||||
key: struct {
|
||||
key: string,
|
||||
code: string,
|
||||
location: Key_Location,
|
||||
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
alt: bool,
|
||||
meta: bool,
|
||||
|
||||
repeat: bool,
|
||||
|
||||
_key_buf: [KEYBOARD_MAX_KEY_SIZE]byte,
|
||||
_code_buf: [KEYBOARD_MAX_KEY_SIZE]byte,
|
||||
},
|
||||
|
||||
mouse: struct {
|
||||
screen: [2]i64,
|
||||
client: [2]i64,
|
||||
offset: [2]i64,
|
||||
page: [2]i64,
|
||||
movement: [2]i64,
|
||||
using pos: [2]i64,
|
||||
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
alt: bool,
|
||||
meta: bool,
|
||||
|
||||
button: i16,
|
||||
buttons: bit_set[0..<16; u16],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
user_data: rawptr,
|
||||
callback: proc(e: Event),
|
||||
}
|
||||
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
event_stop_propagation :: proc() ---
|
||||
event_stop_immediate_propagation :: proc() ---
|
||||
event_prevent_default :: proc() ---
|
||||
}
|
||||
|
||||
add_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="add_event_listener")
|
||||
_add_event_listener :: proc(id: string, name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
|
||||
}
|
||||
// TODO: Pointer_Lock_Change etc related stuff for all different browsers
|
||||
return _add_event_listener(id, event_kind_string[kind], kind, user_data, callback, use_capture)
|
||||
}
|
||||
|
||||
remove_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="remove_event_listener")
|
||||
_remove_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool ---
|
||||
}
|
||||
return _remove_event_listener(id, event_kind_string[kind], user_data, callback)
|
||||
}
|
||||
|
||||
add_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="add_window_event_listener")
|
||||
_add_window_event_listener :: proc(name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
|
||||
}
|
||||
return _add_window_event_listener(event_kind_string[kind], kind, user_data, callback, use_capture)
|
||||
}
|
||||
|
||||
remove_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="remove_window_event_listener")
|
||||
_remove_window_event_listener :: proc(name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool ---
|
||||
}
|
||||
return _remove_window_event_listener(event_kind_string[kind], user_data, callback)
|
||||
}
|
||||
|
||||
remove_event_listener_from_event :: proc(e: Event) -> bool {
|
||||
if e.id == "" {
|
||||
return remove_window_event_listener(e.kind, e.user_data, e.callback)
|
||||
}
|
||||
return remove_event_listener(e.id, e.kind, e.user_data, e.callback)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@(export, link_name="odin_dom_do_event_callback")
|
||||
do_event_callback :: proc(user_data: rawptr, callback: proc(e: Event)) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
init_event_raw :: proc(e: ^Event) ---
|
||||
}
|
||||
|
||||
if callback != nil {
|
||||
event := Event{
|
||||
user_data = user_data,
|
||||
callback = callback,
|
||||
}
|
||||
init_event_raw(&event)
|
||||
callback(event)
|
||||
}
|
||||
}
|
||||
Vendored
-154
@@ -1,154 +0,0 @@
|
||||
class WasmMemoryInterface {
|
||||
constructor() {
|
||||
this.memory = null;
|
||||
}
|
||||
|
||||
setMemory(memory) {
|
||||
this.memory = memory;
|
||||
}
|
||||
|
||||
get mem() {
|
||||
return new DataView(this.memory.buffer);
|
||||
}
|
||||
|
||||
|
||||
loadF32Array(addr, len) {
|
||||
let array = new Float32Array(this.memory.buffer, addr, len);
|
||||
return array;
|
||||
}
|
||||
loadU32Array(addr, len) {
|
||||
let array = new Uint32Array(this.memory.buffer, addr, len);
|
||||
return array;
|
||||
}
|
||||
loadI32Array(addr, len) {
|
||||
let array = new Int32Array(this.memory.buffer, addr, len);
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
loadU8(addr) { return this.mem.getUint8 (addr, true); }
|
||||
loadI8(addr) { return this.mem.getInt8 (addr, true); }
|
||||
loadU16(addr) { return this.mem.getUint16 (addr, true); }
|
||||
loadI16(addr) { return this.mem.getInt16 (addr, true); }
|
||||
loadU32(addr) { return this.mem.getUint32 (addr, true); }
|
||||
loadI32(addr) { return this.mem.getInt32 (addr, true); }
|
||||
loadU64(addr) {
|
||||
const lo = this.mem.getUint32(addr + 0, true);
|
||||
const hi = this.mem.getUint32(addr + 4, true);
|
||||
return lo + hi*4294967296;
|
||||
};
|
||||
loadI64(addr) {
|
||||
// TODO(bill): loadI64 correctly
|
||||
const lo = this.mem.getUint32(addr + 0, true);
|
||||
const hi = this.mem.getUint32(addr + 4, true);
|
||||
return lo + hi*4294967296;
|
||||
};
|
||||
loadF32(addr) { return this.mem.getFloat32(addr, true); }
|
||||
loadF64(addr) { return this.mem.getFloat64(addr, true); }
|
||||
loadInt(addr) { return this.mem.getInt32 (addr, true); }
|
||||
loadUint(addr) { return this.mem.getUint32 (addr, true); }
|
||||
|
||||
loadPtr(addr) { return this.loadUint(addr); }
|
||||
|
||||
loadBytes(ptr, len) {
|
||||
return new Uint8Array(this.memory.buffer, ptr, len);
|
||||
}
|
||||
|
||||
loadString(ptr, len) {
|
||||
const bytes = this.loadBytes(ptr, len);
|
||||
return new TextDecoder("utf-8").decode(bytes);
|
||||
}
|
||||
|
||||
storeU8(addr, value) { this.mem.setUint8 (addr, value, true); }
|
||||
storeI8(addr, value) { this.mem.setInt8 (addr, value, true); }
|
||||
storeU16(addr, value) { this.mem.setUint16 (addr, value, true); }
|
||||
storeI16(addr, value) { this.mem.setInt16 (addr, value, true); }
|
||||
storeU32(addr, value) { this.mem.setUint32 (addr, value, true); }
|
||||
storeI32(addr, value) { this.mem.setInt32 (addr, value, true); }
|
||||
storeU64(addr, value) {
|
||||
this.mem.setUint32(addr + 0, value, true);
|
||||
this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true);
|
||||
}
|
||||
storeI64(addr, value) {
|
||||
// TODO(bill): storeI64 correctly
|
||||
this.mem.setUint32(addr + 0, value, true);
|
||||
this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true);
|
||||
}
|
||||
storeF32(addr, value) { this.mem.setFloat32(addr, value, true); }
|
||||
storeF64(addr, value) { this.mem.setFloat64(addr, value, true); }
|
||||
storeInt(addr, value) { this.mem.setInt32 (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 === undefined) {
|
||||
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 !== undefined) {
|
||||
let info = consoleElement;
|
||||
info.innerHTML = data;
|
||||
info.scrollTop = info.scrollHeight;
|
||||
}
|
||||
};
|
||||
|
||||
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),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export {WasmMemoryInterface, odinSetupDefaultImports};
|
||||
Vendored
+372
@@ -0,0 +1,372 @@
|
||||
class WasmMemoryInterface {
|
||||
constructor() {
|
||||
this.memory = null;
|
||||
this.exports = null;
|
||||
}
|
||||
|
||||
setMemory(memory) {
|
||||
this.memory = memory;
|
||||
}
|
||||
|
||||
setExports(exports) {
|
||||
this.exports = exports;
|
||||
this.listenerMap = {};
|
||||
}
|
||||
|
||||
get mem() {
|
||||
return new DataView(this.memory.buffer);
|
||||
}
|
||||
|
||||
|
||||
loadF32Array(addr, len) {
|
||||
let array = new Float32Array(this.memory.buffer, addr, len);
|
||||
return array;
|
||||
}
|
||||
loadF64Array(addr, len) {
|
||||
let array = new Float64Array(this.memory.buffer, addr, len);
|
||||
return array;
|
||||
}
|
||||
loadU32Array(addr, len) {
|
||||
let array = new Uint32Array(this.memory.buffer, addr, len);
|
||||
return array;
|
||||
}
|
||||
loadI32Array(addr, len) {
|
||||
let array = new Int32Array(this.memory.buffer, addr, len);
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
loadU8(addr) { return this.mem.getUint8 (addr, true); }
|
||||
loadI8(addr) { return this.mem.getInt8 (addr, true); }
|
||||
loadU16(addr) { return this.mem.getUint16 (addr, true); }
|
||||
loadI16(addr) { return this.mem.getInt16 (addr, true); }
|
||||
loadU32(addr) { return this.mem.getUint32 (addr, true); }
|
||||
loadI32(addr) { return this.mem.getInt32 (addr, true); }
|
||||
loadU64(addr) {
|
||||
const lo = this.mem.getUint32(addr + 0, true);
|
||||
const hi = this.mem.getUint32(addr + 4, true);
|
||||
return lo + hi*4294967296;
|
||||
};
|
||||
loadI64(addr) {
|
||||
// TODO(bill): loadI64 correctly
|
||||
const lo = this.mem.getUint32(addr + 0, true);
|
||||
const hi = this.mem.getUint32(addr + 4, true);
|
||||
return lo + hi*4294967296;
|
||||
};
|
||||
loadF32(addr) { return this.mem.getFloat32(addr, true); }
|
||||
loadF64(addr) { return this.mem.getFloat64(addr, true); }
|
||||
loadInt(addr) { return this.mem.getInt32 (addr, true); }
|
||||
loadUint(addr) { return this.mem.getUint32 (addr, true); }
|
||||
|
||||
loadPtr(addr) { return this.loadUint(addr); }
|
||||
|
||||
loadBytes(ptr, len) {
|
||||
return new Uint8Array(this.memory.buffer, ptr, len);
|
||||
}
|
||||
|
||||
loadString(ptr, len) {
|
||||
const bytes = this.loadBytes(ptr, len);
|
||||
return new TextDecoder("utf-8").decode(bytes);
|
||||
}
|
||||
|
||||
storeU8(addr, value) { this.mem.setUint8 (addr, value, true); }
|
||||
storeI8(addr, value) { this.mem.setInt8 (addr, value, true); }
|
||||
storeU16(addr, value) { this.mem.setUint16 (addr, value, true); }
|
||||
storeI16(addr, value) { this.mem.setInt16 (addr, value, true); }
|
||||
storeU32(addr, value) { this.mem.setUint32 (addr, value, true); }
|
||||
storeI32(addr, value) { this.mem.setInt32 (addr, value, true); }
|
||||
storeU64(addr, value) {
|
||||
this.mem.setUint32(addr + 0, value, true);
|
||||
this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true);
|
||||
}
|
||||
storeI64(addr, value) {
|
||||
// TODO(bill): storeI64 correctly
|
||||
this.mem.setUint32(addr + 0, value, true);
|
||||
this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true);
|
||||
}
|
||||
storeF32(addr, value) { this.mem.setFloat32(addr, value, true); }
|
||||
storeF64(addr, value) { this.mem.setFloat64(addr, value, true); }
|
||||
storeInt(addr, value) { this.mem.setInt32 (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 === undefined) {
|
||||
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 !== undefined) {
|
||||
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 = amount;
|
||||
}
|
||||
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);
|
||||
|
||||
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.storeI64(off(8), e.x);
|
||||
wmi.storeI64(off(8), e.y);
|
||||
|
||||
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.value;
|
||||
},
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
document.getElementById(id).value = value;
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export {WasmMemoryInterface, odinSetupDefaultImports};
|
||||
Reference in New Issue
Block a user