瀏覽代碼

add ffi sync interface

appflowy 3 年之前
父節點
當前提交
4febb15f08

+ 20 - 0
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<Uint8> sync_command(
+    Pointer<Uint8> 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<Uint8> Function(
+    Pointer<Uint8> input,
+    Uint64 len,
+    );
+typedef _invoke_sync_Dart = Pointer<Uint8> Function(
+    Pointer<Uint8> input,
+    int len,
+    );
+
 /// C function `init_sdk`.
 int init_sdk(
   Pointer<ffi.Utf8> path,

+ 2 - 0
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);

+ 26 - 0
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<u8>) -> *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<u8> {
+    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
+}

+ 10 - 20
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);
 }
 
-#[inline(never)]
 #[no_mangle]
-pub extern "C" fn link_me_please() {}
-
-thread_local!(
-    static STREAM_SENDER: RefCell<Option<CommandStream<i64>>> = RefCell::new(None);
-);
-
-pub fn sync_send(data: StreamData<i64>) -> EventResponse {
-    STREAM_SENDER.with(|cell| match &*cell.borrow() {
-        Some(stream) => stream.sync_send(data),
-        None => panic!(""),
-    })
+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)
 }
 
-pub fn async_send(data: StreamData<i64>) {
-    STREAM_SENDER.with(|cell| match &*cell.borrow() {
-        Some(stream) => {
-            stream.async_send(data);
-        },
-        None => panic!(""),
-    });
-}
+#[inline(never)]
+#[no_mangle]
+pub extern "C" fn link_me_please() {}

+ 1 - 0
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" }

+ 53 - 0
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<Module> {
+    let modules = vec![];
+    modules
+}
+
+pub fn init_system<F>(modules: Vec<Module>) {
+    FlowySystem::construct(
+        || modules,
+        |module_map| {
+            let mut stream = CommandStream::<i64>::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<Option<CommandStream<i64>>> = RefCell::new(None);
+);
+
+pub fn sync_send(data: StreamData<i64>) -> EventResponse {
+    STREAM_SENDER.with(|cell| match &*cell.borrow() {
+        Some(stream) => stream.sync_send(data),
+        None => panic!(""),
+    })
+}
+
+pub fn async_send(data: StreamData<i64>) {
+    STREAM_SENDER.with(|cell| match &*cell.borrow() {
+        Some(stream) => {
+            stream.async_send(data);
+        },
+        None => panic!(""),
+    });
+}