This commit is contained in:
John Smith 2022-09-09 16:27:13 -04:00
parent b13f8947df
commit 72b03939ef
10 changed files with 99 additions and 51 deletions

View file

@ -36,8 +36,8 @@ typedef _InitializeVeilidCoreDart = void Function(Pointer<Utf8>);
typedef _ChangeLogLevelC = Void Function(Pointer<Utf8>, Pointer<Utf8>);
typedef _ChangeLogLevelDart = void Function(Pointer<Utf8>, Pointer<Utf8>);
// fn startup_veilid_core(port: i64, config: FfiStr)
typedef _StartupVeilidCoreC = Void Function(Int64, Pointer<Utf8>);
typedef _StartupVeilidCoreDart = void Function(int, Pointer<Utf8>);
typedef _StartupVeilidCoreC = Void Function(Int64, Int64, Pointer<Utf8>);
typedef _StartupVeilidCoreDart = void Function(int, int, Pointer<Utf8>);
// fn get_veilid_state(port: i64)
typedef _GetVeilidStateC = Void Function(Int64);
typedef _GetVeilidStateDart = void Function(int);
@ -199,6 +199,51 @@ Future<void> processFutureVoid(Future<dynamic> future) {
});
}
Future<Stream<T>> processFutureStream<T>(
Stream<T> returnStream, Future<dynamic> future) {
return future.then((value) {
final list = value as List<dynamic>;
switch (list[0] as int) {
case messageOk:
{
if (list[1] != null) {
throw VeilidAPIExceptionInternal(
"Unexpected MESSAGE_OK value '${list[1]}' where null expected");
}
return returnStream;
}
case messageErr:
{
throw VeilidAPIExceptionInternal("Internal API Error: ${list[1]}");
}
case messageOkJson:
{
var ret = jsonDecode(list[1] as String);
if (ret != null) {
throw VeilidAPIExceptionInternal(
"Unexpected MESSAGE_OK_JSON value '$ret' where null expected");
}
return returnStream;
}
case messageErrJson:
{
throw VeilidAPIException.fromJson(jsonDecode(list[1] as String));
}
default:
{
throw VeilidAPIExceptionInternal(
"Unexpected async return message type: ${list[0]}");
}
}
}).catchError((e) {
// Wrap all other errors in VeilidAPIExceptionInternal
throw VeilidAPIExceptionInternal(e.toString());
}, test: (e) {
// Pass errors that are already VeilidAPIException through without wrapping
return e is! VeilidAPIException;
});
}
Stream<T> processStreamJson<T>(
T Function(Map<String, dynamic>) jsonConstructor, ReceivePort port) async* {
try {
@ -318,15 +363,20 @@ class VeilidFFI implements Veilid {
}
@override
Stream<VeilidUpdate> startupVeilidCore(VeilidConfig config) {
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) {
var nativeConfig =
jsonEncode(config.json, toEncodable: veilidApiToEncodable)
.toNativeUtf8();
final recvStreamPort = ReceivePort("veilid_api_stream");
final sendStreamPort = recvStreamPort.sendPort;
final recvPort = ReceivePort("startup_veilid_core");
final sendPort = recvPort.sendPort;
_startupVeilidCore(sendPort.nativePort, nativeConfig);
_startupVeilidCore(
sendPort.nativePort, sendStreamPort.nativePort, nativeConfig);
malloc.free(nativeConfig);
return processStreamJson(VeilidUpdate.fromJson, recvPort);
return processFutureStream(
processStreamJson(VeilidUpdate.fromJson, recvStreamPort),
recvPort.first);
}
@override