chore: pass platform info to rust side (#5079)

* chore: pass platform info to rust side

* chore: pass platform info to rust side

* chore: fix test

* chore: fix test

* chore: fix test

* chore: enable ios log
This commit is contained in:
Nathan.fooo
2024-04-07 21:36:55 +08:00
committed by GitHub
parent 81594fa796
commit 3e32fac876
35 changed files with 465 additions and 200 deletions

View File

@ -1,10 +1,15 @@
export 'package:async/async.dart';
import 'dart:async';
import 'dart:convert';
import 'package:appflowy_backend/rust_stream.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'dart:ffi';
import 'ffi.dart' as ffi;
import 'package:ffi/ffi.dart';
import 'dart:isolate';
import 'dart:io';
import 'package:logger/logger.dart';
enum ExceptionType {
AppearanceSettingsIsEmpty,
@ -27,10 +32,15 @@ class FlowySDK {
Future<void> dispose() async {}
Future<void> init(String configuration) async {
final port = RustStreamReceiver.shared.port;
ffi.set_stream_port(port);
ffi.set_stream_port(RustStreamReceiver.shared.port);
ffi.store_dart_post_cobject(NativeApi.postCObject);
// On iOS, VSCode can't print logs from Rust, so we need to use a different method to print logs.
// So we use a shared port to receive logs from Rust and print them using the logger. In release mode, we don't print logs.
if (Platform.isIOS && kDebugMode) {
ffi.set_log_stream_port(RustLogStreamReceiver.logShared.port);
}
// final completer = Completer<Uint8List>();
// // Create a SendPort that accepts only one message.
// final sendPort = singleCompletePort(completer);
@ -42,3 +52,44 @@ class FlowySDK {
// return completer.future;
}
}
class RustLogStreamReceiver {
static RustLogStreamReceiver logShared = RustLogStreamReceiver._internal();
late RawReceivePort _ffiPort;
late StreamController<Uint8List> _streamController;
late StreamSubscription<Uint8List> _subscription;
int get port => _ffiPort.sendPort.nativePort;
late Logger _logger;
RustLogStreamReceiver._internal() {
_ffiPort = RawReceivePort();
_streamController = StreamController();
_ffiPort.handler = _streamController.add;
_logger = Logger(
printer: PrettyPrinter(
methodCount: 0, // number of method calls to be displayed
errorMethodCount: 8, // number of method calls if stacktrace is provided
lineLength: 120, // width of the output
colors: false, // Colorful log messages
printEmojis: false, // Print an emoji for each log message
printTime: false, // Should each log print contain a timestamp
),
level: kDebugMode ? Level.trace : Level.info,
);
_subscription = _streamController.stream.listen((data) {
String decodedString = utf8.decode(data);
_logger.i(decodedString);
});
}
factory RustLogStreamReceiver() {
return logShared;
}
Future<void> dispose() async {
await _streamController.close();
await _subscription.cancel();
_ffiPort.close();
}
}

View File

@ -110,6 +110,22 @@ typedef _set_stream_port_Dart = int Function(
int port,
);
/// C function `set log stream port`.
int set_log_stream_port(int port) {
return _set_log_stream_port(port);
}
final _set_log_stream_port_Dart _set_log_stream_port = _dart_ffi_lib
.lookupFunction<_set_log_stream_port_C, _set_log_stream_port_Dart>(
'set_log_stream_port');
typedef _set_log_stream_port_C = Int32 Function(
Int64 port,
);
typedef _set_log_stream_port_Dart = int Function(
int port,
);
/// C function `link_me_please`.
void link_me_please() {
_link_me_please();

View File

@ -1,6 +1,5 @@
// ignore: import_of_legacy_library_into_null_safe
import 'dart:ffi';
import 'package:ffi/ffi.dart' as ffi;
import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';

View File

@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:ffi';
import 'dart:isolate';
import 'dart:typed_data';
import 'package:appflowy_backend/log.dart';
import 'protobuf/flowy-notification/subject.pb.dart';

View File

@ -11,6 +11,8 @@ const uint8_t *sync_event(const uint8_t *input, uintptr_t len);
int32_t set_stream_port(int64_t port);
int32_t set_log_stream_port(int64_t port);
void link_me_please(void);
void rust_log(int64_t level, const char *data);