mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-15 04:43:41 +00:00
feat: unify native API invocation with async callbacks (#1476)
This commit is contained in:
21 files changed
+1017
-184
No files matched your search
@@ -11,6 +11,7 @@ import 'task_event.dart';
|
||||
class LibgopeedChannel implements LibgopeedInterface {
|
||||
static const _channel = MethodChannel('gopeed.com/libgopeed');
|
||||
final _taskEvents = StreamController<TaskEvent>.broadcast();
|
||||
int _requestID = 0;
|
||||
|
||||
LibgopeedChannel() {
|
||||
_channel.setMethodCallHandler((call) async {
|
||||
@@ -50,7 +51,9 @@ class LibgopeedChannel implements LibgopeedInterface {
|
||||
|
||||
@override
|
||||
Future<String> invoke(String method, String path, {String query = '', String body = ''}) async {
|
||||
final requestID = _requestID++;
|
||||
final result = await _channel.invokeMethod<String>('invoke', {
|
||||
'requestID': requestID,
|
||||
'method': method,
|
||||
'path': path,
|
||||
'query': query,
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
import '../ffi/libgopeed_bind.dart';
|
||||
import '../ffi/libgopeed_worker.dart';
|
||||
import 'api_server_state.dart';
|
||||
import 'libgopeed_interface.dart';
|
||||
@@ -12,51 +8,22 @@ import 'start_config.dart';
|
||||
import 'task_event.dart';
|
||||
|
||||
class LibgopeedFFi implements LibgopeedInterface {
|
||||
late LibgopeedBind _libgopeed;
|
||||
LibgopeedFFi() {
|
||||
_worker.taskEvents.listen(_onTaskEvent, onError: _taskEvents.addError);
|
||||
}
|
||||
|
||||
final _taskEvents = StreamController<TaskEvent>.broadcast();
|
||||
final _worker = LibgopeedWorker();
|
||||
late final NativeCallable<Void Function(Pointer<Char>)> _taskEventCallback;
|
||||
|
||||
LibgopeedFFi(LibgopeedBind libgopeed) {
|
||||
_libgopeed = libgopeed;
|
||||
_taskEventCallback = NativeCallable<Void Function(Pointer<Char>)>.listener(_onTaskEvent);
|
||||
}
|
||||
|
||||
void _onTaskEvent(Pointer<Char> payload) {
|
||||
try {
|
||||
final decoded = jsonDecode(payload.cast<Utf8>().toDartString()) as Map<String, dynamic>;
|
||||
_taskEvents.add(TaskEvent.fromJson(decoded));
|
||||
} finally {
|
||||
_libgopeed.FreeCString(payload);
|
||||
}
|
||||
void _onTaskEvent(Map<String, dynamic> payload) {
|
||||
_taskEvents.add(TaskEvent.fromJson(payload));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> start(StartConfig cfg) {
|
||||
var completer = Completer<int>();
|
||||
final cfgPtr = jsonEncode(cfg).toNativeUtf8();
|
||||
try {
|
||||
final result = _libgopeed.Start(cfgPtr.cast());
|
||||
if (result.r1 != nullptr) {
|
||||
final message = result.r1.cast<Utf8>().toDartString();
|
||||
_libgopeed.FreeCString(result.r1);
|
||||
completer.completeError(Exception(message));
|
||||
} else {
|
||||
completer.complete(result.r0);
|
||||
}
|
||||
} finally {
|
||||
malloc.free(cfgPtr);
|
||||
}
|
||||
return completer.future;
|
||||
}
|
||||
Future<int> start(StartConfig cfg) => _worker.start(jsonEncode(cfg));
|
||||
|
||||
@override
|
||||
Future<void> stop() {
|
||||
var completer = Completer<void>();
|
||||
_libgopeed.Stop();
|
||||
completer.complete();
|
||||
return completer.future;
|
||||
}
|
||||
Future<void> stop() => _worker.stop();
|
||||
|
||||
Future<ApiServerOperationResult> _apiServerOperation(String operation) async {
|
||||
final payload = await _worker.apiServer(operation);
|
||||
@@ -77,33 +44,12 @@ class LibgopeedFFi implements LibgopeedInterface {
|
||||
|
||||
@override
|
||||
Future<String> invoke(String method, String path, {String query = '', String body = ''}) async {
|
||||
final methodPtr = method.toNativeUtf8();
|
||||
final pathPtr = path.toNativeUtf8();
|
||||
final queryPtr = query.toNativeUtf8();
|
||||
final bodyPtr = body.toNativeUtf8();
|
||||
Pointer<Char>? resultPtr;
|
||||
try {
|
||||
resultPtr = _libgopeed.Invoke(methodPtr.cast(), pathPtr.cast(), queryPtr.cast(), bodyPtr.cast());
|
||||
if (resultPtr == nullptr) {
|
||||
throw StateError('Gopeed Invoke returned a null response');
|
||||
}
|
||||
return resultPtr.cast<Utf8>().toDartString();
|
||||
} finally {
|
||||
malloc.free(methodPtr);
|
||||
malloc.free(pathPtr);
|
||||
malloc.free(queryPtr);
|
||||
malloc.free(bodyPtr);
|
||||
if (resultPtr != null && resultPtr != nullptr) {
|
||||
_libgopeed.FreeCString(resultPtr);
|
||||
}
|
||||
}
|
||||
return jsonEncode(await _worker.invoke(method, path, query, body));
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<TaskEvent> get taskEvents => _taskEvents.stream;
|
||||
|
||||
@override
|
||||
Future<void> subscribeTaskEvents(Set<TaskEventType> events) async {
|
||||
_libgopeed.SubscribeTaskEvents(events.mask, events.isEmpty ? 0 : _taskEventCallback.nativeFunction.address);
|
||||
}
|
||||
Future<void> subscribeTaskEvents(Set<TaskEventType> events) => _worker.subscribeTaskEvents(events.mask);
|
||||
}
|
||||
Reference in new issue
Block a user