mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 04:38:16 +00:00
Move vendor:wasm/js to core:sys/wasm/js
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
# WASM on the Web
|
||||
|
||||
This directory is for use when targeting the `js_wasm32` target and the packages that rely on it.
|
||||
|
||||
The `js_wasm32` target assumes that the WASM output will be ran within a web browser rather than a standalone VM. In the VM cases, either `wasi_wasm32` or `freestanding_wasm32` should be used accordingly.
|
||||
|
||||
## Example for `js_wasm32`
|
||||
|
||||
```html
|
||||
<!-- Copy `core:sys/wasm/js/odin.js` into your web server -->
|
||||
<script type="text/javascript" src="odin.js"></script>
|
||||
<script type="text/javascript">
|
||||
odin.runWasm(pathToWasm, consolePreElement);
|
||||
</script>
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
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 ---
|
||||
set_element_value_f64 :: proc(id: string, value: f64) ---
|
||||
|
||||
get_element_key_f64 :: proc(id: string, key: string) -> f64 ---
|
||||
set_element_key_f64 :: proc(id: string, key: string, value: f64) ---
|
||||
|
||||
set_element_value_string :: proc(id: string, value: string) ---
|
||||
get_element_value_string_length :: proc(id: string) -> int ---
|
||||
|
||||
set_element_key_string :: proc(id: string, key: string, value: string) ---
|
||||
get_element_key_string_length :: proc(id: string, key: string, ) -> int ---
|
||||
|
||||
device_pixel_ratio :: proc() -> f64 ---
|
||||
|
||||
window_set_scroll :: proc(x, y: f64) ---
|
||||
}
|
||||
|
||||
get_element_value_string :: proc "contextless" (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])
|
||||
}
|
||||
|
||||
get_element_key_string :: proc "contextless" (id: string, key: string, buf: []byte) -> string {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_element_key_string")
|
||||
_get_element_key_string :: proc(id: string, key: string, buf: []byte) -> int ---
|
||||
}
|
||||
n := _get_element_key_string(id, key, buf)
|
||||
return string(buf[:n])
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
get_element_min_max :: proc "contextless" (id: string) -> (min, max: f64) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_element_min_max")
|
||||
_get_element_min_max :: proc(min_max: ^[2]f64, id: string) ---
|
||||
}
|
||||
min_max: [2]f64
|
||||
_get_element_min_max(&min_max, id)
|
||||
return min_max[0], min_max[1]
|
||||
}
|
||||
|
||||
|
||||
Rect :: struct {
|
||||
x, y, width, height: f64,
|
||||
}
|
||||
|
||||
get_bounding_client_rect :: proc "contextless" (id: string) -> (rect: Rect) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_bounding_client_rect")
|
||||
_get_bounding_client_rect :: proc(rect: ^Rect, id: string) ---
|
||||
}
|
||||
_get_bounding_client_rect(&rect, id)
|
||||
return
|
||||
}
|
||||
|
||||
window_get_rect :: proc "contextless" () -> (rect: Rect) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="window_get_rect")
|
||||
_window_get_rect :: proc(rect: ^Rect) ---
|
||||
}
|
||||
_window_get_rect(&rect)
|
||||
return
|
||||
}
|
||||
|
||||
window_get_scroll :: proc "contextless" () -> (x, y: f64) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="window_get_scroll")
|
||||
_window_get_scroll :: proc(scroll: ^[2]f64) ---
|
||||
}
|
||||
scroll: [2]f64
|
||||
_window_get_scroll(&scroll)
|
||||
return scroll.x, scroll.y
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#+build !js
|
||||
package wasm_js_interface
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
|
||||
get_element_value_string :: proc "contextless" (id: string, buf: []byte) -> string {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
|
||||
get_element_min_max :: proc "contextless" (id: string) -> (min, max: f64) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
|
||||
Rect :: struct {
|
||||
x, y, width, height: f64,
|
||||
}
|
||||
|
||||
get_bounding_client_rect :: proc "contextless" (id: string) -> (rect: Rect) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
window_get_rect :: proc "contextless" () -> (rect: Rect) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
window_get_scroll :: proc "contextless" () -> (x, y: f64) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
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,
|
||||
Focus_In,
|
||||
Focus_Out,
|
||||
Submit,
|
||||
Blur,
|
||||
Change,
|
||||
HashChange,
|
||||
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,
|
||||
|
||||
Context_Menu,
|
||||
|
||||
Custom,
|
||||
|
||||
}
|
||||
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",
|
||||
.Focus_In = "focusin",
|
||||
.Focus_Out = "focusout",
|
||||
.Submit = "submit",
|
||||
.Blur = "blur",
|
||||
.Change = "change",
|
||||
.HashChange = "hashchange",
|
||||
.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",
|
||||
|
||||
.Context_Menu = "contextmenu",
|
||||
|
||||
.Custom = "?custom?",
|
||||
}
|
||||
|
||||
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_Option :: enum u8 {
|
||||
Bubbles = 0,
|
||||
Cancelable = 1,
|
||||
Composed = 2,
|
||||
}
|
||||
Event_Options :: distinct bit_set[Event_Option; u8]
|
||||
|
||||
Event :: struct {
|
||||
kind: Event_Kind,
|
||||
target_kind: Event_Target_Kind,
|
||||
current_target_kind: Event_Target_Kind,
|
||||
id: string,
|
||||
timestamp: f64,
|
||||
|
||||
phase: Event_Phase,
|
||||
options: Event_Options,
|
||||
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_len: int `fmt:"-"`,
|
||||
_code_len: int `fmt:"-"`,
|
||||
_key_buf: [KEYBOARD_MAX_KEY_SIZE]byte `fmt:"-"`,
|
||||
_code_buf: [KEYBOARD_MAX_KEY_SIZE]byte `fmt:"-"`,
|
||||
},
|
||||
|
||||
mouse: struct {
|
||||
screen: [2]i64,
|
||||
client: [2]i64,
|
||||
offset: [2]i64,
|
||||
page: [2]i64,
|
||||
movement: [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() ---
|
||||
dispatch_custom_event :: proc(id: string, name: string, options := Event_Options{}) -> bool ---
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
add_custom_event_listener :: proc(id: string, name: string, 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 ---
|
||||
}
|
||||
return _add_event_listener(id, name, .Custom, user_data, callback, use_capture)
|
||||
}
|
||||
remove_custom_event_listener :: proc(id: string, name: string, 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, name, user_data, 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)
|
||||
|
||||
if event.kind == .Key_Up || event.kind == .Key_Down || event.kind == .Key_Press {
|
||||
event.key.key = string(event.key._key_buf[:event.key._key_len])
|
||||
event.key.code = string(event.key._code_buf[:event.key._code_len])
|
||||
}
|
||||
|
||||
callback(event)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
#+build !js
|
||||
package wasm_js_interface
|
||||
|
||||
|
||||
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,
|
||||
|
||||
Context_Menu,
|
||||
|
||||
Custom,
|
||||
|
||||
}
|
||||
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",
|
||||
|
||||
.Context_Menu = "contextmenu",
|
||||
|
||||
.Custom = "?custom?",
|
||||
}
|
||||
|
||||
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_Option :: enum u8 {
|
||||
Bubbles = 0,
|
||||
Cancelable = 1,
|
||||
Composed = 2,
|
||||
}
|
||||
Event_Options :: distinct bit_set[Event_Option; u8]
|
||||
|
||||
Event :: struct {
|
||||
kind: Event_Kind,
|
||||
target_kind: Event_Target_Kind,
|
||||
current_target_kind: Event_Target_Kind,
|
||||
id: string,
|
||||
timestamp: f64,
|
||||
|
||||
phase: Event_Phase,
|
||||
options: Event_Options,
|
||||
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,
|
||||
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
alt: bool,
|
||||
meta: bool,
|
||||
|
||||
button: i16,
|
||||
buttons: bit_set[0..<16; u16],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
user_data: rawptr,
|
||||
callback: proc(e: Event),
|
||||
}
|
||||
|
||||
|
||||
add_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
remove_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
add_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
remove_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
remove_event_listener_from_event :: proc(e: Event) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
add_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
remove_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import "odin_env"
|
||||
|
||||
@(default_calling_convention="contextless")
|
||||
foreign odin_env {
|
||||
trap :: proc() -> ! ---
|
||||
abort :: proc() -> ! ---
|
||||
alert :: proc(msg: string) ---
|
||||
evaluate :: proc(str: string) ---
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#+build !js
|
||||
package wasm_js_interface
|
||||
|
||||
import "core:mem"
|
||||
|
||||
PAGE_SIZE :: 64 * 1024
|
||||
page_alloc :: proc(page_count: int) -> (data: []byte, err: mem.Allocator_Error) {
|
||||
panic("vendor:wasm/js not supported on non-js targets")
|
||||
}
|
||||
|
||||
page_allocator :: proc() -> mem.Allocator {
|
||||
panic("vendor:wasm/js not supported on non-js targets")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
import "core:mem"
|
||||
import "base:intrinsics"
|
||||
|
||||
PAGE_SIZE :: 64 * 1024
|
||||
page_alloc :: proc(page_count: int) -> (data: []byte, err: mem.Allocator_Error) {
|
||||
prev_page_count := intrinsics.wasm_memory_grow(0, uintptr(page_count))
|
||||
if prev_page_count < 0 {
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
ptr := ([^]u8)(uintptr(prev_page_count) * PAGE_SIZE)
|
||||
return ptr[:page_count * PAGE_SIZE], nil
|
||||
}
|
||||
|
||||
page_allocator :: proc() -> mem.Allocator {
|
||||
procedure :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> ([]byte, mem.Allocator_Error) {
|
||||
switch mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
assert(size % PAGE_SIZE == 0)
|
||||
return page_alloc(size/PAGE_SIZE)
|
||||
case .Resize, .Free, .Free_All, .Query_Info, .Resize_Non_Zeroed:
|
||||
return nil, .Mode_Not_Implemented
|
||||
case .Query_Features:
|
||||
set := (^mem.Allocator_Mode_Set)(old_memory)
|
||||
if set != nil {
|
||||
set^ = {.Alloc, .Query_Features}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return {
|
||||
procedure = procedure,
|
||||
data = nil,
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user