codemp/src/ffi/js/cursor.rs

83 lines
2.2 KiB
Rust

use napi::threadsafe_function::ErrorStrategy::Fatal;
use napi_derive::napi;
use napi::threadsafe_function::{ThreadsafeFunction, ThreadSafeCallContext, ThreadsafeFunctionCallMode};
use crate::api::Controller;
use crate::cursor::controller::CursorController;
#[napi(object, js_name = "Cursor")]
pub struct JsCursor {
/// range of text change, as char indexes in buffer previous state
pub start_row: i32,
pub start_col: i32,
pub end_row: i32,
pub end_col: i32,
pub buffer: String,
pub user: Option<String>,
}
impl From<JsCursor> for crate::api::Cursor {
fn from(value: JsCursor) -> Self {
crate::api::Cursor {
start : (value.start_row, value.start_col),
end: (value.end_row, value.end_col),
buffer: value.buffer,
user: value.user,
}
}
}
impl From<crate::api::Cursor> for JsCursor {
fn from(value: crate::api::Cursor) -> Self {
JsCursor {
start_row : value.start.0,
start_col : value.start.1,
end_row : value.end.0,
end_col: value.end.1,
buffer: value.buffer,
user: value.user.map(|x| x.to_string())
}
}
}
#[napi]
impl CursorController {
#[napi(js_name = "callback", ts_args_type = "fun: (event: CursorController) => void")]
pub fn js_callback(&self, fun: napi::JsFunction) -> napi::Result<()>{
let tsfn : ThreadsafeFunction<crate::cursor::controller::CursorController, Fatal> =
fun.create_threadsafe_function(0,
|ctx : ThreadSafeCallContext<crate::cursor::controller::CursorController>| {
Ok(vec![ctx.value])
}
)?;
self.callback(move |controller : CursorController| {
tsfn.call(controller.clone(), ThreadsafeFunctionCallMode::Blocking); //check this with tracing also we could use Ok(event) to get the error
// If it blocks the main thread too many time we have to change this
});
Ok(())
}
#[napi(js_name = "send")]
pub async fn js_send(&self, pos: JsCursor) -> napi::Result<()> {
Ok(self.send(crate::api::Cursor::from(pos)).await?)
}
#[napi(js_name= "try_recv")]
pub async fn js_try_recv(&self) -> napi::Result<Option<JsCursor>> {
Ok(self.try_recv().await?
.map(JsCursor::from))
}
#[napi(js_name= "recv")]
pub async fn js_recv(&self) -> napi::Result<JsCursor> {
Ok(self.recv().await?.into())
}
}