Skip to content

Commit 5eca306

Browse files
committed
chore: add comment
1 parent 817e235 commit 5eca306

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

src/webui.zig

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,13 +732,32 @@ pub fn interfaceScriptClient(self: webui, event_number: usize, script_content: [
732732
if (!success) return WebUIError.ScriptError;
733733
}
734734

735-
/// a very convenient function for binding callback.
736-
/// you just need to pase a function to get param.
737-
/// no need to care webui param api.
735+
/// binding function: Creates a binding between an HTML element and a callback function
736+
/// - element: A null-terminated string identifying the HTML element(s) to bind to
737+
/// - callback: A function to be called when the bound event triggers
738+
///
739+
/// This function performs compile-time validation on the callback function to ensure it:
740+
/// 1. Is a proper function (not another type)
741+
/// 2. Returns void
742+
/// 3. Is not generic
743+
/// 4. Does not use variable arguments
744+
///
745+
/// The callback function can accept various parameter types:
746+
/// - Event: Gets the full event object
747+
/// - *Event: Gets a pointer to the event object
748+
/// - bool: Converted from event data
749+
/// - int types: Converted from event data
750+
/// - float types: Converted from event data
751+
/// - [:0]const u8: For null-terminated string data
752+
/// - [*]const u8: For raw pointer data
753+
///
754+
/// Returns:
755+
/// - The binding ID that can be used to unbind later
738756
pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !usize {
739757
const T = @TypeOf(callback);
740758
const TInfo = @typeInfo(T);
741759

760+
// Verify the callback is a function
742761
if (TInfo != .@"fn") {
743762
const err_msg = std.fmt.comptimePrint(
744763
"callback's type ({}), it must be a function!",
@@ -748,6 +767,7 @@ pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !
748767
}
749768

750769
const fnInfo = TInfo.@"fn";
770+
// Verify return type is void
751771
if (fnInfo.return_type != void) {
752772
const err_msg = std.fmt.comptimePrint(
753773
"callback's return type ({}), it must be void!",
@@ -756,6 +776,7 @@ pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !
756776
@compileError(err_msg);
757777
}
758778

779+
// Verify function is not generic
759780
if (fnInfo.is_generic) {
760781
const err_msg = std.fmt.comptimePrint(
761782
"callback's type ({}), it can not be a generic function!",
@@ -764,6 +785,7 @@ pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !
764785
@compileError(err_msg);
765786
}
766787

788+
// Verify function does not use varargs
767789
if (fnInfo.is_var_args) {
768790
const err_msg = std.fmt.comptimePrint(
769791
"callback's type ({}), it can not have variable args!",
@@ -775,14 +797,17 @@ pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !
775797
const tmp_struct = struct {
776798
const tup_t = fnParamsToTuple(fnInfo.params);
777799

800+
// Event handler that will convert parameters and call the user's callback
778801
fn handle(e: *Event) void {
779802
var param_tup: tup_t = undefined;
780803

781804
var index: usize = 0;
805+
// Process each parameter of the callback function
782806
inline for (fnInfo.params, 0..fnInfo.params.len) |param, i| {
783807
if (param.type) |tt| {
784808
const paramTInfo = @typeInfo(tt);
785809
switch (paramTInfo) {
810+
// Handle struct type parameters (only Event is allowed)
786811
.@"struct" => {
787812
if (tt == Event) {
788813
param_tup[i] = e.*;
@@ -795,29 +820,36 @@ pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !
795820
@compileError(err_msg);
796821
}
797822
},
823+
// Convert boolean values
798824
.bool => {
799825
const res = e.getBoolAt(i - index);
800826
param_tup[i] = res;
801827
},
828+
// Convert integer values with appropriate casting
802829
.int => {
803830
const res = e.getIntAt(i - index);
804831
param_tup[i] = @intCast(res);
805832
},
833+
// Convert floating point values
806834
.float => {
807835
const res = e.getFloatAt(i - index);
808836
param_tup[i] = res;
809837
},
838+
// Handle pointer types with special cases
810839
.pointer => |pointer| {
840+
// Handle null-terminated string slices
811841
if (pointer.size == .slice and pointer.child == u8 and pointer.is_const == true) {
812842
if (pointer.sentinel()) |sentinel| {
813843
if (sentinel == 0) {
814844
const str_ptr = e.getStringAt(i - index);
815845
param_tup[i] = str_ptr;
816846
}
817847
}
848+
// Handle Event pointers
818849
} else if (pointer.size == .one and pointer.child == Event) {
819850
param_tup[i] = e;
820851
index += 1;
852+
// Handle raw byte pointers
821853
} else if (pointer.size == .many and pointer.child == u8 and pointer.is_const == true and pointer.sentinel() == null) {
822854
const raw_ptr = e.getRawAt(i - index);
823855
param_tup[i] = raw_ptr;
@@ -829,6 +861,7 @@ pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !
829861
@compileError(err_msg);
830862
}
831863
},
864+
// Reject unsupported types
832865
else => {
833866
const err_msg = std.fmt.comptimePrint(
834867
"type is ({}), only support these types: Event, Bool, Int, Float, []u8!",
@@ -842,10 +875,12 @@ pub fn binding(self: webui, element: [:0]const u8, comptime callback: anytype) !
842875
}
843876
}
844877

878+
// Call the user's callback with the properly converted parameters
845879
@call(.auto, callback, param_tup);
846880
}
847881
};
848882

883+
// Create the actual binding with the webui backend
849884
return self.bind(element, tmp_struct.handle);
850885
}
851886

0 commit comments

Comments
 (0)