From 4febb15f0849cdbe6656c8e1d210e1ecec3770ca Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 28 Jun 2021 23:58:43 +0800 Subject: [PATCH] add ffi sync interface --- app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart | 20 +++++++ rust-lib/dart-ffi/binding.h | 2 + rust-lib/dart-ffi/src/c.rs | 26 +++++++++ rust-lib/dart-ffi/src/lib.rs | 30 ++++------- rust-lib/flowy-sdk/Cargo.toml | 1 + rust-lib/flowy-sdk/src/lib.rs | 53 +++++++++++++++++++ 6 files changed, 112 insertions(+), 20 deletions(-) create mode 100644 rust-lib/dart-ffi/src/c.rs diff --git a/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart b/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart index 07ffbb89e6..7dc5fa8e2f 100644 --- a/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart +++ b/app_flowy/packages/flowy_sdk/lib/ffi/ffi.dart @@ -45,6 +45,26 @@ 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 `init_sdk`. int init_sdk( Pointer path, diff --git a/rust-lib/dart-ffi/binding.h b/rust-lib/dart-ffi/binding.h index ac6bcf50e4..0455d23a96 100644 --- a/rust-lib/dart-ffi/binding.h +++ b/rust-lib/dart-ffi/binding.h @@ -8,4 +8,6 @@ int64_t init_sdk(char *path); void async_command(int64_t port, const uint8_t *input, uintptr_t len); +const uint8_t *sync_command(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/c.rs b/rust-lib/dart-ffi/src/c.rs new file mode 100644 index 0000000000..f5ed57fa59 --- /dev/null +++ b/rust-lib/dart-ffi/src/c.rs @@ -0,0 +1,26 @@ +use byteorder::{BigEndian, ByteOrder}; +use flowy_protobuf::ResponsePacket; +use std::mem::{forget, size_of}; + +pub fn forget_rust(buf: Vec) -> *const u8 { + let ptr = buf.as_ptr(); + forget(buf); + ptr +} + +#[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); + } +} + +pub fn extend_front_four_bytes_into_bytes(bytes: &[u8]) -> Vec { + let mut output = Vec::with_capacity(bytes.len() + 4); + let mut marker_bytes = [0; 4]; + BigEndian::write_u32(&mut marker_bytes, bytes.len() as u32); + output.extend_from_slice(&marker_bytes); + output.extend_from_slice(bytes); + output +} diff --git a/rust-lib/dart-ffi/src/lib.rs b/rust-lib/dart-ffi/src/lib.rs index 19e3fa191c..fd72252596 100644 --- a/rust-lib/dart-ffi/src/lib.rs +++ b/rust-lib/dart-ffi/src/lib.rs @@ -1,3 +1,7 @@ +mod c; + +use crate::c::forget_rust; +use flowy_sdk::*; use flowy_sys::prelude::*; use std::{cell::RefCell, ffi::CStr, os::raw::c_char}; @@ -21,26 +25,12 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) { async_send(stream_data); } +#[no_mangle] +pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 { + let bytes = unsafe { std::slice::from_raw_parts(input, len) }.to_vec(); + forget_rust(bytes) +} + #[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 index 87c0481969..197f6ed2d6 100644 --- a/rust-lib/flowy-sdk/Cargo.toml +++ b/rust-lib/flowy-sdk/Cargo.toml @@ -6,3 +6,4 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +flowy-sys = { path = "../flowy-sys" } \ No newline at end of file diff --git a/rust-lib/flowy-sdk/src/lib.rs b/rust-lib/flowy-sdk/src/lib.rs index 8b13789179..c5adb37c35 100644 --- a/rust-lib/flowy-sdk/src/lib.rs +++ b/rust-lib/flowy-sdk/src/lib.rs @@ -1 +1,54 @@ +use flowy_sys::prelude::*; +use std::cell::RefCell; +pub struct FlowySDK {} + +impl FlowySDK { + pub fn init(path: &str) { + let modules = init_modules(); + init_system(modules); + } +} + +pub fn init_modules() -> Vec { + let modules = vec![]; + modules +} + +pub fn init_system(modules: Vec) { + 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 + }, + ) + .run() + .unwrap(); +} + +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!(""), + }); +}