Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wrapping c errors as zig errors #16

Open
pfgithub opened this issue Dec 16, 2021 · 1 comment
Open

wrapping c errors as zig errors #16

pfgithub opened this issue Dec 16, 2021 · 1 comment

Comments

@pfgithub
Copy link

makeBuffer and many other make functions can return null

pub fn makeBuffer(desc: BufferDesc) Buffer {
    return sg_make_buffer(&desc);
}

pub fn makeBuffer(desc: BufferDesc) !Buffer {
    const res = sg_make_buffer(&desc);
    if(res.id == 0) return error.PoolExhausted;
    return res;
}

I think this could be done with a minor modification to gen_zig.py def gen_func_zig but I'm not sure if there's any way for it to know which functions to do this for or what field to check.

def gen_func_zig(decl, prefix):
    c_func_name = decl['name']
    zig_func_name = as_camel_case(check_name_override(decl['name']))
    zig_res_type = funcdecl_result_zig(decl, prefix)
+   can_error = decl['name'].startsWith("sg_make_")
    l(f"pub fn {zig_func_name}({funcdecl_args_zig(decl, prefix)}) {zig_res_type} {{")
+   if can_error:
+       s = f"    const res = {c_func_name}("
-   if zig_res_type != 'void':
+   elif zig_res_type != 'void':
        s = f"    return {c_func_name}("
    else:
        s = f"    {c_func_name}("
    for i, param_decl in enumerate(decl['params']):
        if i > 0:
            s += ", "
        arg_name = param_decl['name']
        arg_type = param_decl['type']
        if is_const_struct_ptr(arg_type):
            s += f"&{arg_name}"
        elif is_string_ptr(arg_type):
            s += f"@ptrCast([*c]const u8,{arg_name})"
        else:
            s += arg_name
    s += ");"
    l(s)
+   if can_error:
+       l("    if (res.id == 0) return error.PoolExhausted;")
+       l("    return res;")
    l("}")
@floooh
Copy link
Owner

floooh commented Dec 16, 2021

Yes makes sense, I'm hesitant to implement this though before getting a better idea of how to map certain "Zig-isms" to the language bindings wrapper. For instance another "obvious" change would be to accept a Zig allocator in the sg.setup() function, but this requires additional work on the C side so that allocation calls from C can be forwarded into the Zig allocator (a more dynamic allocator interface using callback functions is on my mental todo list).

In general, error handling in the Sokol headers by far isn't as strictly designed as it would be required for Zig's error handling approach, and in general I preferred "silently ignored errors", which also isn't quite compatible with Zig's philosophy. In some headers this is mostly fine, but in others the error feedback should be better (for instance in sokol_gl.h).

I'll keep the ticket open as reminder and maybe further discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants