Changes
7 changed files (+158/-22)
-
-
@@ -50,6 +50,7 @@ pub const App = struct {allocator: std.mem.Allocator, state: *State, app: *core.Application, connect_result: *core.Application.ConnectResult, pub const InitError = error{ ServerFindError,
-
@@ -111,12 +112,25 @@ }} defer if (token) |tok| allocator.free(tok); const new_token = app.connect(if (token) |tok| tok.ptr else null) orelse { std.log.err("Unable to connect", .{}); const connect_result = app.connect(if (token) |tok| tok.ptr else null) orelse { std.log.err("Unable to allocate connection result struct: OOM", .{}); return std.mem.Allocator.Error.OutOfMemory; }; if (connect_result.code != .ok) { std.log.err( "Unable to connect to Roon server: {s}", .{@tagName(connect_result.code)}, ); return InitError.UnableToConnect; } const new_token = if (connect_result.token) |tok| tok[0..connect_result.token_len] else { std.log.err("Succesfully connected but got empty token", .{}); return InitError.UnableToConnect; }; state.putToken(inputs.core_id, std.mem.span(new_token)) catch |err| { state.putToken(inputs.core_id, new_token) catch |err| { std.log.err("Failed to save new token: {s}", .{@errorName(err)}); return err; };
-
@@ -130,6 +144,7 @@ return .{.allocator = allocator, .state = state, .app = app, .connect_result = connect_result, }; }
-
-
-
@@ -67,36 +67,99 @@ allocator.destroy(self);} } // TODO: Return status code AND token pub fn connect(self_ptr: ?*Application, token: ?[*:0]const u8) callconv(.C) ?[*:0]const u8 { var self = self_ptr orelse return null; pub const ConnectResultCode = enum(c_int) { ok = 0, unknown_error = 1, null_self_pointer = 2, out_of_memory = 3, registry_down = 4, failed_to_register = 5, websocket_connection_error = 6, listen_thread_spawn_error = 7, }; const conn = allocator.create(Connection) catch return null; conn.* = Connection.init(allocator, self.addr) catch { // TODO: Handle error return null; pub const ConnectResult = extern struct { code: ConnectResultCode, token: ?[*:0]const u8 = null, token_len: usize = 0, pub fn free(self_ptr: ?*ConnectResult) callconv(.C) void { const self = self_ptr orelse return; if (self.token) |token| { allocator.free(token[0..self.token_len]); } allocator.destroy(self); } }; /// Returns `null` when unable to allocate result struct. pub fn connect( self_ptr: ?*Application, saved_token: ?[*:0]const u8, ) callconv(.C) ?*ConnectResult { const result = allocator.create(ConnectResult) catch return null; const self = self_ptr orelse { result.* = .{ .code = .null_self_pointer, }; return result; }; self.connectInternal(saved_token, result) catch |err| { result.* = .{ .code = switch (err) { error.OutOfMemory => .out_of_memory, Connection.InitError.WebSocketClientCreationError, Connection.InitError.WebSocketHandshakeError => .websocket_connection_error, ConnectError.RegistryInfoError => .registry_down, ConnectError.RegistryRegisterError => .failed_to_register, ConnectError.ListeningThreadSpawnError => .listen_thread_spawn_error, else => .unknown_error, }, }; }; return result; } const ConnectError = error{ RegistryInfoError, RegistryRegisterError, ListeningThreadSpawnError, }; fn connectInternal( self: *Application, saved_token: ?[*:0]const u8, result: *ConnectResult, ) !void { const conn = try allocator.create(Connection); conn.* = try Connection.init(allocator, self.addr); errdefer conn.deinit(); conn.listen(PingService.handleRequest) catch { return null; return ConnectError.ListeningThreadSpawnError; }; std.log.debug("Querying registry status...", .{}); const info = RegistryService.info(allocator, conn) catch |err| { std.log.err("Failed to get extension registry status: {s}", .{@errorName(err)}); return null; return ConnectError.RegistryInfoError; }; defer info.deinit(); const extension = AppExtension{ .token = if (token) |tok| std.mem.span(tok) else null, .token = if (saved_token) |tok| std.mem.span(tok) else null, }; std.log.debug("Registering extension {s} token...", .{if (token) |_| "with" else "without"}); std.log.debug("Registering extension {s} token...", .{if (saved_token) |_| "with" else "without"}); const register = RegistryService.register(AppExtension, allocator, conn, extension) catch |err| { std.log.err("Failed to register extension: {s}", .{@errorName(err)}); return null; return ConnectError.RegistryRegisterError; }; defer register.deinit();
-
@@ -104,6 +167,12 @@ self.conn = conn;std.log.debug("Extension registered, application is ready", .{}); return allocator.dupeZ(u8, register.value.token) catch return null; const token = try allocator.dupeZ(u8, register.value.token); result.* = .{ .code = .ok, .token = token.ptr, .token_len = token.len, }; } };
-
-
-
@@ -97,6 +97,29 @@ void plac_server_scanner_free(plac_server_scanner*);plac_scan_result *plac_server_scanner_scan(plac_server_scanner*, plac_server_scan_options*); plac_find_result *plac_server_scanner_find(plac_server_scanner*, char * const, unsigned int); /* Application.ConnectResultCode */ typedef enum { PLAC_APPLICATION_CONNECT_OK = 0, PLAC_APPLICATION_CONNECT_UNKNOWN_ERROR = 1, PLAC_APPLICATION_CONNECT_NULL_SELF_POINTER = 2, PLAC_APPLICATION_CONNECT_OUT_OF_MEMORY = 3, PLAC_APPLICATION_CONNECT_REGISTRY_DOWN = 4, PLAC_APPLICATION_CONNECT_FAILED_TO_REGISTER = 5, PLAC_APPLICATION_CONNECT_WEBSOCKET_CONNECTION_ERROR = 6, PLAC_APPLICATION_CONNECT_LISTEN_THREAD_SPAWN_ERROR = 7, } plac_application_connect_result_code; /* Application.ConnectionResult */ typedef struct { plac_application_connect_result_code const code; char const * const token; unsigned int const token_len; } plac_application_connect_result; void plac_application_connect_result_free(plac_application_connect_result*); /* Application */ typedef struct { struct sockaddr __addr;
-
@@ -104,7 +127,7 @@ void *__conn;} plac_application; plac_application *plac_application_make_from_server(plac_server*); char *plac_application_connect(plac_application*, char*); plac_application_connect_result *plac_application_connect(plac_application*, char*); void plac_application_free(plac_application*); #endif
-
-
-
@@ -91,6 +91,25 @@ [CCode (cname = "plac_server_scanner_find")]public FindResult? find (string id, uint len); } [CCode (cname = "plac_application_connect_result_code", cprefix = "PLAC_APPLICATION_CONNECT_", has_type_id = false)] public enum ConnectResultCode { OK, UNKNOWN_ERROR, NULL_SELF_POINTER, OUT_OF_MEMORY, REGISTRY_DOWN, FAILED_TO_REGISTER, WEBSOCKET_CONNECTION_ERROR, LISTEN_THREAD_SPAWN_ERROR, } [CCode (cname = "plac_application_connect_result", free_function = "plac_application_connect_result_free")] [Compact] public class ConnectResult { public ConnectResultCode code; public string token; } [CCode (cname = "plac_application", free_function = "plac_application_free")] [Compact] public class CoreApp {
-
@@ -98,6 +117,6 @@ [CCode (cname = "plac_application_make_from_server")]public CoreApp (Server server); [CCode (cname = "plac_application_connect")] public string? connect (string? token); public ConnectResult? connect (string? token); } }
-
-
-
@@ -43,4 +43,5 @@@export(&Application.makeFromServer, .{ .name = "plac_application_make_from_server" }); @export(&Application.free, .{ .name = "plac_application_free" }); @export(&Application.connect, .{ .name = "plac_application_connect" }); @export(&Application.ConnectResult.free, .{ .name = "plac_application_connect_result_free" }); }
-
-
-
@@ -46,7 +46,6 @@ responses: ResponsesStore,responses_mutex: *std.Thread.Mutex, pub const InitError = error{ InvalidAddress, WebSocketClientCreationError, WebSocketHandshakeError, PRNGSeedGenerationFailure,
-
@@ -103,7 +102,7 @@ .thread_safe_allocator = tsa,}; } pub fn listen(self: *Connection, on_request: RequestHandler) !void { pub fn listen(self: *Connection, on_request: RequestHandler) std.Thread.SpawnError!void { std.log.debug("Spawning WebSocket request handler thread...", .{}); self.thread = try std.Thread.spawn(.{}, readLoop, .{ self, on_request }); }
-
-
-
@@ -247,8 +247,18 @@ test_label.label = this.server.name;this.app = new Plac.CoreApp(this.server); if (this.app != null) { var token = this.app.connect(null); stderr.printf("Got token: %s\n", token); var result = this.app.connect(null); if (result.code != Plac.ConnectResultCode.OK) { stderr.printf("Unable to connect (%d)\n", result.code); return; } if (result.token == null) { stderr.printf("Connected, but got null token\n"); return; } stderr.printf("Got token: %s\n", result.token); } } }
-