fix: ffi instance be singleton

This commit is contained in:
liwei committed 2024-12-02 23:14:10 +08:00
1 parent 91dfd78b77
commit 4b4c03fd90
18 files changed
+844 -5336

No files matched your search

+8 -19
View File
@@ -2,6 +2,7 @@
/* package github.com/GopeedLab/gopeed/bind/desktop */
#line 1 "cgo-builtin-export-prolog"
#include <stddef.h>
@@ -10,24 +11,19 @@
#define GO_CGO_EXPORT_PROLOGUE_H
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct {
const char *p;
ptrdiff_t n;
} _GoString_;
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#endif
/* Start of preamble from import "C" comments. */
#line 3 "main.go"
#include <stdlib.h>
#line 1 "cgo-generated-wrapper"
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
@@ -60,22 +56,15 @@ typedef double _Complex GoComplex128;
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void *) == 64 / 8 ? 1 : -1];
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
typedef void *GoMap;
typedef void *GoChan;
typedef struct {
void *t;
void *v;
} GoInterface;
typedef struct {
void *data;
GoInt len;
GoInt cap;
} GoSlice;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
@@ -85,8 +74,8 @@ typedef struct {
extern "C" {
#endif
extern __declspec(dllexport) char *Create(char *cfg);
extern __declspec(dllexport) char *Invoke(GoInt index, char *req);
extern __declspec(dllexport) char* Init(char* cfg);
extern __declspec(dllexport) char* Invoke(char* req);
#ifdef __cplusplus
}
@@ -33,9 +33,10 @@ import 'libgopeed_boot_base.dart';
LibgopeedBoot create() => LibgopeedBootNative();
class LibgopeedBootNative with LibgopeedBootBase implements LibgopeedBoot {
class LibgopeedBootNative
with LibgopeedBootBase
implements LibgopeedBoot, LibgopeedApi {
late LibgopeedAbi _libgopeedAbi;
late int _apiInstance;
late Dio _dio;
LibgopeedBootNative() {
@@ -69,8 +70,7 @@ class LibgopeedBootNative with LibgopeedBootBase implements LibgopeedBoot {
}
return jsonEncode(e);
}).toList());
final resp =
await _libgopeedAbi.invoke(_apiInstance, jsonEncode(invokeRequest));
final resp = await _libgopeedAbi.invoke(jsonEncode(invokeRequest));
final result =
Result<T>.fromJson(jsonDecode(resp), fromJsonT ??= (json) => null as T);
return handleResult(result);
@@ -78,87 +78,86 @@ class LibgopeedBootNative with LibgopeedBootBase implements LibgopeedBoot {
List<dynamic> _parseTaskFilter(TaskFilter? filter) {
if (filter == null) {
return [];
return [null];
}
return [filter];
}
@override
Future<void> init(StartConfig cfg) async {
final result = await _libgopeedAbi.create(jsonEncode(cfg.toJson()));
_apiInstance =
Result.fromJson(jsonDecode(result), (data) => data as int).data!;
Future<LibgopeedApi> init(StartConfig cfg) async {
await _libgopeedAbi.init(jsonEncode(cfg.toJson()));
_dio = createDio();
return this;
}
@override
Future<HttpListenResult> startHttp() async {
return _invoke<HttpListenResult>(
"startHttp", [], (json) => HttpListenResult.fromJson(json));
"StartHttp", [], (json) => HttpListenResult.fromJson(json));
}
@override
Future<void> stopHttp() async {
await _invoke<void>("stopHttp", [], null);
await _invoke<void>("StopHttp", [], null);
}
@override
Future<void> restartHttp() async {
await _invoke<void>("restartHttp", [], null);
await _invoke<void>("RestartHttp", [], null);
}
@override
Future<Info> info() async {
return _invoke<Info>("info", [], (json) => Info.fromJson(json));
return _invoke<Info>("Info", [], (json) => Info.fromJson(json));
}
@override
Future<ResolveResult> resolve(Request request) async {
return _invoke<ResolveResult>(
"resolve", [request], (json) => ResolveResult.fromJson(json));
"Resolve", [request], (json) => ResolveResult.fromJson(json));
}
@override
Future<String> createTask(CreateTask createTask) async {
return _invoke<String>(
"createTask", [createTask], (json) => json as String);
"CreateTask", [createTask], (json) => json as String);
}
@override
Future<String> createTaskBatch(CreateTaskBatch createTask) async {
return _invoke<String>(
"createTaskBatch", [createTask], (json) => json as String);
"CreateTaskBatch", [createTask], (json) => json as String);
}
@override
Future<void> pauseTask(String id) async {
await _invoke<void>("pauseTask", [id], null);
await _invoke<void>("PauseTask", [id], null);
}
@override
Future<void> pauseTasks(TaskFilter? filter) async {
await _invoke<void>("pauseTasks", _parseTaskFilter(filter), null);
await _invoke<void>("PauseTasks", _parseTaskFilter(filter), null);
}
@override
Future<void> continueTask(String id) async {
await _invoke<void>("continueTask", [id], null);
await _invoke<void>("ContinueTask", [id], null);
}
@override
Future<void> continueTasks(TaskFilter? filter) async {
await _invoke<void>("continueTasks", _parseTaskFilter(filter), null);
await _invoke<void>("ContinueTasks", _parseTaskFilter(filter), null);
}
@override
Future<void> deleteTask(String id, bool force) async {
await _invoke<void>("deleteTask", [id, force], null);
await _invoke<void>("DeleteTask", [id, force], null);
}
@override
Future<void> deleteTasks(TaskFilter? filter, bool force) async {
await _invoke<void>(
"deleteTasks",
"DeleteTasks",
_parseTaskFilter(filter).apply((it) {
it.add(force);
}),
@@ -167,40 +166,40 @@ class LibgopeedBootNative with LibgopeedBootBase implements LibgopeedBoot {
@override
Future<Task> getTask(String id) async {
return _invoke<Task>("getTask", [id], (json) => Task.fromJson(json));
return _invoke<Task>("GetTask", [id], (json) => Task.fromJson(json));
}
@override
Future<List<Task>> getTasks(TaskFilter? filter) async {
return _invoke<List<Task>>("getTasks", _parseTaskFilter(filter),
return _invoke<List<Task>>("GetTasks", _parseTaskFilter(filter),
(json) => json.map((e) => Task.fromJson(e)).toList());
}
@override
Future<Map<String, dynamic>> getTaskStats(String id) async {
return _invoke<Map<String, dynamic>>(
"getTaskStats", [id], (json) => json as Map<String, dynamic>);
"GetTaskStats", [id], (json) => json as Map<String, dynamic>);
}
@override
Future<DownloaderConfig> getConfig() async {
return _invoke<DownloaderConfig>(
"getConfig", [], (json) => DownloaderConfig.fromJson(json));
"GetConfig", [], (json) => DownloaderConfig.fromJson(json));
}
@override
Future<void> putConfig(DownloaderConfig config) async {
await _invoke<void>("putConfig", [config], null);
await _invoke<void>("PutConfig", [config], null);
}
@override
Future<void> installExtension(InstallExtension installExtension) async {
await _invoke<void>("installExtension", [installExtension], null);
await _invoke<void>("InstallExtension", [installExtension], null);
}
@override
Future<List<Extension>> getExtensions() async {
return _invoke<List<Extension>>("getExtensions", [],
return _invoke<List<Extension>>("GetExtensions", [],
(json) => json.map((e) => Extension.fromJson(e)).toList());
}
@@ -208,33 +207,35 @@ class LibgopeedBootNative with LibgopeedBootBase implements LibgopeedBoot {
Future<void> updateExtensionSettings(
String identity, UpdateExtensionSettings updateExtensionSettings) async {
await _invoke<void>(
"updateExtensionSettings", [identity, updateExtensionSettings], null);
"UpdateExtensionSettings", [identity, updateExtensionSettings], null);
}
@override
Future<void> switchExtension(
String identity, SwitchExtension switchExtension) async {}
String identity, SwitchExtension switchExtension) async {
await _invoke<void>("SwitchExtension", [identity, switchExtension], null);
}
@override
Future<void> deleteExtension(String identity) async {
await _invoke<void>("deleteExtension", [identity], null);
await _invoke<void>("DeleteExtension", [identity], null);
}
@override
Future<UpdateCheckExtensionResp> upgradeCheckExtension(
String identity) async {
return _invoke<UpdateCheckExtensionResp>("upgradeCheckExtension",
return _invoke<UpdateCheckExtensionResp>("UpgradeCheckExtension",
[identity], (json) => UpdateCheckExtensionResp.fromJson(json));
}
@override
Future<void> upgradeExtension(String identity) async {
await _invoke<void>("upgradeExtension", [identity], null);
await _invoke<void>("UpgradeExtension", [identity], null);
}
@override
Future<void> close() async {
await _invoke<void>("close", [], null);
await _invoke<void>("Close", [], null);
}
@override
@@ -20,12 +20,15 @@ import '../../util/extensions.dart';
import '../../util/util.dart';
import '../api_exception.dart';
import '../libgopeed_boot.dart';
import '../native/libgopeed_interface.dart';
import '../native/model/start_config.dart';
import 'libgopeed_boot_base.dart';
LibgopeedBoot create() => LibgopeedBootWeb();
class LibgopeedBootWeb with LibgopeedBootBase implements LibgopeedBoot {
class LibgopeedBootWeb
with LibgopeedBootBase
implements LibgopeedBoot, LibgopeedApi {
late Dio _dio;
static const String _apiPrefix = '/api/v1';
@@ -72,9 +75,10 @@ class LibgopeedBootWeb with LibgopeedBootBase implements LibgopeedBoot {
}
@override
Future<void> init(StartConfig cfg) async {
Future<LibgopeedApi> init(StartConfig cfg) async {
_dio = createDio();
_dio.options.baseUrl = kDebugMode ? 'http://127.0.0.1:9999' : '';
return this;
}
@override
+7 -4
View File
@@ -3,11 +3,14 @@ import "libgopeed_boot_stub.dart"
if (dart.library.io) 'entry/libgopeed_boot_native.dart';
import 'native/libgopeed_interface.dart';
abstract class LibgopeedBoot implements LibgopeedApi {
static LibgopeedBoot? _instance;
abstract class LibgopeedBoot implements LibgopeedApiSingleton {
static LibgopeedApi? _instance;
static LibgopeedBoot get instance {
_instance ??= LibgopeedBoot();
static void singleton(LibgopeedApi instance) {
_instance ??= instance;
}
static LibgopeedApi get instance {
return _instance!;
}
@@ -6,17 +6,15 @@ class LibgopeedChannel implements LibgopeedAbi {
static const _channel = MethodChannel('gopeed.com/libgopeed');
@override
Future<String> create(String cfg) async {
final result = await _channel.invokeMethod<String>('create', {
Future<void> init(String cfg) async {
await _channel.invokeMethod<String>('init', {
'cfg': cfg,
});
return result!;
}
@override
Future<String> invoke(int instance, String params) async {
Future<String> invoke(String params) async {
final result = await _channel.invokeMethod<String>('invoke', {
'instance': instance,
'params': params,
});
return result!;
File diff suppressed because it is too large. Load diff
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
@@ -13,21 +14,25 @@ class LibgopeedFFi implements LibgopeedAbi {
}
@override
Future<String> create(String cfg) {
Future<void> init(String cfg) {
final cfgPtr = cfg.toNativeUtf8();
try {
final result = _libgopeed.Create(cfgPtr.cast());
return Future.value(result.cast<Utf8>().toDartString());
final result = _libgopeed.Init(cfgPtr.cast());
if (result != nullptr) {
throw Exception(
'Libgopeed init failed: ${result.cast<Utf8>().toDartString()}');
}
return Future.value();
} finally {
calloc.free(cfgPtr);
}
}
@override
Future<String> invoke(int instance, String params) {
Future<String> invoke(String params) {
final paramsPtr = params.toNativeUtf8();
try {
final result = _libgopeed.Invoke(instance, paramsPtr.cast());
final result = _libgopeed.Invoke(paramsPtr.cast());
return Future.value(result.cast<Utf8>().toDartString());
} finally {
calloc.free(paramsPtr);
@@ -17,13 +17,15 @@ import '../model/update_extension_settings.dart';
import 'model/start_config.dart';
abstract class LibgopeedAbi {
Future<String> create(String cfg);
Future<String> invoke(int instance, String params);
Future<void> init(String cfg);
Future<String> invoke(String params);
}
abstract class LibgopeedApiSingleton {
Future<LibgopeedApi> init(StartConfig config);
}
abstract class LibgopeedApi {
Future<void> init(StartConfig cfg);
Future<HttpListenResult> startHttp();
Future<void> stopHttp();
+2 -1
View File
@@ -73,10 +73,11 @@ Future<void> init(Args args) async {
final controller = Get.put(AppController());
try {
await LibgopeedBoot.instance.init(StartConfig(
final instance = await LibgopeedBoot().init(StartConfig(
storage: "bolt",
storageDir: Util.getStorageDir(),
));
LibgopeedBoot.singleton(instance);
} catch (e) {
logger.e("libgopeed init fail", e);
}