From 8d2bdf11498426527a8976abad887eed78f96179 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 28 Jun 2021 22:56:15 +0800 Subject: [PATCH] support sync and async on flowy-sys & add dart-ffi --- .idea/appflowy_client.iml | 2 + .idea/libraries/Dart_Packages.xml | 40 - Makefile.toml | 75 + app_flowy/macos/Podfile.lock | 2 +- .../packages/flowy_sdk/ios/flowy_sdk.podspec | 2 +- .../packages/flowy_sdk/lib/cqrs/auto_gen.dart | 1328 ----------------- .../packages/flowy_sdk/lib/cqrs/cqrs.dart | 55 - .../packages/flowy_sdk/lib/cqrs/util.dart | 77 - .../packages/flowy_sdk/lib/ffi/adaptor.dart | 83 -- app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart | 108 +- .../lib/ffi/rust_to_flutter_stream.dart | 54 - .../packages/flowy_sdk/lib/flowy_sdk.dart | 9 +- .../flowy_sdk/macos/Classes/binding.h | 11 - .../flowy_sdk/macos/flowy_sdk.podspec | 2 +- rust-lib/Cargo.toml | 2 + rust-lib/dart-ffi/Cargo.toml | 27 + rust-lib/dart-ffi/binding.h | 11 + rust-lib/dart-ffi/src/lib.rs | 46 + rust-lib/flowy-sdk/Cargo.toml | 8 + rust-lib/flowy-sdk/src/lib.rs | 1 + rust-lib/flowy-sys/Cargo.toml | 14 +- rust-lib/flowy-sys/src/dart_ffi/ffi.rs | 93 -- rust-lib/flowy-sys/src/dart_ffi/mod.rs | 4 - rust-lib/flowy-sys/src/error/error.rs | 31 +- rust-lib/flowy-sys/src/module/module.rs | 2 - rust-lib/flowy-sys/src/request/request.rs | 2 +- rust-lib/flowy-sys/src/response/data.rs | 2 +- rust-lib/flowy-sys/src/response/response.rs | 2 +- rust-lib/flowy-sys/src/rt/mod.rs | 3 +- rust-lib/flowy-sys/src/stream.rs | 117 +- rust-lib/flowy-sys/src/system.rs | 35 +- rust-lib/flowy-sys/tests/api/dart_ffi.rs | 34 - rust-lib/flowy-sys/tests/api/helper.rs | 53 +- rust-lib/flowy-sys/tests/api/main.rs | 1 - rust-lib/flowy-sys/tests/api/module_event.rs | 43 +- scripts/makefile/db.toml | 8 - scripts/makefile/desktop.toml | 30 +- scripts/makefile/pb.toml | 49 - 38 files changed, 360 insertions(+), 2106 deletions(-) create mode 100644 Makefile.toml delete mode 100644 app_flowy/packages/flowy_sdk/lib/cqrs/auto_gen.dart delete mode 100644 app_flowy/packages/flowy_sdk/lib/cqrs/cqrs.dart delete mode 100644 app_flowy/packages/flowy_sdk/lib/cqrs/util.dart delete mode 100644 app_flowy/packages/flowy_sdk/lib/ffi/rust_to_flutter_stream.dart create mode 100644 rust-lib/dart-ffi/Cargo.toml create mode 100644 rust-lib/dart-ffi/binding.h create mode 100644 rust-lib/dart-ffi/src/lib.rs create mode 100644 rust-lib/flowy-sdk/Cargo.toml create mode 100644 rust-lib/flowy-sdk/src/lib.rs delete mode 100644 rust-lib/flowy-sys/src/dart_ffi/ffi.rs delete mode 100644 rust-lib/flowy-sys/src/dart_ffi/mod.rs delete mode 100644 rust-lib/flowy-sys/tests/api/dart_ffi.rs delete mode 100644 scripts/makefile/db.toml delete mode 100644 scripts/makefile/pb.toml diff --git a/.idea/appflowy_client.iml b/.idea/appflowy_client.iml index ee323030e9..12b5c938f9 100644 --- a/.idea/appflowy_client.iml +++ b/.idea/appflowy_client.iml @@ -7,6 +7,8 @@ + + diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml index 06f3134367..1e952e4d5f 100644 --- a/.idea/libraries/Dart_Packages.xml +++ b/.idea/libraries/Dart_Packages.xml @@ -44,7 +44,6 @@ @@ -59,7 +58,6 @@ @@ -131,7 +129,6 @@ @@ -139,7 +136,6 @@ @@ -161,7 +157,6 @@ @@ -177,7 +172,6 @@ @@ -229,7 +223,6 @@ @@ -255,7 +248,6 @@ @@ -422,7 +414,6 @@ @@ -430,7 +421,6 @@ @@ -460,7 +450,6 @@ @@ -540,7 +529,6 @@ @@ -606,7 +594,6 @@ @@ -614,7 +601,6 @@ @@ -622,7 +608,6 @@ @@ -637,7 +622,6 @@ @@ -652,7 +636,6 @@ @@ -660,7 +643,6 @@ @@ -690,7 +672,6 @@ @@ -705,7 +686,6 @@ @@ -778,10 +758,8 @@ - - @@ -799,17 +777,13 @@ - - - - @@ -819,7 +793,6 @@ - @@ -827,7 +800,6 @@ - @@ -851,15 +823,12 @@ - - - @@ -873,7 +842,6 @@ - @@ -884,28 +852,20 @@ - - - - - - - - diff --git a/Makefile.toml b/Makefile.toml new file mode 100644 index 0000000000..4f9fb3d977 --- /dev/null +++ b/Makefile.toml @@ -0,0 +1,75 @@ +extend = [ + { path = "scripts/makefile/desktop.toml" }, +] + +[env] +CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true +CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" +CARGO_MAKE_CRATE_NAME = "dart-ffi" +DEV = true +LIB_OUT_DIR = "debug" +RELEASE = false +TARGET_OS = "unknown" + +[tasks.setup-crate-type] +private = true +script = [ + """ + toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml + crate_type = set "" + os = get_env TARGET_OS + is_android = eq ${os} "android" + is_ios = eq ${os} "ios" + is_macos = eq ${os} "macos" + is_pad = eq ${os} "pad" + + if ${is_android} + crate_type = set "cdylib" + elseif ${is_ios} + crate_type = set "staticlib" + elseif ${is_macos} + crate_type = set "cdylib" + elseif ${is_pad} + crate_type = set "cdylib" + else + crate_type = set "rlib" + end + + val = replace ${toml} "rlib" ${crate_type} + result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val} + assert ${result} + """, +] +script_runner = "@duckscript" + + +[tasks.restore-crate-type] +private = true +script = [ + """ + toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml + crate_type = set "" + os = get_env TARGET_OS + is_android = eq ${os} "android" + is_ios = eq ${os} "ios" + is_macos = eq ${os} "macos" + is_pad = eq ${os} "pad" + + if ${is_android} + crate_type = set "cdylib" + elseif ${is_ios} + crate_type = set "staticlib" + elseif ${is_macos} + crate_type = set "cdylib" + elseif ${is_pad} + crate_type = set "cdylib" + else + crate_type = set "rlib" + end + + val = replace ${toml} ${crate_type} "rlib" + result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val} + assert ${result} + """, +] +script_runner = "@duckscript" \ No newline at end of file diff --git a/app_flowy/macos/Podfile.lock b/app_flowy/macos/Podfile.lock index ee4eff018c..2260813685 100644 --- a/app_flowy/macos/Podfile.lock +++ b/app_flowy/macos/Podfile.lock @@ -24,7 +24,7 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/window_size/macos SPEC CHECKSUMS: - flowy_sdk: 12d2c047ed260a0aa8788a0b9616da46e2312025 + flowy_sdk: c302ac0a22dea596db0df8073b9637b2bf2ff6fd FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b window_size: 339dafa0b27a95a62a843042038fa6c3c48de195 diff --git a/app_flowy/packages/flowy_sdk/ios/flowy_sdk.podspec b/app_flowy/packages/flowy_sdk/ios/flowy_sdk.podspec index de720c906f..c38482c452 100644 --- a/app_flowy/packages/flowy_sdk/ios/flowy_sdk.podspec +++ b/app_flowy/packages/flowy_sdk/ios/flowy_sdk.podspec @@ -20,5 +20,5 @@ A new flutter plugin project. # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } s.swift_version = '5.0' - s.vendored_libraries = "libflowy_ffi.dylib" + s.vendored_libraries = "libdart_ffi.dylib" end diff --git a/app_flowy/packages/flowy_sdk/lib/cqrs/auto_gen.dart b/app_flowy/packages/flowy_sdk/lib/cqrs/auto_gen.dart deleted file mode 100644 index 2296cc99f1..0000000000 --- a/app_flowy/packages/flowy_sdk/lib/cqrs/auto_gen.dart +++ /dev/null @@ -1,1328 +0,0 @@ - - -/// Auto gen code from rust ast, do not edit -part of 'cqrs.dart'; -class WorkspaceCreateRequest { - WorkspaceCreation body; - WorkspaceCreateRequest(this.body); - Future> send() { - final command = Command.Workspace_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Workspace.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class WorkspaceDeleteRequest { - IdentifiableEntity body; - WorkspaceDeleteRequest(this.body); - Future> send() { - final command = Command.Workspace_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Workspace.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class WorkspaceUpdateRequest { - WorkspaceChangeset body; - WorkspaceUpdateRequest(this.body); - Future> send() { - final command = Command.Workspace_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Workspace.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class WorkspaceQueryRequest { - WorkspaceQuery body; - WorkspaceQueryRequest(this.body); - Future> send() { - final command = Command.Workspace_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = WorkspaceQueryResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class ViewCreateRequest { - ViewCreation body; - ViewCreateRequest(this.body); - Future> send() { - final command = Command.View_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = ViewCreation.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class ViewDeleteRequest { - IdentifiableEntity body; - ViewDeleteRequest(this.body); - Future> send() { - final command = Command.View_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = View.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class ViewUpdateRequest { - ViewChangeset body; - ViewUpdateRequest(this.body); - Future> send() { - final command = Command.View_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = View.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class ViewQueryRequest { - ViewQuery body; - ViewQueryRequest(this.body); - Future> send() { - final command = Command.View_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = ViewQueryResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class GridViewCreateRequest { - GridViewCreation body; - GridViewCreateRequest(this.body); - Future> send() { - final command = Command.Grid_View_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = GridViewCreationResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class ViewDisplayUpdateRequest { - ViewDisplayChangeset body; - ViewDisplayUpdateRequest(this.body); - Future> send() { - final command = Command.View_Display_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = ViewDisplay.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class TableCreateRequest { - TableCreation body; - TableCreateRequest(this.body); - Future> send() { - final command = Command.Table_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = TableCreation.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class TableDeleteRequest { - IdentifiableEntity body; - TableDeleteRequest(this.body); - Future> send() { - final command = Command.Table_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = FYTable.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class TableUpdateRequest { - FYTableChangeset body; - TableUpdateRequest(this.body); - Future> send() { - final command = Command.Table_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = FYTable.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class TableQueryRequest { - TableQuery body; - TableQueryRequest(this.body); - Future> send() { - final command = Command.Table_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = TableQueryResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class RowCreateRequest { - RowCreation body; - RowCreateRequest(this.body); - Future> send() { - final command = Command.Row_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Row.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class RowDeleteRequest { - IdentifiableEntity body; - RowDeleteRequest(this.body); - Future> send() { - final command = Command.Row_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Row.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class RowUpdateRequest { - RowChangeset body; - RowUpdateRequest(this.body); - Future> send() { - final command = Command.Row_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Row.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class RowQueryRequest { - RowQuery body; - RowQueryRequest(this.body); - Future> send() { - final command = Command.Row_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = RowQueryResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class FieldCreateRequest { - FieldCreation body; - FieldCreateRequest(this.body); - Future> send() { - final command = Command.Field_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Field.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class FieldDeleteRequest { - IdentifiableEntity body; - FieldDeleteRequest(this.body); - Future> send() { - final command = Command.Field_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Field.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class FieldUpdateRequest { - FieldChangeset body; - FieldUpdateRequest(this.body); - Future> send() { - final command = Command.Field_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Field.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class FieldQueryRequest { - FieldQuery body; - FieldQueryRequest(this.body); - Future> send() { - final command = Command.Field_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = FieldQueryResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class AppCreateRequest { - AppCreation body; - AppCreateRequest(this.body); - Future> send() { - final command = Command.App_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = App.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class AppDeleteRequest { - IdentifiableEntity body; - AppDeleteRequest(this.body); - Future> send() { - final command = Command.App_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = App.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class AppUpdateRequest { - AppChangeset body; - AppUpdateRequest(this.body); - Future> send() { - final command = Command.App_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = App.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class AppQueryRequest { - AppQuery body; - AppQueryRequest(this.body); - Future> send() { - final command = Command.App_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = AppQueryResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class CellCreateRequest { - CellCreation body; - CellCreateRequest(this.body); - Future> send() { - final command = Command.Cell_Create; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Cell.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class CellDeleteRequest { - IdentifiableEntity body; - CellDeleteRequest(this.body); - Future> send() { - final command = Command.Cell_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Cell.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class CellUpdateRequest { - CellChangeset body; - CellUpdateRequest(this.body); - Future> send() { - final command = Command.Cell_Update; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = Cell.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class CellQueryRequest { - CellQuery body; - CellQueryRequest(this.body); - Future> send() { - final command = Command.Cell_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = CellQueryResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class UserQueryRequest { - Uint8List? body; - UserQueryRequest(); - Future> send() { - final command = Command.User_Query; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = UserQueryResult.fromBuffer(response.body); - return left(pb); - } - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - - }); - } -} -class UserCheckRequest { - Uint8List? body; - UserCheckRequest(); - Future> send() { - final command = Command.User_Check; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = User.fromBuffer(response.body); - return left(pb); - } - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - - }); - } -} -class UserSignInRequest { - UserSignIn body; - UserSignInRequest(this.body); - Future> send() { - final command = Command.User_Sign_In; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = UserSignInResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class UserSignUpRequest { - UserSignUp body; - UserSignUpRequest(this.body); - Future> send() { - final command = Command.User_Sign_Up; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = UserSignUpResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class UserSignOutRequest { - UserSignOut body; - UserSignOutRequest(this.body); - Future> send() { - final command = Command.User_Sign_Out; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - return left(response); - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class UserActiveRequest { - User body; - UserActiveRequest(this.body); - Future> send() { - final command = Command.User_Active; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - return left(response); - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class UserMobileCodeRequest { - VerificationCodeRequest body; - UserMobileCodeRequest(this.body); - Future> send() { - final command = Command.User_Mobile_Code; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = VerificationCodeResponse.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class UserAuthInputRequest { - UserAuthInput body; - UserAuthInputRequest(this.body); - Future> send() { - final command = Command.User_Auth_Input; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = UserAuthInput.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class BucketSetRequest { - BucketItem body; - BucketSetRequest(this.body); - Future> send() { - final command = Command.Bucket_Set; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - return left(response); - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class BucketGetRequest { - BucketItem body; - BucketGetRequest(this.body); - Future> send() { - final command = Command.Bucket_Get; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncQuery(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = BucketItem.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class BucketDeleteRequest { - BucketItem body; - BucketDeleteRequest(this.body); - Future> send() { - final command = Command.Bucket_Delete; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - return left(response); - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} -class CSVImportRequest { - FlowyResource body; - CSVImportRequest(this.body); - Future> send() { - final command = Command.CSV_Import; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); - return protobufToBytes(body).fold( - (req_bytes) { - request.body = req_bytes; - return asyncCommand(request).then((response) { - try { - if (response.hasErr()) { - return right(FlowyError.from(response)); - } else { - final pb = ShareResult.fromBuffer(response.body); - return left(pb); - } - - } catch (e, s) { - final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError); - return right(error); - } - }); - }, - (err) => Future(() { - final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError); - return right(error); - }), - ); - } -} diff --git a/app_flowy/packages/flowy_sdk/lib/cqrs/cqrs.dart b/app_flowy/packages/flowy_sdk/lib/cqrs/cqrs.dart deleted file mode 100644 index feb88b3821..0000000000 --- a/app_flowy/packages/flowy_sdk/lib/cqrs/cqrs.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:dartz/dartz.dart'; -import 'package:flowy_protobuf/remote.dart'; -import 'package:infra/uuid.dart'; -import 'dart:typed_data'; -import 'package:flowy_protobuf/all.dart'; -import 'util.dart'; - -part 'auto_gen.dart'; - -class FlowyError { - late StatusCode _statusCode; - late String _error; - late bool _has_error; - - StatusCode get statusCode { - return _statusCode; - } - - String get error { - return _error; - } - - bool get has_error { - return _has_error; - } - - String toString() { - return "$_statusCode: $_error"; - } - - @override - bool operator ==(other) { - if (other is FlowyError) { - return (this.statusCode == other.statusCode && - this._error == other._error); - } else { - return false; - } - } - - FlowyError({required StatusCode statusCode, required String error}) { - _statusCode = statusCode; - _error = error; - _has_error = true; - } - - factory FlowyError.from(ResponsePacket resp) { - return FlowyError(statusCode: resp.statusCode, error: resp.err) - .._has_error = resp.hasErr(); - } - - factory FlowyError.fromError(String error, StatusCode statusCode) { - return FlowyError(statusCode: statusCode, error: error); - } -} diff --git a/app_flowy/packages/flowy_sdk/lib/cqrs/util.dart b/app_flowy/packages/flowy_sdk/lib/cqrs/util.dart deleted file mode 100644 index 076d36df18..0000000000 --- a/app_flowy/packages/flowy_sdk/lib/cqrs/util.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:dartz/dartz.dart'; -import 'package:flowy_protobuf/remote.dart'; -// ignore: import_of_legacy_library_into_null_safe -import 'package:protobuf/protobuf.dart'; -import 'package:flowy_sdk/ffi/adaptor.dart'; -import 'dart:typed_data'; -import 'package:flowy_logger/flowy_logger.dart'; - -Either protobufToBytes( - T? message) { - try { - if (message != null) { - return left(message.writeToBuffer()); - } else { - return left(Uint8List.fromList([])); - } - } catch (e, s) { - return right( - 'FlowyFFI syncRequest error: ${e.runtimeType}. Stack trace: $s'); - } -} - -Future asyncCommand(RequestPacket request) { - try { - return FFIAdaptor.asyncRequest(request).future.then((value) { - try { - final resp = ResponsePacket.fromBuffer(value); - return Future.microtask(() => resp); - } catch (e, s) { - Log.error('FlowyFFI asyncRequest error: ${e.runtimeType}\n'); - Log.error('Stack trace \n $s'); - final resp = responseFromRequest( - request, "FlowyFFI asyncRequest error: ${e.runtimeType}"); - return Future.microtask(() => resp); - } - }); - } catch (e, s) { - Log.error('FlowyFFI asyncRequest error: ${e.runtimeType}\n'); - Log.error('Stack trace \n $s'); - final resp = responseFromRequest( - request, "FlowyFFI asyncRequest error: ${e.runtimeType}"); - return Future.microtask(() => resp); - } -} - -Future asyncQuery(RequestPacket request) { - try { - return FFIAdaptor.asyncQuery(request).future.then((value) { - try { - final resp = ResponsePacket.fromBuffer(value); - return Future.microtask(() => resp); - } catch (e, s) { - Log.error('FlowyFFI asyncRequest error: ${e.runtimeType}\n'); - Log.error('Stack trace \n $s'); - final resp = responseFromRequest( - request, "FlowyFFI asyncRequest error: ${e.runtimeType}"); - return Future.microtask(() => resp); - } - }); - } catch (e, s) { - Log.error('FlowyFFI asyncRequest error: ${e.runtimeType}\n'); - Log.error('Stack trace \n $s'); - final resp = responseFromRequest( - request, "FlowyFFI asyncRequest error: ${e.runtimeType}"); - return Future.microtask(() => resp); - } -} - -ResponsePacket responseFromRequest(RequestPacket request, String message) { - var resp = ResponsePacket(); - resp.id = request.id; - resp.statusCode = StatusCode.Fail; - resp.command = request.command; - resp.err = message; - - return resp; -} diff --git a/app_flowy/packages/flowy_sdk/lib/ffi/adaptor.dart b/app_flowy/packages/flowy_sdk/lib/ffi/adaptor.dart index c699f8dc2e..26face2e2d 100644 --- a/app_flowy/packages/flowy_sdk/lib/ffi/adaptor.dart +++ b/app_flowy/packages/flowy_sdk/lib/ffi/adaptor.dart @@ -42,88 +42,5 @@ class FFIAdaptor { return completer; } - - static Completer asyncQuery(RequestPacket request) { - Uint8List bytes = request.writeToBuffer(); - assert(bytes.isEmpty == false); - if (bytes.isEmpty) { - throw FFIAdaptorException(FFIExceptionType.RequestPacketIsEmpty); - } - - final Pointer input = calloc.allocate(bytes.length); - final list = input.asTypedList(bytes.length); - list.setAll(0, bytes); - - final completer = Completer(); - final port = singleCompletePort(completer); - ffi.async_query(port.nativePort, input, bytes.length); - calloc.free(input); - - return completer; - } - - //https://suragch.medium.com/working-with-bytes-in-dart-6ece83455721 - static FFISafeUint8Wrapper syncRequest(RequestPacket request) { - Uint8List bytes; - try { - bytes = request.writeToBuffer(); - } catch (e, s) { - //TODO nathan: upload the log - print('Sync RequestPacket writeToBuffer error: ${e.runtimeType}'); - print('Stack trace \n $s'); - rethrow; - } - - assert(bytes.isEmpty == false); - if (bytes.isEmpty) { - throw FFIAdaptorException(FFIExceptionType.RequestPacketIsEmpty); - } - - final Pointer dartPtr = _pointerFromBytes(bytes); - Pointer rustPtr = ffi.sync_command(dartPtr, bytes.length); - calloc.free(dartPtr); - FFISafeUint8Wrapper safeWrapper; - try { - safeWrapper = FFISafeUint8Wrapper(rustPtr); - } catch (_) { - rethrow; - } - return safeWrapper; - } - - // inline? - static Pointer _pointerFromBytes(Uint8List bytes) { - final Pointer ptr = calloc.allocate(bytes.length); - final list = ptr.asTypedList(bytes.length); - list.setAll(0, bytes); - return ptr; - } } -class FFISafeUint8Wrapper { - Pointer _ptr; - int _responseBytesLen = 0; - int _markerBytesLen = 4; - FFISafeUint8Wrapper(this._ptr) { - try { - this._responseBytesLen = - ByteData.sublistView(_ptr.asTypedList(_markerBytesLen)) - .getUint32(0, Endian.big); - } catch (_) { - throw FFIAdaptorException(FFIExceptionType.RequestPacketIsEmpty); - } - - if (this._responseBytesLen < _markerBytesLen) { - throw FFIAdaptorException(FFIExceptionType.ResponsePacketIsInvalid); - } - } - - void destroy() { - ffi.free_rust(_ptr, _responseBytesLen + _markerBytesLen); - } - - Uint8List buffer() { - Pointer respPtr = _ptr.elementAt(_markerBytesLen); - return respPtr.asTypedList(_responseBytesLen); - } -} diff --git a/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart b/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart index e469b3535e..07ffbb89e6 100644 --- a/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart +++ b/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart @@ -1,4 +1,4 @@ -/// bindings for `libflowy_ffi` +/// bindings for `libdart_ffi` import 'dart:ffi'; import 'dart:io'; @@ -14,9 +14,9 @@ final DynamicLibrary dl = _dl; DynamicLibrary _open() { if (is_tester()) { return DynamicLibrary.open( - '${Directory.systemTemp.path}/app_flowy/libflowy_ffi.dylib'); + '${Directory.systemTemp.path}/app_flowy/libdart_ffi.dylib'); } else { - if (Platform.isAndroid) return DynamicLibrary.open('libflowy_ffi.so'); + if (Platform.isAndroid) return DynamicLibrary.open('libdart_ffi.so'); if (Platform.isMacOS) return DynamicLibrary.executable(); if (Platform.isIOS) return DynamicLibrary.executable(); throw UnsupportedError('This platform is not supported.'); @@ -45,92 +45,6 @@ typedef _invoke_async_Dart = void Function( int len, ); -/// C function `command_sync`. -Pointer sync_command( - Pointer input, - int len, -) { - return _invoke_sync(input, len); -} - -final _invoke_sync_Dart _invoke_sync = - _dl.lookupFunction<_invoke_sync_C, _invoke_sync_Dart>('sync_command'); -typedef _invoke_sync_C = Pointer Function( - Pointer input, - Uint64 len, -); -typedef _invoke_sync_Dart = Pointer Function( - Pointer input, - int len, -); - -/// C function `async_query`. -void async_query( - int port, - Pointer input, - int len, -) { - _invoke_async_query(port, input, len); -} - -final _invoke_async_query_Dart _invoke_async_query = - _dl.lookupFunction<_invoke_async_query_C, _invoke_async_query_Dart>( - 'async_query'); -typedef _invoke_async_query_C = Void Function( - Int64 port, - Pointer input, - Uint64 len, -); -typedef _invoke_async_query_Dart = void Function( - int port, - Pointer input, - int len, -); - -/// C function `free_rust`. -void free_rust( - Pointer input, - int len, -) { - _free_rust(input, len); -} - -final _free_rust_Dart _free_rust = - _dl.lookupFunction<_free_rust_C, _free_rust_Dart>('free_rust'); -typedef _free_rust_C = Void Function( - Pointer input, - Uint64 len, -); -typedef _free_rust_Dart = void Function( - Pointer input, - int len, -); - -/// C function `init_stream`. -int init_stream(int port) { - return _init_stream(port); -} - -final _init_stream_Dart _init_stream = - _dl.lookupFunction<_init_stream_C, _init_stream_Dart>('init_stream'); - -typedef _init_stream_C = Int32 Function( - Int64 port, -); -typedef _init_stream_Dart = int Function( - int port, -); - -/// C function `init_logger`. -int init_logger() { - return _init_logger(); -} - -final _init_logger_Dart _init_logger = - _dl.lookupFunction<_init_logger_C, _init_logger_Dart>('init_logger'); -typedef _init_logger_C = Int64 Function(); -typedef _init_logger_Dart = int Function(); - /// C function `init_sdk`. int init_sdk( Pointer path, @@ -174,22 +88,6 @@ typedef _store_dart_post_cobject_Dart = void Function( Pointer)>> ptr, ); -/// C function `setup_logger`. -void setup_logger( - Pointer ptr, -) { - _setup_logger(ptr); -} - -final _setup_logger_Dart _setup_logger = - _dl.lookupFunction<_setup_logger_C, _setup_logger_Dart>('setup_logger'); -typedef _setup_logger_C = Void Function( - Pointer ptr, -); -typedef _setup_logger_Dart = void Function( - Pointer ptr, -); - bool is_tester() { if (Foundation.kDebugMode) { // ignore: unnecessary_null_comparison diff --git a/app_flowy/packages/flowy_sdk/lib/ffi/rust_to_flutter_stream.dart b/app_flowy/packages/flowy_sdk/lib/ffi/rust_to_flutter_stream.dart deleted file mode 100644 index a88a9b6d2a..0000000000 --- a/app_flowy/packages/flowy_sdk/lib/ffi/rust_to_flutter_stream.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:isolate'; -import 'dart:async'; -import 'dart:typed_data'; -import 'dart:ffi'; -import 'package:flowy_logger/flowy_logger.dart'; -import 'package:flowy_protobuf/model/observable.pb.dart'; - -typedef ObserverCallback = void Function(ObservableSubject observable); - -class R2FStream { - static R2FStream shared = R2FStream._internal(); - late RawReceivePort _ffiPort; - late StreamController _streamController; - late StreamController _observableController; - late StreamSubscription _ffiSubscription; - - int get port => _ffiPort.sendPort.nativePort; - StreamController get observable => _observableController; - - R2FStream._internal() { - _ffiPort = RawReceivePort(); - _streamController = StreamController(); - _observableController = StreamController.broadcast(); - - _ffiPort.handler = _streamController.add; - _ffiSubscription = _streamController.stream.listen(streamCallback); - } - - factory R2FStream() { - return shared; - } - - static listen(void Function(ObservableSubject subject) callback) { - R2FStream.shared.observable.stream.listen(callback); - } - - void streamCallback(Uint8List bytes) { - try { - final observable = ObservableSubject.fromBuffer(bytes); - _observableController.add(observable); - } catch (e, s) { - Log.error('FFIStream handleReceviedBytes error: ${e.runtimeType}'); - Log.error('Stack trace \n $s'); - rethrow; - } - } - - Future dispose() async { - await _ffiSubscription.cancel(); - await _streamController.close(); - await _observableController.close(); - _ffiPort.close(); - } -} diff --git a/app_flowy/packages/flowy_sdk/lib/flowy_sdk.dart b/app_flowy/packages/flowy_sdk/lib/flowy_sdk.dart index e1a1dc8524..5abe02caea 100644 --- a/app_flowy/packages/flowy_sdk/lib/flowy_sdk.dart +++ b/app_flowy/packages/flowy_sdk/lib/flowy_sdk.dart @@ -1,11 +1,9 @@ -export 'cqrs/cqrs.dart'; export 'package:async/async.dart'; import 'dart:io'; import 'dart:async'; import 'package:flutter/services.dart'; import 'dart:ffi'; -import 'ffi/rust_to_flutter_stream.dart'; import 'ffi/ffi.dart' as ffi; import 'package:ffi/ffi.dart'; @@ -19,16 +17,11 @@ class FlowySDK { const FlowySDK(); void dispose() { - R2FStream.shared.dispose(); + } Future init(Directory sdkDir) async { - final port = R2FStream.shared.port; - ffi.init_stream(port); - - ffi.init_logger(); ffi.store_dart_post_cobject(NativeApi.postCObject); - print("Application document directory: ${sdkDir.absolute}"); ffi.init_sdk(sdkDir.path.toNativeUtf8()); } } diff --git a/app_flowy/packages/flowy_sdk/macos/Classes/binding.h b/app_flowy/packages/flowy_sdk/macos/Classes/binding.h index 9ac0b90249..ac6bcf50e4 100644 --- a/app_flowy/packages/flowy_sdk/macos/Classes/binding.h +++ b/app_flowy/packages/flowy_sdk/macos/Classes/binding.h @@ -3,20 +3,9 @@ #include #include -int64_t init_logger(); int64_t init_sdk(char *path); -int32_t init_stream(int64_t port); - void async_command(int64_t port, const uint8_t *input, uintptr_t len); -void async_query(int64_t port, const uint8_t *input, uintptr_t len); - -const uint8_t *sync_command(const uint8_t *input, uintptr_t len); - -void free_rust( - uint8_t *ptr, - uint32_t length); - void link_me_please(void); \ No newline at end of file diff --git a/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec b/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec index 79b009d92e..ff416e83fe 100644 --- a/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec +++ b/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec @@ -20,5 +20,5 @@ A new flutter plugin project. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } s.swift_version = '5.0' # s.static_framework = true - s.vendored_libraries = "libflowy_ffi.dylib" + s.vendored_libraries = "libdart_ffi.dylib" end diff --git a/rust-lib/Cargo.toml b/rust-lib/Cargo.toml index 456a79dcfe..5d0ec862f2 100644 --- a/rust-lib/Cargo.toml +++ b/rust-lib/Cargo.toml @@ -1,6 +1,8 @@ [workspace] members = [ "flowy-sys", + "flowy-sdk", + "dart-ffi", ] [profile.dev] diff --git a/rust-lib/dart-ffi/Cargo.toml b/rust-lib/dart-ffi/Cargo.toml new file mode 100644 index 0000000000..9ca697fef4 --- /dev/null +++ b/rust-lib/dart-ffi/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "dart-ffi" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "dart_ffi" +# this value will change depending on the target os +# for iOS it would be `rlib` +# for Macos it would be `rlib` +# for android it would be `c-dylib` +# default rlib +crate-type = ["rlib"] + + +[dependencies] +allo-isolate = {version = "^0.1", features = ["catch-unwind",]} +byteorder = {version = "1.3.4"} +ffi-support = {version = "0.4.2"} +protobuf = {version = "2.20.0"} +lazy_static = {version = "1.4.0"} +tokio = { version = "1", features = ["sync"] } +log = "0.4.14" + +flowy-sys = {path = "../flowy-sys"} +flowy-sdk = {path = "../flowy-sdk"} \ No newline at end of file diff --git a/rust-lib/dart-ffi/binding.h b/rust-lib/dart-ffi/binding.h new file mode 100644 index 0000000000..ac6bcf50e4 --- /dev/null +++ b/rust-lib/dart-ffi/binding.h @@ -0,0 +1,11 @@ +#include +#include +#include +#include + + +int64_t init_sdk(char *path); + +void async_command(int64_t port, const uint8_t *input, uintptr_t len); + +void link_me_please(void); \ No newline at end of file diff --git a/rust-lib/dart-ffi/src/lib.rs b/rust-lib/dart-ffi/src/lib.rs new file mode 100644 index 0000000000..19e3fa191c --- /dev/null +++ b/rust-lib/dart-ffi/src/lib.rs @@ -0,0 +1,46 @@ +use flowy_sys::prelude::*; +use std::{cell::RefCell, ffi::CStr, os::raw::c_char}; + +#[no_mangle] +pub extern "C" fn init_sdk(path: *mut c_char) -> i64 { + let c_str: &CStr = unsafe { CStr::from_ptr(path) }; + let path: &str = c_str.to_str().unwrap(); + println!("{}", path); + return 1; +} + +#[no_mangle] +pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) { + let bytes = unsafe { std::slice::from_raw_parts(input, len) }.to_vec(); + let request = EventRequest::from_data(bytes); + + let stream_data = StreamData::new(port, Some(request)).with_callback(Box::new(|_config, response| { + log::info!("async resp: {:?}", response); + })); + + async_send(stream_data); +} + +#[inline(never)] +#[no_mangle] +pub extern "C" fn link_me_please() {} + +thread_local!( + static STREAM_SENDER: RefCell>> = RefCell::new(None); +); + +pub fn sync_send(data: StreamData) -> EventResponse { + STREAM_SENDER.with(|cell| match &*cell.borrow() { + Some(stream) => stream.sync_send(data), + None => panic!(""), + }) +} + +pub fn async_send(data: StreamData) { + STREAM_SENDER.with(|cell| match &*cell.borrow() { + Some(stream) => { + stream.async_send(data); + }, + None => panic!(""), + }); +} diff --git a/rust-lib/flowy-sdk/Cargo.toml b/rust-lib/flowy-sdk/Cargo.toml new file mode 100644 index 0000000000..87c0481969 --- /dev/null +++ b/rust-lib/flowy-sdk/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "flowy-sdk" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust-lib/flowy-sdk/src/lib.rs b/rust-lib/flowy-sdk/src/lib.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/rust-lib/flowy-sdk/src/lib.rs @@ -0,0 +1 @@ + diff --git a/rust-lib/flowy-sys/Cargo.toml b/rust-lib/flowy-sys/Cargo.toml index 6343f6c6c4..b8dc7ca2bc 100644 --- a/rust-lib/flowy-sys/Cargo.toml +++ b/rust-lib/flowy-sys/Cargo.toml @@ -13,7 +13,7 @@ futures-channel = "0.3.15" futures = "0.3.15" futures-util = "0.3.15" bytes = "0.5" -tokio = { version = "1", features = ["sync"] } +tokio = { version = "1", features = ["full"] } uuid = { version = "0.8", features = ["serde", "v4"] } log = "0.4.14" env_logger = "0.8" @@ -21,17 +21,9 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_with = "1.9.4" thread-id = "3.3.0" - -#optional crate -allo-isolate = {version = "^0.1", features = ["catch-unwind",], optional = true} -byteorder = {version = "1.3.4", optional = true} -ffi-support = {version = "0.4.2", optional = true} -protobuf = {version = "2.20.0", optional = true} -lazy_static = {version = "1.4.0", optional = true} +lazy_static = "1.4.0" +dyn-clone = "1.0" [dev-dependencies] tokio = { version = "1", features = ["full"] } futures-util = "0.3.15" - -[features] -dart_ffi = ["ffi-support", "allo-isolate", "byteorder", "protobuf", "lazy_static"] \ No newline at end of file diff --git a/rust-lib/flowy-sys/src/dart_ffi/ffi.rs b/rust-lib/flowy-sys/src/dart_ffi/ffi.rs deleted file mode 100644 index ae1425833d..0000000000 --- a/rust-lib/flowy-sys/src/dart_ffi/ffi.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::{ - module::Module, - request::EventRequest, - response::EventResponse, - rt::SystemCommand, - stream::*, - system::FlowySystem, -}; -use futures_core::ready; -use lazy_static::lazy_static; -use protobuf::Message; -use std::{ - cell::RefCell, - future::Future, - sync::{Arc, RwLock}, - task::Context, -}; -use tokio::{ - macros::support::{Pin, Poll}, - sync::{mpsc::UnboundedSender, oneshot}, -}; - -#[no_mangle] -pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) { - let bytes = unsafe { std::slice::from_raw_parts(input, len) }.to_vec(); - let request = EventRequest::from_data(bytes); - - let stream_data = StreamData::new(port, Some(request), Box::new(|port, response| {})); - send(stream_data); -} - -#[no_mangle] -pub extern "C" fn free_rust(ptr: *mut u8, length: u32) { reclaim_rust(ptr, length) } - -#[no_mangle] -pub extern "C" fn init_stream(port: i64) -> i32 { return 0; } - -#[allow(unused_attributes)] -pub fn reclaim_rust(ptr: *mut u8, length: u32) { - unsafe { - let len: usize = length as usize; - Vec::from_raw_parts(ptr, len, len); - } -} - -thread_local!( - static STREAM_SENDER: RefCell>>> = RefCell::new(None); -); - -pub fn send(data: StreamData) { - STREAM_SENDER.with(|cell| match &*cell.borrow() { - Some(tx) => { - tx.send(data); - }, - None => panic!(""), - }); -} - -pub fn init_dart(modules: Vec, f: F) -where - F: FnOnce() + 'static, -{ - let mut stream = CommandStream::::new(); - let stream = CommandStream::::new(); - let tx = stream.tx(); - - STREAM_SENDER.with(|cell| { - *cell.borrow_mut() = Some(tx); - }); - - FlowySystem::construct(|| modules, stream) - .spawn(async { f() }) - .run() - .unwrap(); - - // FlowySystem::construct(|| modules, stream) - // .spawn(async move { - // let request = EventRequest::new("1".to_string()); - // let stream_data = StreamData::new( - // 1, - // Some(request), - // Box::new(|config, response| { - // log::info!("😁{:?}", response); - // }), - // ); - // - // send(stream_data); - // - // FlowySystem::current().stop(); - // }) - // .run() - // .unwrap(); -} diff --git a/rust-lib/flowy-sys/src/dart_ffi/mod.rs b/rust-lib/flowy-sys/src/dart_ffi/mod.rs deleted file mode 100644 index 873bec1e08..0000000000 --- a/rust-lib/flowy-sys/src/dart_ffi/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[cfg(feature = "dart_ffi")] -mod ffi; - -pub use ffi::*; diff --git a/rust-lib/flowy-sys/src/error/error.rs b/rust-lib/flowy-sys/src/error/error.rs index 429ab8157a..52243567b2 100644 --- a/rust-lib/flowy-sys/src/error/error.rs +++ b/rust-lib/flowy-sys/src/error/error.rs @@ -2,19 +2,23 @@ use crate::{ request::EventRequest, response::{EventResponse, EventResponseBuilder, StatusCode}, }; +use dyn_clone::DynClone; use std::{fmt, option::NoneError}; use tokio::sync::mpsc::error::SendError; -pub trait Error: fmt::Debug + fmt::Display { +pub trait Error: fmt::Debug + fmt::Display + DynClone { fn status_code(&self) -> StatusCode; fn as_response(&self) -> EventResponse { EventResponse::new(self.status_code()) } } +dyn_clone::clone_trait_object!(Error); + impl From for SystemError { fn from(err: T) -> SystemError { SystemError { inner: Box::new(err) } } } +#[derive(Clone)] pub struct SystemError { inner: Box, } @@ -37,15 +41,13 @@ impl std::error::Error for SystemError { fn cause(&self) -> Option<&dyn std::error::Error> { None } } -impl From> for SystemError -where - T: fmt::Display + fmt::Debug + 'static, -{ - fn from(err: SendError) -> Self { InternalError { inner: err }.into() } -} - impl From> for SystemError { - fn from(err: SendError) -> Self { InternalError { inner: err }.into() } + fn from(err: SendError) -> Self { + InternalError { + inner: format!("{}", err), + } + .into() + } } impl From for SystemError { @@ -61,31 +63,32 @@ impl From for EventResponse { fn from(err: SystemError) -> Self { err.inner_error().as_response() } } -pub struct InternalError { +#[derive(Clone)] +pub struct InternalError { inner: T, } -impl InternalError { +impl InternalError { pub fn new(inner: T) -> Self { InternalError { inner } } } impl fmt::Debug for InternalError where - T: fmt::Debug + 'static, + T: fmt::Debug + 'static + Clone, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.inner, f) } } impl fmt::Display for InternalError where - T: fmt::Display + 'static, + T: fmt::Debug + fmt::Display + 'static + Clone, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.inner, f) } } impl Error for InternalError where - T: fmt::Debug + fmt::Display + 'static, + T: fmt::Debug + fmt::Display + 'static + Clone, { fn status_code(&self) -> StatusCode { StatusCode::Err } diff --git a/rust-lib/flowy-sys/src/module/module.rs b/rust-lib/flowy-sys/src/module/module.rs index 42aaa650ef..01bad43ae8 100644 --- a/rust-lib/flowy-sys/src/module/module.rs +++ b/rust-lib/flowy-sys/src/module/module.rs @@ -11,7 +11,6 @@ use crate::{ error::InternalError, request::{payload::Payload, EventRequest}, response::EventResponse, - rt::SystemCommand, service::{factory, BoxServiceFactory, HandlerService}, }; use futures_core::{future::LocalBoxFuture, ready}; @@ -21,7 +20,6 @@ use std::{ future::Future, pin::Pin, rc::Rc, - sync::Arc, task::{Context, Poll}, }; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; diff --git a/rust-lib/flowy-sys/src/request/request.rs b/rust-lib/flowy-sys/src/request/request.rs index 7dfcc91bfb..12aafd415a 100644 --- a/rust-lib/flowy-sys/src/request/request.rs +++ b/rust-lib/flowy-sys/src/request/request.rs @@ -31,7 +31,7 @@ impl EventRequest { pub fn get_id(&self) -> &str { &self.id } - pub fn from_data(data: Vec) -> Self { unimplemented!() } + pub fn from_data(_data: Vec) -> Self { unimplemented!() } } pub trait FromRequest: Sized { diff --git a/rust-lib/flowy-sys/src/response/data.rs b/rust-lib/flowy-sys/src/response/data.rs index 03746285fa..4be2edd98f 100644 --- a/rust-lib/flowy-sys/src/response/data.rs +++ b/rust-lib/flowy-sys/src/response/data.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::{fmt, fmt::Formatter}; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub enum ResponseData { Bytes(Vec), None, diff --git a/rust-lib/flowy-sys/src/response/response.rs b/rust-lib/flowy-sys/src/response/response.rs index 6ffec1e0e6..0be953f41f 100644 --- a/rust-lib/flowy-sys/src/response/response.rs +++ b/rust-lib/flowy-sys/src/response/response.rs @@ -14,7 +14,7 @@ pub enum StatusCode { } // serde user guide: https://serde.rs/field-attrs.html -#[derive(Serialize, Debug)] +#[derive(Serialize, Debug, Clone)] pub struct EventResponse { #[serde(serialize_with = "serialize_data")] pub data: ResponseData, diff --git a/rust-lib/flowy-sys/src/rt/mod.rs b/rust-lib/flowy-sys/src/rt/mod.rs index b26dccd35e..4a0fa7d87a 100644 --- a/rust-lib/flowy-sys/src/rt/mod.rs +++ b/rust-lib/flowy-sys/src/rt/mod.rs @@ -1,5 +1,4 @@ pub use runtime::*; pub use crate::system::*; - -mod runtime; +pub mod runtime; diff --git a/rust-lib/flowy-sys/src/stream.rs b/rust-lib/flowy-sys/src/stream.rs index 233ee3e6fe..9dc0445514 100644 --- a/rust-lib/flowy-sys/src/stream.rs +++ b/rust-lib/flowy-sys/src/stream.rs @@ -1,18 +1,39 @@ use crate::{ error::{InternalError, SystemError}, - module::{Event, Module}, request::EventRequest, response::EventResponse, service::{BoxService, Service, ServiceFactory}, - system::ModuleServiceMap, + system::ModuleMap, }; use futures_core::{future::LocalBoxFuture, ready, task::Context}; -use std::{collections::HashMap, future::Future, rc::Rc}; +use std::future::Future; use tokio::{ macros::support::{Pin, Poll}, sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, }; +macro_rules! service_factor_impl { + ($name:ident) => { + #[allow(non_snake_case, missing_docs)] + impl ServiceFactory> for $name + where + T: 'static, + { + type Response = EventResponse; + type Error = SystemError; + type Service = BoxService, Self::Response, Self::Error>; + type Config = (); + type Future = LocalBoxFuture<'static, Result>; + + fn new_service(&self, _cfg: Self::Config) -> Self::Future { + let module_map = self.module_map.clone(); + let service = Box::new(CommandStreamService { module_map }); + Box::pin(async move { Ok(service as Self::Service) }) + } + } + }; +} + pub type BoxStreamCallback = Box; pub struct StreamData where @@ -20,46 +41,75 @@ where { config: T, request: Option, - callback: BoxStreamCallback, + callback: Option>, } impl StreamData { - pub fn new(config: T, request: Option, callback: BoxStreamCallback) -> Self { + pub fn new(config: T, request: Option) -> Self { Self { config, request, - callback, + callback: None, } } + + pub fn with_callback(mut self, callback: BoxStreamCallback) -> Self { + self.callback = Some(callback); + self + } } pub struct CommandStream where T: 'static, { - module_map: Option, + module_map: ModuleMap, data_tx: UnboundedSender>, - data_rx: UnboundedReceiver>, + data_rx: Option>>, } +service_factor_impl!(CommandStream); + impl CommandStream { - pub fn new() -> Self { + pub fn new(module_map: ModuleMap) -> Self { let (data_tx, data_rx) = unbounded_channel::>(); Self { - module_map: None, + module_map, data_tx, - data_rx, + data_rx: Some(data_rx), } } - pub fn send(&self, data: StreamData) { let _ = self.data_tx.send(data); } + pub fn async_send(&self, data: StreamData) { let _ = self.data_tx.send(data); } - pub fn module_service_map(&mut self, map: ModuleServiceMap) { self.module_map = Some(map) } + pub fn sync_send(&self, data: StreamData) -> EventResponse { + let factory = self.new_service(()); + + futures::executor::block_on(async { + let service = factory.await.unwrap(); + service.call(data).await.unwrap() + }) + } pub fn tx(&self) -> UnboundedSender> { self.data_tx.clone() } + + pub fn take_data_rx(&mut self) -> UnboundedReceiver> { self.data_rx.take().unwrap() } } -impl Future for CommandStream +pub struct CommandStreamFuture { + module_map: ModuleMap, + data_rx: UnboundedReceiver>, +} + +service_factor_impl!(CommandStreamFuture); + +impl CommandStreamFuture { + pub fn new(module_map: ModuleMap, data_rx: UnboundedReceiver>) -> Self { + Self { module_map, data_rx } + } +} + +impl Future for CommandStreamFuture where T: 'static, { @@ -80,41 +130,20 @@ where } } -impl ServiceFactory> for CommandStream -where - T: 'static, -{ - type Response = (); - type Error = SystemError; - type Service = BoxService, Self::Response, Self::Error>; - type Config = (); - type Future = LocalBoxFuture<'static, Result>; - - fn new_service(&self, _cfg: Self::Config) -> Self::Future { - let module_map = self.module_map.as_ref().unwrap().clone(); - let service = Box::new(CommandStreamService { module_map }); - Box::pin(async move { Ok(service as Self::Service) }) - } -} - pub struct CommandStreamService { - module_map: ModuleServiceMap, + module_map: ModuleMap, } -impl Service> for CommandStreamService -where - T: 'static, -{ - type Response = (); +impl Service> for CommandStreamService { + type Response = EventResponse; type Error = SystemError; type Future = LocalBoxFuture<'static, Result>; fn call(&self, mut data: StreamData) -> Self::Future { let module_map = self.module_map.clone(); - + let request = data.request.take().unwrap(); let fut = async move { - let request = data.request.take().unwrap(); - let result = || async { + let result = { match module_map.get(request.get_event()) { Some(module) => { let config = request.get_id().to_owned(); @@ -129,12 +158,12 @@ where } }; - match result().await { - Ok(resp) => (data.callback)(data.config, resp), - Err(e) => log::error!("{:?}", e), + let response = result.unwrap_or_else(|e| e.into()); + if let Some(callback) = data.callback { + callback(data.config, response.clone()); } - Ok(()) + Ok(response) }; Box::pin(fut) } diff --git a/rust-lib/flowy-sys/src/system.rs b/rust-lib/flowy-sys/src/system.rs index d35187681e..6dbb12ae6d 100644 --- a/rust-lib/flowy-sys/src/system.rs +++ b/rust-lib/flowy-sys/src/system.rs @@ -1,10 +1,7 @@ use crate::{ - error::SystemError, module::{Event, Module}, - request::EventRequest, - response::EventResponse, rt::Runtime, - stream::{CommandStream, CommandStreamService, StreamData}, + stream::CommandStreamFuture, }; use futures_core::{ready, task::Context}; use std::{cell::RefCell, collections::HashMap, future::Future, io, rc::Rc, sync::Arc}; @@ -23,19 +20,19 @@ thread_local!( #[derive(Debug)] pub enum SystemCommand { Exit(i8), - Response(EventResponse), } -pub type ModuleServiceMap = Rc>>; +pub type ModuleMap = Rc>>; pub struct FlowySystem { sys_cmd_tx: UnboundedSender, - module_map: ModuleServiceMap, } impl FlowySystem { - pub fn construct(module_factory: F, mut stream: CommandStream) -> SystemRunner + pub fn construct(module_factory: F, stream_factory: S) -> SystemRunner where F: FnOnce() -> Vec, + S: FnOnce(ModuleMap) -> CommandStreamFuture, + T: 'static, { let runtime = Runtime::new().unwrap(); let (sys_cmd_tx, sys_cmd_rx) = unbounded_channel::(); @@ -47,25 +44,18 @@ impl FlowySystem { }); let factory = module_factory(); - let mut module_service_map = HashMap::new(); + let mut module_map = HashMap::new(); factory.into_iter().for_each(|m| { let events = m.events(); let rc_module = Rc::new(m); events.into_iter().for_each(|e| { - module_service_map.insert(e, rc_module.clone()); + module_map.insert(e, rc_module.clone()); }); }); - let mut system = Self { - sys_cmd_tx: sys_cmd_tx.clone(), - module_map: Rc::new(HashMap::default()), - }; - - let map = Rc::new(module_service_map); - system.module_map = map.clone(); - stream.module_service_map(map.clone()); - - runtime.spawn(stream); + let system = Self { sys_cmd_tx }; + let stream_fut = stream_factory(Rc::new(module_map)); + runtime.spawn(stream_fut); FlowySystem::set_current(system); let runner = SystemRunner { rt: runtime, stop_rx }; @@ -81,8 +71,6 @@ impl FlowySystem { } } - pub fn module_map(&self) -> ModuleServiceMap { self.module_map.clone() } - #[doc(hidden)] pub fn set_current(sys: FlowySystem) { CURRENT.with(|cell| { @@ -115,9 +103,6 @@ impl Future for SystemController { let _ = tx.send(code); } }, - SystemCommand::Response(resp) => { - log::debug!("Response: {:?}", resp); - }, }, } } diff --git a/rust-lib/flowy-sys/tests/api/dart_ffi.rs b/rust-lib/flowy-sys/tests/api/dart_ffi.rs deleted file mode 100644 index 1b645abaf1..0000000000 --- a/rust-lib/flowy-sys/tests/api/dart_ffi.rs +++ /dev/null @@ -1,34 +0,0 @@ -use crate::helper::*; -use flowy_sys::{dart_ffi::*, prelude::*}; - -pub async fn no_params() -> String { "no params function call".to_string() } -pub async fn one_params(_s: String) -> String { "one params function call".to_string() } -pub async fn two_params(_s1: String, _s2: String) -> String { "two params function call".to_string() } - -#[test] -fn test_init() { - setup_env(); - - let no_params_command = "no params".to_string(); - let one_params_command = "one params".to_string(); - let two_params_command = "two params".to_string(); - - let modules = vec![Module::new() - .event(no_params_command.clone(), no_params) - .event(one_params_command.clone(), one_params) - .event(two_params_command.clone(), two_params)]; - - init_dart(modules, || { - let request = EventRequest::new(no_params_command); - let stream_data = StreamData::new( - 1, - Some(request), - Box::new(|config, response| { - log::info!("😁😁😁 {:?}", response); - }), - ); - - send(stream_data); - FlowySystem::current().stop(); - }); -} diff --git a/rust-lib/flowy-sys/tests/api/helper.rs b/rust-lib/flowy-sys/tests/api/helper.rs index d6546d5702..ac93b9e529 100644 --- a/rust-lib/flowy-sys/tests/api/helper.rs +++ b/rust-lib/flowy-sys/tests/api/helper.rs @@ -1,10 +1,15 @@ -use std::sync::Once; +use flowy_sys::prelude::{CommandStream, CommandStreamFuture, EventResponse, FlowySystem, Module, StreamData}; +use std::{ + cell::RefCell, + sync::{Once, RwLock}, + task::Context, +}; #[allow(dead_code)] pub fn setup_env() { static INIT: Once = Once::new(); INIT.call_once(|| { - std::env::set_var("RUST_LOG", "flowy_sys=trace,trace"); + std::env::set_var("RUST_LOG", "flowy_sys=debug,debug"); env_logger::init(); }); } @@ -14,3 +19,47 @@ pub struct ExecutorAction { } pub struct FlowySystemExecutor {} + +thread_local!( + static STREAM_SENDER: RefCell>> = RefCell::new(None); +); + +pub fn sync_send(data: StreamData) -> EventResponse { + STREAM_SENDER.with(|cell| match &*cell.borrow() { + Some(stream) => stream.sync_send(data), + None => panic!(""), + }) +} + +pub fn async_send(data: StreamData) { + STREAM_SENDER.with(|cell| match &*cell.borrow() { + Some(stream) => { + stream.async_send(data); + }, + None => panic!(""), + }); +} + +pub fn stop_system() { FlowySystem::current().stop(); } + +pub fn init_system(modules: Vec, f: F) +where + F: FnOnce() + 'static, +{ + FlowySystem::construct( + || modules, + |module_map| { + let mut stream = CommandStream::::new(module_map.clone()); + let stream_fut = CommandStreamFuture::new(module_map, stream.take_data_rx()); + + STREAM_SENDER.with(|cell| { + *cell.borrow_mut() = Some(stream); + }); + + stream_fut + }, + ) + .spawn(async { f() }) + .run() + .unwrap(); +} diff --git a/rust-lib/flowy-sys/tests/api/main.rs b/rust-lib/flowy-sys/tests/api/main.rs index 8814b112ec..21ac62726e 100644 --- a/rust-lib/flowy-sys/tests/api/main.rs +++ b/rust-lib/flowy-sys/tests/api/main.rs @@ -1,3 +1,2 @@ -mod dart_ffi; mod helper; mod module_event; diff --git a/rust-lib/flowy-sys/tests/api/module_event.rs b/rust-lib/flowy-sys/tests/api/module_event.rs index 0b6e2227b6..2e23ebce6f 100644 --- a/rust-lib/flowy-sys/tests/api/module_event.rs +++ b/rust-lib/flowy-sys/tests/api/module_event.rs @@ -6,36 +6,27 @@ pub async fn one_params(_s: String) -> String { "one params function call".to_st pub async fn two_params(_s1: String, _s2: String) -> String { "two params function call".to_string() } #[test] -fn test() { +fn test_init() { setup_env(); let no_params_command = "no params".to_string(); let one_params_command = "one params".to_string(); let two_params_command = "two params".to_string(); - let stream = CommandStream::::new(); - let tx = stream.tx(); - FlowySystem::construct( - || { - vec![Module::new() - .event(no_params_command.clone(), no_params) - .event(one_params_command.clone(), one_params) - .event(two_params_command.clone(), two_params)] - }, - stream, - ) - .spawn(async move { - let request = EventRequest::new(no_params_command.clone()); - let stream_data = StreamData::new( - 1, - Some(request), - Box::new(|config, response| { - log::info!("{:?}", response); - }), - ); - tx.send(stream_data); - FlowySystem::current().stop(); - }) - .run() - .unwrap(); + let modules = vec![Module::new() + .event(no_params_command.clone(), no_params) + .event(one_params_command.clone(), one_params) + .event(two_params_command.clone(), two_params)]; + + init_system(modules, || { + let request = EventRequest::new(no_params_command); + let stream_data = StreamData::new(1, Some(request)).with_callback(Box::new(|_config, response| { + log::info!("async resp: {:?}", response); + })); + + let resp = sync_send(stream_data); + log::info!("sync resp: {:?}", resp); + + stop_system(); + }); } diff --git a/scripts/makefile/db.toml b/scripts/makefile/db.toml deleted file mode 100644 index 3abea8e265..0000000000 --- a/scripts/makefile/db.toml +++ /dev/null @@ -1,8 +0,0 @@ -[tasks.setup-diesel] -script = [ - """ - brew install sqlite3 - cargo install diesel_cli --no-default-features --features sqlite - """, -] -script_runner = "@shell" diff --git a/scripts/makefile/desktop.toml b/scripts/makefile/desktop.toml index b5fdafb44e..3aee8610b2 100644 --- a/scripts/makefile/desktop.toml +++ b/scripts/makefile/desktop.toml @@ -1,7 +1,7 @@ [tasks.desktop] category = "Build" -dependencies = ["cqrs_gen", "desktop-debug", "desktop-release", "post-desktop"] +dependencies = ["desktop-debug", "desktop-release", "post-desktop"] description = "Build desktop targets" [tasks.desktop-debug] @@ -18,16 +18,14 @@ private = true run_task = "desktop-build" [tasks.desktop-build] -# args = ["build", "--target", "${DESKTOP_TARGET}"] category = "Build" -# command = "cargo" condition = { platforms = ["mac"], env_true = ["DEV"] } dependencies = ["export-env", "setup-crate-type-macos"] description = "Build desktop targets." script = [ """ cd rust-lib/ - cargo build --package=flowy-ffi --target ${DESKTOP_TARGET} + cargo build --package=dart-ffi --target ${DESKTOP_TARGET} cd ../ """, ] @@ -37,12 +35,13 @@ condition = { platforms = ["mac"] } dependencies = ["restore-crate-type"] script = [ """ + echo ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY} cp ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/target/x86_64-apple-darwin/${LIB_OUT_DIR}/lib${CARGO_MAKE_CRATE_FS_NAME}.dylib \ - ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/flutter-lib/packages/flowy_sdk/macos/lib${CARGO_MAKE_CRATE_FS_NAME}.dylib + ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/packages/flowy_sdk/macos/lib${CARGO_MAKE_CRATE_FS_NAME}.dylib """, """ cp ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/binding.h \ - ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/flutter-lib/packages/flowy_sdk/macos/Classes/binding.h + ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/packages/flowy_sdk/macos/Classes/binding.h """, ] script_runner = "@duckscript" @@ -55,13 +54,6 @@ run_task = "setup-crate-type" [tasks.export-env] script = [ """ -# Try to fix the issue -# ld: warning: dylib (/Users/vedon/Documents/Private/RustProject/App-Flowy/app_flowy/flutter-lib/packages/flowy_sdk/macos/libflowy_ffi.dylib) was built for newer macOS version (10.15) than being linked (10.11) -# ld: warning: dylib (/Users/vedon/Documents/Private/RustProject/App-Flowy/app_flowy/flutter-lib/packages/flowy_sdk/macos/libflowy_ffi.dylib) was built for newer macOS version (10.15) than being linked (10.11) -# https://users.rust-lang.org/t/compile-rust-binary-for-older-versions-of-mac-osx/38695/3 -# https://stackoverflow.com/questions/43216273/object-file-was-built-for-newer-osx-version-than-being-linked - - export MACOSX_DEPLOYMENT_TARGET=10.11 """, ] @@ -71,7 +63,7 @@ script_runner = "@shell" condition = { platforms = ["mac"] } script = [ """ - target_path = set ${TMPDIR}/app_flowy/lib${CARGO_MAKE_CRATE_FS_NAME}.dylib + target_path = set ${TMPDIR}/appflowy_client/lib${CARGO_MAKE_CRATE_FS_NAME}.dylib echo "remove old dylib" rm ${target_path} echo "copy new dylib to system" @@ -91,13 +83,3 @@ script = [ script_runner = "@shell" -[tasks.cqrs_gen] -script = [ - """ - manifest_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/scripts/tool/rust-tool/Cargo.toml - cqrs_file=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-store/src/entities/command.rs - output_file=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/flutter-lib/packages/flowy_sdk/lib/cqrs/auto_gen.dart - cargo run --manifest-path ${manifest_path} flutter --cqrs=${cqrs_file} --output=${output_file} - """, -] -script_runner = "@shell" diff --git a/scripts/makefile/pb.toml b/scripts/makefile/pb.toml deleted file mode 100644 index c9d7d7359a..0000000000 --- a/scripts/makefile/pb.toml +++ /dev/null @@ -1,49 +0,0 @@ - - -[tasks.pb_init_setup_dev] -description = "Setup protobuf" -script = [ - """ - brew tap dart-lang/dart - brew install dart - pub global activate protoc_plugin - cargo install --force --version 2.18.0 protobuf-codegen - """, -] -script_runner = "@shell" - -[tasks.gen_pb_file] -script = [ - """ - pb_gen_exec=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/scripts/tool/rust-tool/Cargo.toml - proto_source_file=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-store/src/entities/ - proto_define_dir=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define - derive_file=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-ast/src/auto_gen_file/category_from_str.rs - rust_mod_file=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/src/model/mod.rs - flutter_mod_file=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/flutter-lib/packages/flowy_protobuf/lib/all.dart - cargo run --manifest-path ${pb_gen_exec} pb-gen -i=${proto_source_file} --derive_file=${derive_file} --proto_define_dir=${proto_define_dir} --rust_mod_file=${rust_mod_file} --flutter_mod_file=${flutter_mod_file} - """, -] -script_runner = "@shell" - -[tasks.gen_rust_pb] -script = [ - """ - protoc --rust_out=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/src/model \ - --proto_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define \ - ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define/*.proto - """, -] -script_runner = "@shell" - -[tasks.gen_dart_pb] -script = [ - """ - dart_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/flutter-lib/packages/flowy_protobuf/lib/model - pb_define_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define - pb_proto_files=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define/*.proto - rm -rf ${dart_path}/* - protoc --dart_out=${dart_path} --proto_path=${pb_define_path} ${pb_proto_files} - """, -] -script_runner = "@shell"