mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-07 00:50:27 +00:00
feat: move native communication to FFI (#1457)
This commit is contained in:
86 files changed
+4558
-886
No files matched your search
@@ -1,8 +1,21 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void (*TaskEventCallback)(char* payload);
|
||||
|
||||
static void callTaskEventCallback(uintptr_t callback, char* payload) {
|
||||
((TaskEventCallback)callback)(payload);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/GopeedLab/gopeed/pkg/rest"
|
||||
"github.com/GopeedLab/gopeed/pkg/rest/model"
|
||||
)
|
||||
@@ -16,6 +29,7 @@ func Start(cfg *C.char) (int, *C.char) {
|
||||
return 0, C.CString(err.Error())
|
||||
}
|
||||
config.ProductionMode = true
|
||||
config.NativeMode = true
|
||||
applyWebViewProvider(&config)
|
||||
realPort, err := rest.Start(&config)
|
||||
if err != nil {
|
||||
@@ -28,3 +42,65 @@ func Start(cfg *C.char) (int, *C.char) {
|
||||
func Stop() {
|
||||
rest.Stop()
|
||||
}
|
||||
|
||||
//export GetAPIServerState
|
||||
func GetAPIServerState() *C.char {
|
||||
return C.CString(apiServerResult(rest.GetAPIServerState()))
|
||||
}
|
||||
|
||||
//export StartAPIServer
|
||||
func StartAPIServer() *C.char {
|
||||
return C.CString(apiServerResult(rest.StartAPIServer()))
|
||||
}
|
||||
|
||||
//export StopAPIServer
|
||||
func StopAPIServer() *C.char {
|
||||
return C.CString(apiServerResult(rest.StopAPIServer()))
|
||||
}
|
||||
|
||||
//export RestartAPIServer
|
||||
func RestartAPIServer() *C.char {
|
||||
return C.CString(apiServerResult(rest.RestartAPIServer()))
|
||||
}
|
||||
|
||||
func apiServerResult(state *model.APIServerState, err error) string {
|
||||
result := &model.APIServerOperationResult{State: state}
|
||||
if err != nil {
|
||||
result.Error = err.Error()
|
||||
}
|
||||
data, marshalErr := json.Marshal(result)
|
||||
if marshalErr != nil {
|
||||
return fmt.Sprintf(`{"state":null,"error":%q}`, marshalErr.Error())
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
|
||||
//export Invoke
|
||||
func Invoke(method *C.char, path *C.char, query *C.char, body *C.char) *C.char {
|
||||
return C.CString(rest.Invoke(
|
||||
C.GoString(method),
|
||||
C.GoString(path),
|
||||
C.GoString(query),
|
||||
C.GoString(body),
|
||||
))
|
||||
}
|
||||
|
||||
//export SubscribeTaskEvents
|
||||
func SubscribeTaskEvents(mask C.ulonglong, callback C.uintptr_t) {
|
||||
if mask == 0 || callback == 0 {
|
||||
rest.SubscribeTaskEvents(0, nil)
|
||||
return
|
||||
}
|
||||
rest.SubscribeTaskEvents(uint64(mask), func(payload string) {
|
||||
// Ownership crosses the asynchronous Dart callback boundary. Dart frees
|
||||
// this string with FreeCString after decoding it.
|
||||
C.callTaskEventCallback(callback, C.CString(payload))
|
||||
})
|
||||
}
|
||||
|
||||
//export FreeCString
|
||||
func FreeCString(value *C.char) {
|
||||
if value != nil {
|
||||
C.free(unsafe.Pointer(value))
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package libgopeed
|
||||
import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/GopeedLab/gopeed/internal/webview/rpcprovider"
|
||||
"github.com/GopeedLab/gopeed/pkg/rest"
|
||||
"github.com/GopeedLab/gopeed/pkg/rest/model"
|
||||
@@ -15,6 +16,7 @@ func Start(cfg string) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
config.ProductionMode = true
|
||||
config.NativeMode = true
|
||||
applyWebViewProvider(&config)
|
||||
return rest.Start(&config)
|
||||
}
|
||||
@@ -23,6 +25,47 @@ func Stop() {
|
||||
rest.Stop()
|
||||
}
|
||||
|
||||
func GetAPIServerState() string {
|
||||
return apiServerResult(rest.GetAPIServerState())
|
||||
}
|
||||
|
||||
func StartAPIServer() string {
|
||||
return apiServerResult(rest.StartAPIServer())
|
||||
}
|
||||
|
||||
func StopAPIServer() string {
|
||||
return apiServerResult(rest.StopAPIServer())
|
||||
}
|
||||
|
||||
func RestartAPIServer() string {
|
||||
return apiServerResult(rest.RestartAPIServer())
|
||||
}
|
||||
|
||||
func apiServerResult(state *model.APIServerState, err error) string {
|
||||
result := &model.APIServerOperationResult{State: state}
|
||||
if err != nil {
|
||||
result.Error = err.Error()
|
||||
}
|
||||
data, _ := json.Marshal(result)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func Invoke(method, path, query, body string) string {
|
||||
return rest.Invoke(method, path, query, body)
|
||||
}
|
||||
|
||||
type TaskEventListener interface {
|
||||
OnTaskEvent(payload string)
|
||||
}
|
||||
|
||||
func SubscribeTaskEvents(mask int64, listener TaskEventListener) {
|
||||
if mask == 0 || listener == nil {
|
||||
rest.SubscribeTaskEvents(0, nil)
|
||||
return
|
||||
}
|
||||
rest.SubscribeTaskEvents(uint64(mask), listener.OnTaskEvent)
|
||||
}
|
||||
|
||||
func applyWebViewProvider(config *model.StartConfig) {
|
||||
if config == nil || config.WebViewRPCConfig == nil || !config.WebViewRPCConfig.Enabled() {
|
||||
return
|
||||
|
||||
Reference in new issue
Block a user