I am writing a DLL that is intended to serve as a focal point for event handling for a server executable. The code is set up so that other DLLs loaded by this main one can add('bind') their own callbacks for a given event at runtime (so that people don't have to recompile everything if they want to add their own custom code to a server). I currently have the event handlers set up like this:
export const Status = extern struct {
default: bool = true,
custom: bool = true,
};
const OnServerInit_CallbackType = *const fn (Status) callconv(.C) Status;
const OnServerExit_CallbackType = *const fn (Status, bool) callconv(.C) Status;
var OnServerInit_callbacks: std.ArrayListUnmanaged(OnServerInit_CallbackType) = .{};
var OnServerExit_callbacks: std.ArrayListUnmanaged(OnServerExit_CallbackType) = .{};
pub export fn OnServerInit() void {
var status: Status = .{};
for (OnServerInit_callbacks.items) |cb| {
status = cb(status);
}
}
pub export fn bind_OnServerInit(callback: OnServerInit_CallbackType) void {
OnServerInit_callbacks.append(event_allocator, callback) catch |err| {
// print error message, exit
};
}
pub export fn OnServerExit(error_state: bool) void {
var status: Status = .{};
for (OnServerInit_callbacks.items) |cb| {
status = cb(status, error_state);
}
}
pub export fn bind_OnServerExit(callback: OnServerExit_CallbackType) void {
OnServerExit_callbacks.append(event_allocator, callback) catch |err| {
// print error message, exit
};
}
However, this is kind of unwieldy as I have to define the necessary parts for each event by hand. I would much prefer to wrap these in a helper function or two, but I'm not sure how the actual handler calls (and calls to callback functions) should be defined.