use *Async methods from gomuks
Performance improvement due to not needing as many Isolates.
This commit is contained in:
parent
f5645db6ea
commit
e14ab3e708
3 changed files with 47 additions and 33 deletions
2
gomuks
2
gomuks
|
|
@ -1 +1 @@
|
||||||
Subproject commit ba82b6e31c87c99766a8366a72a9f07d643b323f
|
Subproject commit a65299d327e3a533e6c476b0450b09be91fbb827
|
||||||
|
|
@ -106,39 +106,50 @@ class ClientController extends AsyncNotifier<int> {
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calls gomuks with [data] as JSON, returning its decoded response.
|
||||||
Future<dynamic> callGomuksMethod(
|
Future<dynamic> callGomuksMethod(
|
||||||
Map<String, dynamic> data,
|
Map<String, dynamic> data,
|
||||||
FutureOr<GomuksResponse> Function(int handle, GomuksBorrowedBuffer data)
|
void Function(
|
||||||
callback,
|
int handle,
|
||||||
|
GomuksOwnedBuffer data,
|
||||||
|
Pointer<NativeFunction<Void Function(GomuksResponse)>> callback,
|
||||||
|
)
|
||||||
|
call,
|
||||||
) async {
|
) async {
|
||||||
final bufferPointer = data.toGomuksBufferPtr();
|
final handle = await future;
|
||||||
|
final buffer = data.toGomuksOwnedBuffer();
|
||||||
|
|
||||||
|
final completer = Completer<dynamic>();
|
||||||
|
late final NativeCallable<Void Function(GomuksResponse)> callable;
|
||||||
|
callable = .listener((GomuksResponse response) {
|
||||||
|
callable.close();
|
||||||
|
try {
|
||||||
|
final json = response.buf.toJsonAndFree();
|
||||||
|
|
||||||
|
if (response.command.cast<Utf8>().toDartString() == "error") {
|
||||||
|
throw GomuksException(json.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
completer.complete(json);
|
||||||
|
} catch (error, stackTrace) {
|
||||||
|
completer.completeError(error, stackTrace);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final handle = await future;
|
call(handle, buffer, callable.nativeFunction);
|
||||||
|
} catch (_) {
|
||||||
final response = await Isolate.run(
|
// gomuks never got the call, so it won't respond or free the buffer
|
||||||
() => callback(handle, bufferPointer.ref),
|
callable.close();
|
||||||
);
|
GomuksFreeBuffer(buffer);
|
||||||
|
rethrow;
|
||||||
final json = response.buf.toJsonAndFree();
|
|
||||||
|
|
||||||
if (response.command.cast<Utf8>().toDartString() == "error") {
|
|
||||||
throw GomuksException(json.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
} finally {
|
|
||||||
calloc
|
|
||||||
..free(bufferPointer.ref.base)
|
|
||||||
..free(bufferPointer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<PushNotification?> handlePush(Map<String, dynamic> data) async {
|
Future<PushNotification?> handlePush(Map<String, dynamic> data) async {
|
||||||
final response = await callGomuksMethod(
|
final response = await callGomuksMethod(data, GomuksHandlePushAsync);
|
||||||
data,
|
|
||||||
(handle, data) async => GomuksHandlePush(handle, data),
|
|
||||||
);
|
|
||||||
|
|
||||||
return response?["notification"] == null
|
return response?["notification"] == null
|
||||||
? null
|
? null
|
||||||
|
|
@ -148,11 +159,12 @@ class ClientController extends AsyncNotifier<int> {
|
||||||
Future<dynamic> _sendCommand(
|
Future<dynamic> _sendCommand(
|
||||||
String command, [
|
String command, [
|
||||||
Map<String, dynamic> data = const {},
|
Map<String, dynamic> data = const {},
|
||||||
]) => callGomuksMethod(data, (handle, data) {
|
]) => callGomuksMethod(data, (handle, data, callback) {
|
||||||
final commandPointer = command.toNativeUtf8().cast<Char>();
|
final commandPointer = command.toNativeUtf8().cast<Char>();
|
||||||
try {
|
try {
|
||||||
return GomuksSubmitCommand(handle, commandPointer, data);
|
GomuksSubmitCommandAsync(handle, commandPointer, data, callback);
|
||||||
} finally {
|
} finally {
|
||||||
|
// gomuks copies the command name before returning
|
||||||
calloc.free(commandPointer);
|
calloc.free(commandPointer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -19,19 +19,21 @@ extension GomuksOwnedBufferToX on GomuksOwnedBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension JsonToGomuksBuffer on Map<String, dynamic> {
|
extension JsonToGomuksBuffer on Map<String, dynamic> {
|
||||||
|
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<GomuksBorrowedBuffer> toGomuksBufferPtr() {
|
Pointer<GomuksBorrowedBuffer> toGomuksBufferPtr() {
|
||||||
final jsonString = json.encode(this);
|
final bytes = utf8.encode(json.encode(this));
|
||||||
final bytes = utf8.encode(jsonString);
|
|
||||||
|
|
||||||
final dataPtr = calloc<Uint8>(bytes.length);
|
final dataPtr = calloc<Uint8>(bytes.length);
|
||||||
dataPtr.asTypedList(bytes.length).setAll(0, bytes);
|
dataPtr.asTypedList(bytes.length).setAll(0, bytes);
|
||||||
|
|
||||||
final ptr = calloc<GomuksBorrowedBuffer>();
|
return calloc<GomuksBorrowedBuffer>()
|
||||||
|
..ref.base = dataPtr
|
||||||
ptr.ref
|
..ref.length = bytes.length;
|
||||||
..base = dataPtr
|
|
||||||
..length = bytes.length;
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue