diff --git a/examples/call_odin.odin b/examples/call_odin.odin
index 7ecd77c..e3c2009 100644
--- a/examples/call_odin.odin
+++ b/examples/call_odin.odin
@@ -32,6 +32,8 @@ DOC :: `
+
+
Call an Odin function that returns a response
Double:
@@ -49,8 +51,10 @@ DOC :: `
// JavaScript: `webui.handleStr('Hello', 'World');`
handle_string :: proc "c" (e: ^ui.Event) {
context = runtime.default_context()
- str1 := ui.get_arg(string, e)
- str2 := ui.get_arg(string, e, 1)
+ str1, _ := ui.get_arg(string, e)
+ str2, _ := ui.get_arg(string, e, 1)
+ _, err := ui.get_arg(string, e, 3)
+ assert(err == .No_Argument)
fmt.println("handle_string 1:", str1) // Hello
fmt.println("handle_string 2:", str2) // World
@@ -59,9 +63,9 @@ handle_string :: proc "c" (e: ^ui.Event) {
// JavaScript: `webui.handleInt(123, 456, 789);`
handle_int :: proc "c" (e: ^ui.Event) {
context = runtime.default_context()
- num1 := ui.get_arg(int, e)
- num2 := ui.get_arg(int, e, 1)
- num3 := ui.get_arg(int, e, 2)
+ num1, _ := ui.get_arg(int, e)
+ num2, _ := ui.get_arg(int, e, 1)
+ num3, _ := ui.get_arg(int, e, 2)
fmt.println("handle_int 1:", num1) // 123
fmt.println("handle_int 2:", num2) // 456
@@ -71,17 +75,36 @@ handle_int :: proc "c" (e: ^ui.Event) {
// JavaScript: webui.handleBool(true, false);
handle_bool :: proc "c" (e: ^ui.Event) {
context = runtime.default_context()
- status1 := ui.get_arg(bool, e)
- status2 := ui.get_arg(bool, e, 1)
+ status1, _ := ui.get_arg(bool, e)
+ status2, _ := ui.get_arg(bool, e, 1)
fmt.println("handle_bool 1:", status1) // true
fmt.println("handle_bool 2:", status2) // false
}
+// JavaScript: webui.handleObj(JSON.stringify({ name: 'Bob', age: 30 }), JSON.stringify({ email: 'test@webui.dev', hash: 'abc' }));
+handle_struct :: proc "c" (e: ^ui.Event) {
+ context = runtime.default_context()
+ Person :: struct {
+ name: string,
+ age: int,
+ }
+ struct1, _ := ui.get_arg(Person, e)
+ struct2, err := ui.get_arg(struct {
+ email, hash: string,
+ }, e, 1)
+ if err != nil {
+ fmt.println("Failed to get arg: ", err)
+ }
+
+ fmt.println("handle_struct 1:", struct1)
+ fmt.println("handle_struct 2:", struct2)
+}
+
// JavaScript: `const result = await webui.getResponse(number);`
get_response :: proc "c" (e: ^ui.Event) {
context = runtime.default_context()
- num := ui.get_arg(int, e)
+ num, _ := ui.get_arg(int, e)
resp := num * 2
fmt.println("handle_response:", resp)
@@ -98,6 +121,7 @@ main :: proc() {
ui.bind(w, "handleStr", handle_string)
ui.bind(w, "handleInt", handle_int)
ui.bind(w, "handleBool", handle_bool)
+ ui.bind(w, "handleObj", handle_struct)
ui.bind(w, "getResponse", get_response)
// Show the HTML UI.
diff --git a/webui.odin b/webui.odin
index 0942c4c..d54ac60 100644
--- a/webui.odin
+++ b/webui.odin
@@ -3,6 +3,7 @@ package webui
import "base:intrinsics"
import "base:runtime"
import "core:c"
+import "core:encoding/json"
import "core:fmt"
import "core:strings"
import "core:time"
@@ -214,17 +215,28 @@ script :: proc(
return strings.string_from_ptr(buf, int(buffer_len)), .None
}
+GetArgError :: union {
+ enum {
+ None,
+ No_Argument,
+ },
+ json.Unmarshal_Error,
+}
+
// Parse a JS argument as Odin data type.
-get_arg :: proc($T: typeid, e: ^Event, idx: uint = 0) -> T {
+get_arg :: proc($T: typeid, e: ^Event, idx: uint = 0) -> (res: T, err: GetArgError) {
+ if get_size_at(e, idx) == 0 {
+ return res, .No_Argument
+ }
when intrinsics.type_is_numeric(T) {
- return auto_cast get_int_at(e, idx)
+ return auto_cast get_int_at(e, idx), nil
} else when T == string {
- return string(get_string_at(e, idx))
+ return string(get_string_at(e, idx)), nil
} else when T == bool {
- return get_bool_at(e, idx)
+ return get_bool_at(e, idx), nil
}
- // TODO: unmarshal other types from JSON
- return {}
+ json.unmarshal_string(string(get_string_at(e, idx)), &res) or_return
+ return
}
// Return the response to JavaScript.