mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-21 23:04:49 +01:00
Merge pull request #67 from hexedtech/feat/lua-bump
feat: bump mlua version
This commit is contained in:
commit
b48a410816
15 changed files with 123 additions and 64 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -240,7 +240,7 @@ dependencies = [
|
||||||
"jni",
|
"jni",
|
||||||
"jni-toolbox",
|
"jni-toolbox",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"mlua-codemp-patch",
|
"mlua",
|
||||||
"napi",
|
"napi",
|
||||||
"napi-build",
|
"napi-build",
|
||||||
"napi-derive",
|
"napi-derive",
|
||||||
|
@ -911,12 +911,13 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mlua-codemp-patch"
|
name = "mlua"
|
||||||
version = "0.10.0-beta.2"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a52f529509c236114a5cf5bb3c0c06ff0695ad45d718256930ec2416edf3817"
|
checksum = "0ae9546e4a268c309804e8bbb7526e31cbfdedca7cd60ac1b987d0b212e0d876"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
|
"either",
|
||||||
"erased-serde",
|
"erased-serde",
|
||||||
"mlua-sys",
|
"mlua-sys",
|
||||||
"mlua_derive",
|
"mlua_derive",
|
||||||
|
@ -929,9 +930,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mlua-sys"
|
name = "mlua-sys"
|
||||||
version = "0.6.4"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9eebac25c35a13285456c88ee2fde93d9aee8bcfdaf03f9d6d12be3391351ec"
|
checksum = "efa6bf1a64f06848749b7e7727417f4ec2121599e2a10ef0a8a3888b0e9a5a0d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
@ -940,9 +941,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mlua_derive"
|
name = "mlua_derive"
|
||||||
version = "0.10.0-beta.1"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13e6f40fa1fd8426285688f4a37b56beac69284743d057ee6db352b543f4b621"
|
checksum = "2cfc5faa2e0d044b3f5f0879be2920e0a711c97744c42cf1c295cb183668933e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -44,7 +44,7 @@ jni = { version = "0.21", features = ["invocation"], optional = true }
|
||||||
jni-toolbox = { version = "0.2", optional = true, features = ["uuid"] }
|
jni-toolbox = { version = "0.2", optional = true, features = ["uuid"] }
|
||||||
|
|
||||||
# glue (lua)
|
# glue (lua)
|
||||||
mlua-codemp-patch = { version = "0.10.0-beta.2", features = ["module", "send", "serialize"], optional = true }
|
mlua = { version = "0.10", features = ["module", "serialize", "error-send"], optional = true }
|
||||||
|
|
||||||
# glue (js)
|
# glue (js)
|
||||||
napi = { version = "2.16", features = ["full"], optional = true }
|
napi = { version = "2.16", features = ["full"], optional = true }
|
||||||
|
@ -74,10 +74,10 @@ test-e2e = []
|
||||||
java = ["dep:lazy_static", "dep:jni", "dep:tracing-subscriber", "dep:jni-toolbox"]
|
java = ["dep:lazy_static", "dep:jni", "dep:tracing-subscriber", "dep:jni-toolbox"]
|
||||||
js = ["dep:napi-build", "dep:tracing-subscriber", "dep:napi", "dep:napi-derive"]
|
js = ["dep:napi-build", "dep:tracing-subscriber", "dep:napi", "dep:napi-derive"]
|
||||||
py = ["dep:pyo3", "dep:tracing-subscriber", "dep:pyo3-build-config"]
|
py = ["dep:pyo3", "dep:tracing-subscriber", "dep:pyo3-build-config"]
|
||||||
lua = ["serialize", "dep:mlua-codemp-patch", "dep:tracing-subscriber", "dep:lazy_static"]
|
lua = ["serialize", "dep:mlua", "dep:tracing-subscriber", "dep:lazy_static"]
|
||||||
# ffi variants
|
# ffi variants
|
||||||
lua-jit = ["mlua-codemp-patch?/luajit"]
|
lua-jit = ["mlua?/luajit"]
|
||||||
lua-54 = ["mlua-codemp-patch?/lua54"]
|
lua-54 = ["mlua?/lua54"]
|
||||||
py-abi3 = ["pyo3?/abi3-py38"]
|
py-abi3 = ["pyo3?/abi3-py38"]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,14 @@ use crate::ext::IgnorableError;
|
||||||
pub struct BufferController(pub(crate) Arc<BufferControllerInner>);
|
pub struct BufferController(pub(crate) Arc<BufferControllerInner>);
|
||||||
|
|
||||||
impl BufferController {
|
impl BufferController {
|
||||||
|
/// Get id of workspace containing this controller
|
||||||
|
pub fn workspace_id(&self) -> &str {
|
||||||
|
&self.0.workspace_id
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the buffer path.
|
/// Get the buffer path.
|
||||||
pub fn path(&self) -> &str {
|
pub fn path(&self) -> &str {
|
||||||
&self.0.name
|
&self.0.path
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return buffer whole content, updating internal acknowledgement tracker.
|
/// Return buffer whole content, updating internal acknowledgement tracker.
|
||||||
|
@ -50,7 +55,7 @@ impl BufferController {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct BufferControllerInner {
|
pub(crate) struct BufferControllerInner {
|
||||||
pub(crate) name: String,
|
pub(crate) path: String,
|
||||||
pub(crate) latest_version: watch::Receiver<diamond_types::LocalVersion>,
|
pub(crate) latest_version: watch::Receiver<diamond_types::LocalVersion>,
|
||||||
pub(crate) local_version: watch::Receiver<diamond_types::LocalVersion>,
|
pub(crate) local_version: watch::Receiver<diamond_types::LocalVersion>,
|
||||||
pub(crate) ops_in: mpsc::UnboundedSender<TextChange>,
|
pub(crate) ops_in: mpsc::UnboundedSender<TextChange>,
|
||||||
|
@ -59,6 +64,7 @@ pub(crate) struct BufferControllerInner {
|
||||||
pub(crate) delta_request: mpsc::Sender<oneshot::Sender<Option<BufferUpdate>>>,
|
pub(crate) delta_request: mpsc::Sender<oneshot::Sender<Option<BufferUpdate>>>,
|
||||||
pub(crate) callback: watch::Sender<Option<ControllerCallback<BufferController>>>,
|
pub(crate) callback: watch::Sender<Option<ControllerCallback<BufferController>>>,
|
||||||
pub(crate) ack_tx: mpsc::UnboundedSender<LocalVersion>,
|
pub(crate) ack_tx: mpsc::UnboundedSender<LocalVersion>,
|
||||||
|
pub(crate) workspace_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "async-trait", async_trait::async_trait)]
|
#[cfg_attr(feature = "async-trait", async_trait::async_trait)]
|
||||||
|
|
|
@ -40,6 +40,7 @@ impl BufferController {
|
||||||
path: &str,
|
path: &str,
|
||||||
tx: mpsc::Sender<Operation>,
|
tx: mpsc::Sender<Operation>,
|
||||||
rx: Streaming<BufferEvent>,
|
rx: Streaming<BufferEvent>,
|
||||||
|
workspace_id: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let init = diamond_types::LocalVersion::default();
|
let init = diamond_types::LocalVersion::default();
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ impl BufferController {
|
||||||
let agent_id = oplog.get_or_create_agent_id(&user_id.to_string());
|
let agent_id = oplog.get_or_create_agent_id(&user_id.to_string());
|
||||||
|
|
||||||
let controller = Arc::new(BufferControllerInner {
|
let controller = Arc::new(BufferControllerInner {
|
||||||
name: path.to_string(),
|
path: path.to_string(),
|
||||||
latest_version: latest_version_rx,
|
latest_version: latest_version_rx,
|
||||||
local_version: my_version_rx,
|
local_version: my_version_rx,
|
||||||
ops_in: opin_tx,
|
ops_in: opin_tx,
|
||||||
|
@ -66,6 +67,7 @@ impl BufferController {
|
||||||
delta_request: recv_tx,
|
delta_request: recv_tx,
|
||||||
callback: cb_tx,
|
callback: cb_tx,
|
||||||
ack_tx,
|
ack_tx,
|
||||||
|
workspace_id: workspace_id.to_string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let weak = Arc::downgrade(&controller);
|
let weak = Arc::downgrade(&controller);
|
||||||
|
|
|
@ -25,12 +25,19 @@ use codemp_proto::{
|
||||||
#[cfg_attr(feature = "js", napi_derive::napi)]
|
#[cfg_attr(feature = "js", napi_derive::napi)]
|
||||||
pub struct CursorController(pub(crate) Arc<CursorControllerInner>);
|
pub struct CursorController(pub(crate) Arc<CursorControllerInner>);
|
||||||
|
|
||||||
|
impl CursorController {
|
||||||
|
pub fn workspace_id(&self) -> &str {
|
||||||
|
&self.0.workspace_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct CursorControllerInner {
|
pub(crate) struct CursorControllerInner {
|
||||||
pub(crate) op: mpsc::UnboundedSender<CursorPosition>,
|
pub(crate) op: mpsc::UnboundedSender<CursorPosition>,
|
||||||
pub(crate) stream: mpsc::Sender<oneshot::Sender<Option<Cursor>>>,
|
pub(crate) stream: mpsc::Sender<oneshot::Sender<Option<Cursor>>>,
|
||||||
pub(crate) poll: mpsc::UnboundedSender<oneshot::Sender<()>>,
|
pub(crate) poll: mpsc::UnboundedSender<oneshot::Sender<()>>,
|
||||||
pub(crate) callback: watch::Sender<Option<ControllerCallback<CursorController>>>,
|
pub(crate) callback: watch::Sender<Option<ControllerCallback<CursorController>>>,
|
||||||
|
pub(crate) workspace_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "async-trait", async_trait::async_trait)]
|
#[cfg_attr(feature = "async-trait", async_trait::async_trait)]
|
||||||
|
|
|
@ -28,6 +28,7 @@ impl CursorController {
|
||||||
user_map: Arc<dashmap::DashMap<Uuid, User>>,
|
user_map: Arc<dashmap::DashMap<Uuid, User>>,
|
||||||
tx: mpsc::Sender<CursorPosition>,
|
tx: mpsc::Sender<CursorPosition>,
|
||||||
rx: Streaming<CursorEvent>,
|
rx: Streaming<CursorEvent>,
|
||||||
|
workspace_id: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// TODO we should tweak the channel buffer size to better propagate backpressure
|
// TODO we should tweak the channel buffer size to better propagate backpressure
|
||||||
let (op_tx, op_rx) = mpsc::unbounded_channel();
|
let (op_tx, op_rx) = mpsc::unbounded_channel();
|
||||||
|
@ -39,6 +40,7 @@ impl CursorController {
|
||||||
stream: stream_tx,
|
stream: stream_tx,
|
||||||
callback: cb_tx,
|
callback: cb_tx,
|
||||||
poll: poll_tx,
|
poll: poll_tx,
|
||||||
|
workspace_id: workspace_id.to_string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let weak = Arc::downgrade(&controller);
|
let weak = Arc::downgrade(&controller);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
|
|
||||||
use super::ext::a_sync::a_sync;
|
use super::ext::a_sync::a_sync;
|
||||||
|
|
||||||
|
@ -31,11 +30,23 @@ impl LuaUserData for CodempBufferController {
|
||||||
|_, this, ()| a_sync! { this => this.content().await? },
|
|_, this, ()| a_sync! { this => this.content().await? },
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("clear_callback", |_, this, ()| Ok(this.clear_callback()));
|
methods.add_method("clear_callback", move |lua, this, ()| {
|
||||||
methods.add_method("callback", |_, this, (cb,): (LuaFunction,)| {
|
this.clear_callback();
|
||||||
|
lua.unset_named_registry_value(&this.lua_callback_id())
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_method("callback", move |lua, this, (cb,): (LuaFunction,)| {
|
||||||
|
let key = this.lua_callback_id();
|
||||||
|
lua.set_named_registry_value(&key, cb)?;
|
||||||
Ok(this.callback(move |controller: CodempBufferController| {
|
Ok(this.callback(move |controller: CodempBufferController| {
|
||||||
super::ext::callback().invoke(cb.clone(), controller)
|
super::ext::callback().invoke(key.clone(), controller, false)
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CodempBufferController {
|
||||||
|
fn lua_callback_id(&self) -> String {
|
||||||
|
format!("codemp-buffercontroller({}:{})-callback-registry", self.workspace_id(), self.path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
|
|
||||||
use super::ext::a_sync::a_sync;
|
use super::ext::a_sync::a_sync;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
|
|
||||||
use super::ext::a_sync::a_sync;
|
use super::ext::a_sync::a_sync;
|
||||||
|
|
||||||
|
@ -22,11 +21,22 @@ impl LuaUserData for CodempCursorController {
|
||||||
methods.add_method("recv", |_, this, ()| a_sync! { this => this.recv().await? });
|
methods.add_method("recv", |_, this, ()| a_sync! { this => this.recv().await? });
|
||||||
methods.add_method("poll", |_, this, ()| a_sync! { this => this.poll().await? });
|
methods.add_method("poll", |_, this, ()| a_sync! { this => this.poll().await? });
|
||||||
|
|
||||||
methods.add_method("clear_callback", |_, this, ()| Ok(this.clear_callback()));
|
methods.add_method("clear_callback", |lua, this, ()| {
|
||||||
methods.add_method("callback", |_, this, (cb,): (LuaFunction,)| {
|
this.clear_callback();
|
||||||
|
lua.unset_named_registry_value(&this.lua_callback_id())
|
||||||
|
});
|
||||||
|
methods.add_method("callback", |lua, this, (cb,): (LuaFunction,)| {
|
||||||
|
let key = this.lua_callback_id();
|
||||||
|
lua.set_named_registry_value(&key, cb)?;
|
||||||
Ok(this.callback(move |controller: CodempCursorController| {
|
Ok(this.callback(move |controller: CodempCursorController| {
|
||||||
super::ext::callback().invoke(cb.clone(), controller)
|
super::ext::callback().invoke(key.clone(), controller, false)
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CodempCursorController {
|
||||||
|
fn lua_callback_id(&self) -> String {
|
||||||
|
format!("codemp-cursorcontroller({})-callback-registry", self.workspace_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
|
|
||||||
pub(crate) fn tokio() -> &'static tokio::runtime::Runtime {
|
pub(crate) fn tokio() -> &'static tokio::runtime::Runtime {
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
@ -21,7 +20,8 @@ macro_rules! a_sync {
|
||||||
Some(
|
Some(
|
||||||
crate::ffi::lua::ext::a_sync::tokio()
|
crate::ffi::lua::ext::a_sync::tokio()
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
Ok(crate::ffi::lua::ext::callback::CallbackArg::from($x))
|
let res = $x;
|
||||||
|
Ok(crate::ffi::lua::ext::callback::CallbackArg::from(res))
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -47,13 +47,20 @@ impl LuaUserData for Promise {
|
||||||
// TODO: await MUST NOT be used in callbacks!!
|
// TODO: await MUST NOT be used in callbacks!!
|
||||||
methods.add_method_mut("await", |_, this, ()| match this.0.take() {
|
methods.add_method_mut("await", |_, this, ()| match this.0.take() {
|
||||||
None => Err(LuaError::runtime("Promise already awaited")),
|
None => Err(LuaError::runtime("Promise already awaited")),
|
||||||
Some(x) => tokio().block_on(x).map_err(LuaError::runtime)?,
|
Some(x) => Ok(
|
||||||
|
tokio()
|
||||||
|
.block_on(x)
|
||||||
|
.map_err(LuaError::runtime)?
|
||||||
|
.map_err(LuaError::runtime)?
|
||||||
|
),
|
||||||
});
|
});
|
||||||
methods.add_method_mut("cancel", |_, this, ()| match this.0.take() {
|
methods.add_method_mut("cancel", |_, this, ()| match this.0.take() {
|
||||||
None => Err(LuaError::runtime("Promise already awaited")),
|
None => Err(LuaError::runtime("Promise already awaited")),
|
||||||
Some(x) => Ok(x.abort()),
|
Some(x) => Ok(x.abort()),
|
||||||
});
|
});
|
||||||
methods.add_method_mut("and_then", |_, this, (cb,): (LuaFunction,)| {
|
methods.add_method_mut("and_then", |lua, this, (cb,): (LuaFunction,)| {
|
||||||
|
let key = uuid::Uuid::new_v4().to_string();
|
||||||
|
lua.set_named_registry_value(&key, cb)?;
|
||||||
match this.0.take() {
|
match this.0.take() {
|
||||||
None => Err(LuaError::runtime("Promise already awaited")),
|
None => Err(LuaError::runtime("Promise already awaited")),
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
|
@ -64,9 +71,9 @@ impl LuaUserData for Promise {
|
||||||
}
|
}
|
||||||
Ok(res) => match res {
|
Ok(res) => match res {
|
||||||
Err(e) => super::callback().failure(e),
|
Err(e) => super::callback().failure(e),
|
||||||
Ok(val) => super::callback().invoke(cb, val),
|
Ok(val) => super::callback().invoke(key, val, true),
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::ext::IgnorableError;
|
use crate::ext::IgnorableError;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
|
|
||||||
pub(crate) fn callback() -> &'static CallbackChannel<LuaCallback> {
|
pub(crate) fn callback() -> &'static CallbackChannel<LuaCallback> {
|
||||||
static CHANNEL: std::sync::OnceLock<CallbackChannel<LuaCallback>> = std::sync::OnceLock::new();
|
static CHANNEL: std::sync::OnceLock<CallbackChannel<LuaCallback>> = std::sync::OnceLock::new();
|
||||||
|
@ -25,21 +24,19 @@ impl Default for CallbackChannel<LuaCallback> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallbackChannel<LuaCallback> {
|
impl CallbackChannel<LuaCallback> {
|
||||||
pub(crate) fn invoke(&self, cb: LuaFunction, arg: impl Into<CallbackArg>) {
|
pub(crate) fn invoke(&self, key: String, arg: impl Into<CallbackArg>, cleanup: bool) {
|
||||||
self.tx
|
self.tx
|
||||||
.send(LuaCallback::Invoke(cb, arg.into()))
|
.send(LuaCallback::Invoke(key, arg.into(), cleanup))
|
||||||
.unwrap_or_warn("error scheduling callback")
|
.unwrap_or_warn("error scheduling callback")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn failure(&self, err: impl std::error::Error) {
|
pub(crate) fn failure(&self, err: impl std::error::Error) {
|
||||||
self.tx
|
self.tx
|
||||||
.send(LuaCallback::Fail(format!(
|
.send(LuaCallback::Fail(format!("callback returned error: {err:?}")))
|
||||||
"promise failed with error: {err:?}"
|
|
||||||
)))
|
|
||||||
.unwrap_or_warn("error scheduling callback failure")
|
.unwrap_or_warn("error scheduling callback failure")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn recv(&self) -> Option<LuaCallback> {
|
pub(crate) fn recv(&self, lua: &Lua) -> Option<(LuaFunction, CallbackArg)> {
|
||||||
match self.rx.try_lock() {
|
match self.rx.try_lock() {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::debug!("backing off from callback mutex: {e}");
|
tracing::debug!("backing off from callback mutex: {e}");
|
||||||
|
@ -51,7 +48,25 @@ impl CallbackChannel<LuaCallback> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Err(tokio::sync::mpsc::error::TryRecvError::Empty) => None,
|
Err(tokio::sync::mpsc::error::TryRecvError::Empty) => None,
|
||||||
Ok(cb) => Some(cb),
|
Ok(LuaCallback::Fail(msg)) => {
|
||||||
|
tracing::error!("callback returned error: {msg}");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
Ok(LuaCallback::Invoke(key, arg, cleanup)) => {
|
||||||
|
let cb = match lua.named_registry_value::<LuaFunction>(&key) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("could not get callback to invoke: {e}");
|
||||||
|
return None;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if cleanup {
|
||||||
|
if let Err(e) = lua.unset_named_registry_value(&key) {
|
||||||
|
tracing::warn!("could not unset callback from registry: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some((cb, arg))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +74,7 @@ impl CallbackChannel<LuaCallback> {
|
||||||
|
|
||||||
pub(crate) enum LuaCallback {
|
pub(crate) enum LuaCallback {
|
||||||
Fail(String),
|
Fail(String),
|
||||||
Invoke(LuaFunction, CallbackArg),
|
Invoke(String, CallbackArg, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! callback_args {
|
macro_rules! callback_args {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{io::Write, sync::Mutex};
|
use std::{io::Write, sync::Mutex};
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -19,7 +18,7 @@ impl Write for LuaLoggerProducer {
|
||||||
|
|
||||||
// TODO can we make this less verbose?
|
// TODO can we make this less verbose?
|
||||||
pub(crate) fn setup_tracing(
|
pub(crate) fn setup_tracing(
|
||||||
_: &Lua,
|
lua: &Lua,
|
||||||
(printer, debug): (LuaValue, Option<bool>),
|
(printer, debug): (LuaValue, Option<bool>),
|
||||||
) -> LuaResult<bool> {
|
) -> LuaResult<bool> {
|
||||||
let level = if debug.unwrap_or_default() {
|
let level = if debug.unwrap_or_default() {
|
||||||
|
@ -37,14 +36,6 @@ pub(crate) fn setup_tracing(
|
||||||
.with_source_location(false);
|
.with_source_location(false);
|
||||||
|
|
||||||
let success = match printer {
|
let success = match printer {
|
||||||
LuaValue::Boolean(_)
|
|
||||||
| LuaValue::LightUserData(_)
|
|
||||||
| LuaValue::Integer(_)
|
|
||||||
| LuaValue::Number(_)
|
|
||||||
| LuaValue::Table(_)
|
|
||||||
| LuaValue::Thread(_)
|
|
||||||
| LuaValue::UserData(_)
|
|
||||||
| LuaValue::Error(_) => return Err(LuaError::BindError), // TODO full BadArgument type??
|
|
||||||
LuaValue::Nil => tracing_subscriber::fmt()
|
LuaValue::Nil => tracing_subscriber::fmt()
|
||||||
.event_format(format)
|
.event_format(format)
|
||||||
.with_max_level(level)
|
.with_max_level(level)
|
||||||
|
@ -63,6 +54,8 @@ pub(crate) fn setup_tracing(
|
||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
LuaValue::Function(cb) => {
|
LuaValue::Function(cb) => {
|
||||||
|
let key = uuid::Uuid::new_v4().to_string();
|
||||||
|
lua.set_named_registry_value(&key, cb)?;
|
||||||
let (tx, mut rx) = mpsc::unbounded_channel();
|
let (tx, mut rx) = mpsc::unbounded_channel();
|
||||||
let res = tracing_subscriber::fmt()
|
let res = tracing_subscriber::fmt()
|
||||||
.event_format(format)
|
.event_format(format)
|
||||||
|
@ -74,12 +67,13 @@ pub(crate) fn setup_tracing(
|
||||||
if res {
|
if res {
|
||||||
super::a_sync::tokio().spawn(async move {
|
super::a_sync::tokio().spawn(async move {
|
||||||
while let Some(msg) = rx.recv().await {
|
while let Some(msg) = rx.recv().await {
|
||||||
super::callback().invoke(cb.clone(), msg);
|
super::callback().invoke(key.clone(), msg, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
},
|
||||||
|
_ => return Err(LuaError::BindError), // TODO full BadArgument type??
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(success)
|
Ok(success)
|
||||||
|
|
|
@ -6,7 +6,6 @@ mod workspace;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
|
|
||||||
// define multiple entrypoints, so this library can have multiple names and still work
|
// define multiple entrypoints, so this library can have multiple names and still work
|
||||||
#[mlua::lua_module(name = "codemp")]
|
#[mlua::lua_module(name = "codemp")]
|
||||||
|
@ -57,16 +56,12 @@ fn entrypoint(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
"poll_callback",
|
"poll_callback",
|
||||||
lua.create_function(|lua, ()| {
|
lua.create_function(|lua, ()| {
|
||||||
let mut val = LuaMultiValue::new();
|
let mut val = LuaMultiValue::new();
|
||||||
match ext::callback().recv() {
|
match ext::callback().recv(lua) {
|
||||||
None => {}
|
None => {}
|
||||||
Some(ext::callback::LuaCallback::Invoke(cb, arg)) => {
|
Some((cb, arg)) => {
|
||||||
val.push_back(LuaValue::Function(cb));
|
val.push_back(LuaValue::Function(cb));
|
||||||
val.push_back(arg.into_lua(lua)?);
|
val.push_back(arg.into_lua(lua)?);
|
||||||
}
|
}
|
||||||
Some(ext::callback::LuaCallback::Fail(msg)) => {
|
|
||||||
val.push_back(false.into_lua(lua)?);
|
|
||||||
val.push_back(msg.into_lua(lua)?);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(val)
|
Ok(val)
|
||||||
})?,
|
})?,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_codemp_patch as mlua;
|
|
||||||
|
|
||||||
use super::ext::a_sync::a_sync;
|
use super::ext::a_sync::a_sync;
|
||||||
|
|
||||||
|
@ -67,12 +66,23 @@ impl LuaUserData for CodempWorkspace {
|
||||||
|
|
||||||
methods.add_method("poll", |_, this, ()| a_sync! { this => this.poll().await? });
|
methods.add_method("poll", |_, this, ()| a_sync! { this => this.poll().await? });
|
||||||
|
|
||||||
methods.add_method("callback", |_, this, (cb,): (LuaFunction,)| {
|
methods.add_method("callback", |lua, this, (cb,): (LuaFunction,)| {
|
||||||
|
let key = this.lua_callback_id();
|
||||||
|
lua.set_named_registry_value(&key, cb)?;
|
||||||
Ok(this.callback(move |controller: CodempWorkspace| {
|
Ok(this.callback(move |controller: CodempWorkspace| {
|
||||||
super::ext::callback().invoke(cb.clone(), controller)
|
super::ext::callback().invoke(key.clone(), controller, false)
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
methods.add_method("clear_callback", |_, this, ()| Ok(this.clear_callback()));
|
methods.add_method("clear_callback", |lua, this, ()| {
|
||||||
|
this.clear_callback();
|
||||||
|
lua.unset_named_registry_value(&this.lua_callback_id())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodempWorkspace {
|
||||||
|
fn lua_callback_id(&self) -> String {
|
||||||
|
format!("codemp-workspace({})-callback-registry", self.id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl Workspace {
|
||||||
|
|
||||||
let users = Arc::new(DashMap::default());
|
let users = Arc::new(DashMap::default());
|
||||||
|
|
||||||
let controller = cursor::Controller::spawn(users.clone(), tx, cur_stream);
|
let controller = cursor::Controller::spawn(users.clone(), tx, cur_stream, &name);
|
||||||
|
|
||||||
let ws = Self(Arc::new(WorkspaceInner {
|
let ws = Self(Arc::new(WorkspaceInner {
|
||||||
name,
|
name,
|
||||||
|
@ -175,7 +175,7 @@ impl Workspace {
|
||||||
);
|
);
|
||||||
let stream = self.0.services.buf().attach(req).await?.into_inner();
|
let stream = self.0.services.buf().attach(req).await?.into_inner();
|
||||||
|
|
||||||
let controller = buffer::Controller::spawn(self.0.user.id, path, tx, stream);
|
let controller = buffer::Controller::spawn(self.0.user.id, path, tx, stream, &self.0.name);
|
||||||
self.0.buffers.insert(path.to_string(), controller.clone());
|
self.0.buffers.insert(path.to_string(), controller.clone());
|
||||||
|
|
||||||
Ok(controller)
|
Ok(controller)
|
||||||
|
|
Loading…
Reference in a new issue