lib.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. mod c;
  2. use crate::c::{extend_front_four_bytes_into_bytes, forget_rust};
  3. use flowy_sdk::*;
  4. use flowy_sys::prelude::*;
  5. use lazy_static::lazy_static;
  6. use std::{ffi::CStr, future::Future, os::raw::c_char};
  7. lazy_static! {
  8. pub static ref FFI_RUNTIME: tokio::runtime::Runtime =
  9. tokio::runtime::Builder::new_current_thread()
  10. .thread_name("flowy-dart-ffi")
  11. .build()
  12. .unwrap();
  13. }
  14. #[no_mangle]
  15. pub extern "C" fn init_sdk(path: *mut c_char) -> i64 {
  16. let c_str: &CStr = unsafe { CStr::from_ptr(path) };
  17. let path: &str = c_str.to_str().unwrap();
  18. FlowySDK::init_log(path);
  19. FlowySDK::init(path);
  20. return 1;
  21. }
  22. #[no_mangle]
  23. pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
  24. let mut request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
  25. log::trace!(
  26. "[FFI]: {} Async Event: {:?} with {} port",
  27. &request.id,
  28. &request.event,
  29. port
  30. );
  31. request = request.callback(Box::new(move |resp: EventResponse| {
  32. let bytes = match resp.payload {
  33. Payload::Bytes(bytes) => bytes,
  34. Payload::None => vec![],
  35. };
  36. log::trace!("[FFI]: Post data to dart through {} port", port);
  37. Box::pin(spawn_future(async { bytes }, port))
  38. }));
  39. let _ = EventDispatch::async_send(request);
  40. }
  41. #[no_mangle]
  42. pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 {
  43. let request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
  44. log::trace!("[FFI]: {} Sync Event: {:?}", &request.id, &request.event,);
  45. let _response = EventDispatch::sync_send(request);
  46. // FFIResponse { }
  47. let response_bytes = vec![];
  48. let result = extend_front_four_bytes_into_bytes(&response_bytes);
  49. forget_rust(result)
  50. }
  51. #[inline(never)]
  52. #[no_mangle]
  53. pub extern "C" fn link_me_please() {}
  54. #[derive(serde::Deserialize)]
  55. pub struct FFIRequest {
  56. event: String,
  57. payload: Vec<u8>,
  58. }
  59. impl FFIRequest {
  60. pub fn from_u8_pointer(pointer: *const u8, len: usize) -> Self {
  61. let bytes = unsafe { std::slice::from_raw_parts(pointer, len) }.to_vec();
  62. let request: FFIRequest = serde_json::from_slice(&bytes).unwrap();
  63. request
  64. }
  65. }
  66. #[derive(serde::Serialize)]
  67. pub struct FFIResponse {
  68. event: String,
  69. payload: Vec<u8>,
  70. error: String,
  71. }
  72. #[inline(always)]
  73. async fn spawn_future<F>(future: F, port: i64)
  74. where
  75. F: Future<Output = Vec<u8>> + Send + 'static,
  76. {
  77. let isolate = allo_isolate::Isolate::new(port);
  78. match isolate.catch_unwind(future).await {
  79. Ok(_success) => {
  80. log::trace!("[FFI]: Post data to dart success");
  81. },
  82. Err(e) => {
  83. if let Some(msg) = e.downcast_ref::<&str>() {
  84. log::error!("[FFI]: {:?}", msg);
  85. } else {
  86. log::error!("[FFI]: allo_isolate post panic");
  87. }
  88. },
  89. }
  90. }
  91. impl std::convert::From<FFIRequest> for DispatchRequest {
  92. fn from(ffi_request: FFIRequest) -> Self {
  93. let payload = if !ffi_request.payload.is_empty() {
  94. Payload::Bytes(ffi_request.payload)
  95. } else {
  96. Payload::None
  97. };
  98. let request = DispatchRequest::new(ffi_request.event, payload);
  99. request
  100. }
  101. }