From e14ab3e70851ae11d34f671b9a7fcc8692dd6d64 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 21 Oct 2026 22:57:26 -0400 Subject: [PATCH] use *Async methods from gomuks Performance improvement due to not needing as many Isolates. --- gomuks | 2 +- lib/controllers/client.dart | 64 ++++++++++++++--------- lib/helpers/extensions/gomuks_buffer.dart | 20 +++---- 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/gomuks b/gomuks index ba82b6e..a65299d 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit ba82b6e31c87c99766a8366a72a9f07d643b323f +Subproject commit a65299d327e3a533e6c476b0450b09be91fbb827 diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 78670ea..9aaa216 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -106,39 +106,50 @@ class ClientController extends AsyncNotifier { return handle; } + /// Calls gomuks with [data] as JSON, returning its decoded response. Future callGomuksMethod( Map data, - FutureOr Function(int handle, GomuksBorrowedBuffer data) - callback, + void Function( + int handle, + GomuksOwnedBuffer data, + Pointer> callback, + ) + call, ) async { - final bufferPointer = data.toGomuksBufferPtr(); + final handle = await future; + final buffer = data.toGomuksOwnedBuffer(); + + final completer = Completer(); + late final NativeCallable callable; + callable = .listener((GomuksResponse response) { + callable.close(); + try { + final json = response.buf.toJsonAndFree(); + + if (response.command.cast().toDartString() == "error") { + throw GomuksException(json.toString()); + } + + completer.complete(json); + } catch (error, stackTrace) { + completer.completeError(error, stackTrace); + } + }); try { - final handle = await future; - - final response = await Isolate.run( - () => callback(handle, bufferPointer.ref), - ); - - final json = response.buf.toJsonAndFree(); - - if (response.command.cast().toDartString() == "error") { - throw GomuksException(json.toString()); - } - - return json; - } finally { - calloc - ..free(bufferPointer.ref.base) - ..free(bufferPointer); + call(handle, buffer, callable.nativeFunction); + } catch (_) { + // gomuks never got the call, so it won't respond or free the buffer + callable.close(); + GomuksFreeBuffer(buffer); + rethrow; } + + return completer.future; } Future handlePush(Map data) async { - final response = await callGomuksMethod( - data, - (handle, data) async => GomuksHandlePush(handle, data), - ); + final response = await callGomuksMethod(data, GomuksHandlePushAsync); return response?["notification"] == null ? null @@ -148,11 +159,12 @@ class ClientController extends AsyncNotifier { Future _sendCommand( String command, [ Map data = const {}, - ]) => callGomuksMethod(data, (handle, data) { + ]) => callGomuksMethod(data, (handle, data, callback) { final commandPointer = command.toNativeUtf8().cast(); try { - return GomuksSubmitCommand(handle, commandPointer, data); + GomuksSubmitCommandAsync(handle, commandPointer, data, callback); } finally { + // gomuks copies the command name before returning calloc.free(commandPointer); } }); diff --git a/lib/helpers/extensions/gomuks_buffer.dart b/lib/helpers/extensions/gomuks_buffer.dart index 10a273a..57425be 100644 --- a/lib/helpers/extensions/gomuks_buffer.dart +++ b/lib/helpers/extensions/gomuks_buffer.dart @@ -19,19 +19,21 @@ extension GomuksOwnedBufferToX on GomuksOwnedBuffer { } extension JsonToGomuksBuffer on Map { + GomuksOwnedBuffer toGomuksOwnedBuffer() { + final bytes = utf8.encode(json.encode(this)); + final buffer = GomuksAllocBuffer(bytes.length); + buffer.base.asTypedList(bytes.length).setAll(0, bytes); + return buffer; + } + Pointer toGomuksBufferPtr() { - final jsonString = json.encode(this); - final bytes = utf8.encode(jsonString); + final bytes = utf8.encode(json.encode(this)); final dataPtr = calloc(bytes.length); dataPtr.asTypedList(bytes.length).setAll(0, bytes); - final ptr = calloc(); - - ptr.ref - ..base = dataPtr - ..length = bytes.length; - - return ptr; + return calloc() + ..ref.base = dataPtr + ..ref.length = bytes.length; } }