优化了dartapi

This commit is contained in:
Alex Zhang
2022-05-13 21:49:46 +08:00
parent 42a09e0958
commit 629ea56948
15 changed files with 131 additions and 145 deletions

View File

@@ -14,6 +14,7 @@
*.ipr
*.iws
.idea/
resource/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line

View File

@@ -8,6 +8,7 @@ import 'package:maa_core/typedefs.dart';
import "package:path/path.dart" as p;
void main() {
print(Directory.current.path);
runApp(const MyApp());
}
@@ -56,16 +57,18 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> {
late MaaCore _asst;
List<String> _logs =[];
List<String> _logs = [];
@override
void initState() {
setState(() {
_asst = MaaCore(p.join(p.current, 'linux'));
_asst = MaaCore(p.current, callback);
_asst.connect('adb', 'emulator-5554');
});
super.initState();
}
void callback(dynamic message) {
void callback(String message) {
setState(() {
_logs.add(message);
});
@@ -81,16 +84,15 @@ class _MyHomePageState extends State<MyHomePage> {
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
child: Column(
children: _logs.map((e) => Text(e)).toList(),
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
)
);
body: Center(
child: Column(
children: _logs.map((e) => Text(e)).toList(),
),
));
}
}

View File

@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:ffi';
import 'dart:convert';
import 'dart:isolate';
@@ -7,6 +8,9 @@ import 'package:path/path.dart' as p;
class MaaCore implements MaaCoreInterface {
late Assistant _asst;
late AsstLoadResourceFunc _asstLoadResource;
late AsstCreateFunc _asstCreate;
late AsstCreateExFunc _asstCreateEx;
late AsstConnectFunc _asstConnect;
late AsstDestroyFunc _asstDestroy;
late AsstAppendTaskFunc _asstAppendTask;
@@ -16,39 +20,67 @@ class MaaCore implements MaaCoreInterface {
late AsstCtrlerClickFunc _asstCtrlerClick;
late AsstGetVersionFunc _asstGetVersion;
late AsstLogFunc _asstLog;
static bool resourceLoaded = false;
static bool _resourceLoaded = false;
late ReceivePort? _receivePort;
static bool _apiInited = false;
ReceivePort? get receivePort => _receivePort;
late Pointer<Int64> _pointer;
late StreamSubscription _portSubscription;
late List<Pointer> _allocated;
static Future<String> get platformVersion async {
return Future<String>(() => '0.0.1');
}
static bool loadResource(DynamicLibrary lib, String resourceDir) {
final AsstLoadResourceFunc asstLoadResource =
lib.lookup<AsstLoadResourceNative>('AsstLoadResource').asFunction();
if (!resourceLoaded) {
return asstLoadResource(resourceDir.toNativeUtf8());
}
return true;
void _loadResource(String path) {
final strPtr = toManagedString(path);
final result = _asstLoadResource(strPtr);
_resourceLoaded = _resourceLoaded || result;
}
MaaCore(String libDir, [Function(dynamic)? callback]) {
MaaCore(String libDir, [Function(String)? callback]) {
_loadCppLib(libDir);
final _createWithDartPort = loadAsstCreateDart(libDir);
_receivePort = ReceivePort();
final portPtr = malloc.allocate<Int64>(sizeOf<Int64>());
portPtr.value = _receivePort!.sendPort.nativePort;
_asst = _createWithDartPort(portPtr);
if (callback != null) {
_receivePort!.listen(callback);
if (!_apiInited) {
final callbackLib = DynamicLibrary.open(p.join(libDir, 'libCallback.so'));
final InitDartApiFunc initNativeApi =
callbackLib.lookup<InitDartApiNative>('init_dart_api').asFunction();
initNativeApi(NativeApi.initializeApiDLData);
_apiInited = true;
}
_allocated = [];
if (!_resourceLoaded) {
_loadResource(libDir);
}
_receivePort = ReceivePort();
final nativePort = _receivePort!.sendPort.nativePort;
final portPtr = malloc.allocate<Int64>(sizeOf<Int64>());
_asst = _asstCreateEx(nativeCallback, portPtr.cast<Void>());
_allocated.add(portPtr);
portPtr.value = nativePort;
if (callback != null) {
_portSubscription = _receivePort!.listen(_wrapCallback(callback));
}
}
void Function(dynamic) _wrapCallback(void Function(String) cb) {
return (dynamic data) {
// c will manage the memory for the string
String msg = data;
cb(msg);
};
}
Pointer<AsstCallbackNative> get nativeCallback {
return DynamicLibrary.open('./libCallback.so')
.lookup<AsstCallbackNative>('callback');
}
void _loadCppLib(String libDir) {
final lib = DynamicLibrary.open(p.join(libDir, 'libMeoAssistant.so'));
_asstLoadResource =
lib.lookup<AsstLoadResourceNative>('AsstLoadResource').asFunction();
_asstCreate = lib.lookup<AsstCreateNative>('AsstCreate').asFunction();
_asstCreateEx = lib.lookup<AsstCreateExNative>('AsstCreateEx').asFunction();
_asstConnect = lib.lookup<AsstConnectNative>('AsstConnect').asFunction();
_asstDestroy = lib.lookup<AsstDestroyNative>('AsstDestroy').asFunction();
_asstAppendTask =
@@ -65,24 +97,24 @@ class MaaCore implements MaaCoreInterface {
}
@override
bool connect({
required String adbPath,
required String address,
String config = '',
}) {
bool connect(adbPath, address, [config = '']) {
return _asstConnect(
_asst,
adbPath.toNativeUtf8(),
address.toNativeUtf8(),
config.toNativeUtf8(),
toManagedString(adbPath),
toManagedString(address),
toManagedString(config),
);
}
@override
void destroy() {
if (_receivePort != null) {
_portSubscription.cancel();
_receivePort!.close();
malloc.free(_pointer);
}
while (_allocated.isNotEmpty) {
final ptr = _allocated.removeLast();
malloc.free(ptr);
}
_asstDestroy(_asst);
}
@@ -92,8 +124,8 @@ class MaaCore implements MaaCoreInterface {
final json = jsonEncode(params ?? {});
final taskId = _asstAppendTask(
_asst,
type.toNativeUtf8(),
json.toNativeUtf8(),
toManagedString(type),
toManagedString(json),
);
return taskId;
}
@@ -104,7 +136,7 @@ class MaaCore implements MaaCoreInterface {
final result = _asstSetTaskParams(
_asst,
taskId,
json.toNativeUtf8(),
toManagedString(json),
);
return result;
}
@@ -131,23 +163,12 @@ class MaaCore implements MaaCoreInterface {
@override
void log(String logLevel, String msg) {
_asstLog(logLevel.toNativeUtf8(), msg.toNativeUtf8());
_asstLog(toManagedString(logLevel), toManagedString(msg));
}
Pointer<Utf8> toManagedString(String str) {
final ptr = str.toNativeUtf8();
_allocated.add(ptr);
return ptr;
}
}
AsstCreateDartFunc loadAsstCreateDart(String libPath) {
final lib = DynamicLibrary.open(p.join(libPath, 'libMeoAssistantDart.so'));
return lib
.lookup<AsstCreateDartNative>('AsstCreateWithDartPort')
.asFunction();
}
InitDartVMFunc loadInitDartVM(String libPath) {
final lib = DynamicLibrary.open(p.join(libPath, 'libMeoAssistantDart.so'));
return lib.lookup<InitDartVMNative>('InitDartVM').asFunction();
}
CleanUpDartVMFunc loadCleanUpDartVM(String libPath) {
final lib = DynamicLibrary.open(p.join(libPath, 'libMeoAssistantDart.so'));
return lib.lookup<CleanUpDartVMNative>('CleanUpDartVM').asFunction();
}

View File

@@ -3,14 +3,14 @@ import "dart:ffi";
import "package:ffi/ffi.dart";
typedef Assistant = Pointer<Void>;
typedef AsstCallbackNative
= NativeFunction<Void Function(Int32, StringPtr, Pointer<Void>)>;
typedef AsstCallbackFunc = Void Function(Int32, StringPtr, Pointer<Void>);
typedef AsstCallbackFunc = void Function(int, Pointer<Utf8>, Pointer<Void>);
typedef AsstCallbackNative = NativeFunction<Void Function(Int32, Pointer<Utf8>, Pointer<Void>)>;
// AsstCreateEx
typedef AsstCreateDartFunc = Assistant Function(Pointer<Int64>);
typedef AsstCreateDartNative
= NativeFunction<Assistant Function(Pointer<Int64>)>;
typedef AsstCreateExFunc = Assistant Function(Pointer<AsstCallbackNative>, Pointer<Void>);
typedef AsstCreateExNative = NativeFunction<AsstCreateExFunc>;
// AsstCreate
typedef AsstCreateFunc = Assistant Function();
@@ -65,8 +65,8 @@ typedef TaskId = int;
typedef TaskIdNative = Int32;
typedef StringPtr = Pointer<Utf8>;
typedef InitDartVMFunc = void Function(Pointer<Void>);
typedef InitDartVMNative = NativeFunction<Void Function(Pointer<Void>)>;
typedef InitDartApiFunc = void Function(Pointer<Void>);
typedef InitDartApiNative = NativeFunction<Void Function(Pointer<Void>)>;
typedef CleanUpDartVMFunc = void Function();
@@ -74,8 +74,7 @@ typedef CleanUpDartVMNative = NativeFunction<Void Function()>;
abstract class MaaCoreInterface {
void destroy();
bool connect(
{required String adbPath, required String address, String config = ''});
bool connect(String adbPath, String address,[String config = '']);
TaskId appendTask(String type, [Map<String, dynamic>? params]);
bool setTaskParams(TaskId taskId, [Map<String, dynamic>? params]);
bool start();

View File

@@ -1,27 +1,9 @@
cmake_minimum_required(VERSION 2.8)
project(MeoAssistantArknightsDart)
project(callback)
if (WIN32)
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/MP>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/MP>")
add_library(Callback SHARED callback.c dart_api_dl.c)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif()
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/W4>")
add_compile_options("$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall;-Wextra;-Wpedantic>")
add_library(MeoAssistantDart SHARED src/AsstDartApi.cpp)
set(CMAKE_CXX_STANDARD 17)
set(MAA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../..")
include_directories("include" "${MAA_ROOT}/include" "dart" "dart/internal")
find_library(MeoAssistant PATHS "${CMAKE_CURRENT_SOURCE}/lib")
target_link_libraries(MeoAssistantDart PUBLIC ${MeoAssitant})
install(TARGETS MeoAssistantDart DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/../linux")
install(FILES lib/libMeoAssistant.so DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/../linux")
target_include_directories(Callback PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include/internal"
)

View File

@@ -0,0 +1,32 @@
#include "dart_api_dl.h"
#include <string.h>
#include <stdio.h>
void callback(int, const char *, void *);
void init_dart_api(void *);
void init_dart_api(void *api_data) {
Dart_InitializeApiDL(api_data);
}
void callback(int retval, const char *json_str, void *custom_arg) {
Dart_Port port = *(Dart_Port *)custom_arg;
int n_digits = 1;
int k = retval;
while (k > 10) {
n_digits++;
k /= 10;
}
Dart_CObject obj;
int required_len = n_digits + strlen(json_str) + 1;
char retstr[required_len];
retstr[required_len-1] = 0;
sprintf(retstr, "{\"retval\": %d, payload: \"%s\" }", retval, json_str);
obj.type = Dart_CObject_kString;
obj.value.as_string = retstr;
printf("C: Sending Pointer %ld to dart through port %ld\n", (int64_t)json_str, port);
char res = Dart_PostCObject_DL(port, &obj);
if (res == 0) {
printf("C: Failed to send message to Dart\n");
}
}

View File

@@ -1,9 +0,0 @@
#ifndef ASST_DART_API_H_
#define ASST_DART_API_H_
#include "dart_api.h"
#include "AsstCaller.h"
DART_EXPORT AsstHandle AsstCreateWithDartPort(Dart_Port *dart_port);
DART_EXPORT void InitDartVM(void *data);
#endif

View File

@@ -1,42 +0,0 @@
#include "AsstDartApi.h"
#include "AsstCaller.h"
#include "dart_api.h"
#include "dart_api_dl.h"
#include<iostream>
#include<string.h>
DART_EXPORT AsstHandle AsstCreateWithDartPort(Dart_Port *dart_port)
{
std::cout << "CPP: Dart_Port Pointer " << dart_port << std::endl;
std::cout << "CPP: Native Port: " << *dart_port << std::endl;
AsstApiCallback dart_cb = [](int msg, const char* detail, void* custom_arg)
{
Dart_CObject obj;
obj.type = Dart_CObject_kString;
obj.value.as_string = const_cast<char*>(detail);
Dart_Port port = *(Dart_Port *)custom_arg;
std::cout << "CPP: Native Port in closure: " << port << std::endl;
bool res = Dart_PostCObject(port, &obj);
if (!res) {
std::cerr << "CPP: Dart_PostCObject failed" << std::endl;
} else {
std::cout << "CPP: Successfully Sent message: " << detail << std::endl;
}
};
return AsstCreateEx(dart_cb, dart_port);
}
DART_EXPORT void InitDartVM(void *data)
{
std::cout << "CPP: InitDartVM" << std::endl;
Dart_InitializeParams* params = (Dart_InitializeParams*) data;
char* res = Dart_Initialize(params);
if (res) {
std::cerr << "CPP: Dart_Initialize failed:" << res << std::endl;
} else {
std::cout << "CPP: Dart_Initialize success" << std::endl;
}
free(res);
}