mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-25 00:24:48 +01:00
feat(lua): reintroduce and_then safely
This commit is contained in:
parent
7b9d743f6f
commit
42ae4247ce
3 changed files with 118 additions and 76 deletions
1
.github/workflows/lua.yml
vendored
1
.github/workflows/lua.yml
vendored
|
@ -4,6 +4,7 @@ on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- stable
|
- stable
|
||||||
|
- dev
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
13
dist/lua/annotations.lua
vendored
13
dist/lua/annotations.lua
vendored
|
@ -14,36 +14,47 @@
|
||||||
|
|
||||||
---@class (exact) NilPromise : Promise
|
---@class (exact) NilPromise : Promise
|
||||||
---@field await fun(self: NilPromise): nil block until promise is ready
|
---@field await fun(self: NilPromise): nil block until promise is ready
|
||||||
|
---@field and_then fun(cb: fun(x: nil)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) StringPromise : Promise
|
---@class (exact) StringPromise : Promise
|
||||||
---@field await fun(self: StringPromise): string block until promise is ready and return value
|
---@field await fun(self: StringPromise): string block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: string)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) StringArrayPromise : Promise
|
---@class (exact) StringArrayPromise : Promise
|
||||||
---@field await fun(self: StringArrayPromise): string[] block until promise is ready and return value
|
---@field await fun(self: StringArrayPromise): string[] block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: string[])): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) ClientPromise : Promise
|
---@class (exact) ClientPromise : Promise
|
||||||
---@field await fun(self: ClientPromise): Client block until promise is ready and return value
|
---@field await fun(self: ClientPromise): Client block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: Client)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) WorkspacePromise : Promise
|
---@class (exact) WorkspacePromise : Promise
|
||||||
---@field await fun(self: WorkspacePromise): Workspace block until promise is ready and return value
|
---@field await fun(self: WorkspacePromise): Workspace block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: Workspace)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) WorkspaceEventPromise : Promise
|
---@class (exact) WorkspaceEventPromise : Promise
|
||||||
---@field await fun(self: WorkspaceEventPromise): WorkspaceEvent block until promise is ready and return value
|
---@field await fun(self: WorkspaceEventPromise): WorkspaceEvent block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: WorkspaceEvent)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) BufferControllerPromise : Promise
|
---@class (exact) BufferControllerPromise : Promise
|
||||||
---@field await fun(self: BufferControllerPromise): BufferController block until promise is ready and return value
|
---@field await fun(self: BufferControllerPromise): BufferController block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: BufferController)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) CursorPromise : Promise
|
---@class (exact) CursorPromise : Promise
|
||||||
---@field await fun(self: CursorPromise): Cursor block until promise is ready and return value
|
---@field await fun(self: CursorPromise): Cursor block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: Cursor)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) MaybeCursorPromise : Promise
|
---@class (exact) MaybeCursorPromise : Promise
|
||||||
---@field await fun(self: MaybeCursorPromise): Cursor? block until promise is ready and return value
|
---@field await fun(self: MaybeCursorPromise): Cursor? block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: Cursor | nil)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) TextChangePromise : Promise
|
---@class (exact) TextChangePromise : Promise
|
||||||
---@field await fun(self: TextChangePromise): TextChange block until promise is ready and return value
|
---@field await fun(self: TextChangePromise): TextChange block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: TextChange)): nil run callback after promise is complete
|
||||||
|
|
||||||
---@class (exact) MaybeTextChangePromise : Promise
|
---@class (exact) MaybeTextChangePromise : Promise
|
||||||
---@field await fun(self: MaybeTextChangePromise): TextChange? block until promise is ready and return value
|
---@field await fun(self: MaybeTextChangePromise): TextChange? block until promise is ready and return value
|
||||||
|
---@field and_then fun(cb: fun(x: TextChange | nil)): nil run callback after promise is complete
|
||||||
|
|
||||||
-- [[ END ASYNC STUFF ]]
|
-- [[ END ASYNC STUFF ]]
|
||||||
|
|
||||||
|
@ -307,7 +318,7 @@ local Codemp = {}
|
||||||
---connect to codemp server, authenticate and return client
|
---connect to codemp server, authenticate and return client
|
||||||
function Codemp.connect(config) end
|
function Codemp.connect(config) end
|
||||||
|
|
||||||
---@return function | nil
|
---@return function, any | nil
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---check if codemp thread sent a callback to be run on main thread
|
---check if codemp thread sent a callback to be run on main thread
|
||||||
function Codemp.poll_callback() end
|
function Codemp.poll_callback() end
|
||||||
|
|
180
src/ffi/lua.rs
180
src/ffi/lua.rs
|
@ -47,13 +47,58 @@ fn lua_tuple<T: IntoLua>(lua: &Lua, (a, b): (T, T)) -> LuaResult<LuaTable> {
|
||||||
Ok(table)
|
Ok(table)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO cannot do Box<dyn IntoLuaMulti> ?? maybe its temporary because im using betas
|
enum CallbackArg {
|
||||||
#[allow(unused)] // TODO pass callback args!
|
Nil,
|
||||||
//struct CallbackArg<T: IntoLuaMulti>(tokio::sync::oneshot::Receiver<T>);
|
Str(String),
|
||||||
struct CallbackArg;
|
VecStr(Vec<String>),
|
||||||
|
Client(CodempClient),
|
||||||
|
CursorController(CodempCursorController),
|
||||||
|
BufferController(CodempBufferController),
|
||||||
|
Workspace(CodempWorkspace),
|
||||||
|
Event(CodempEvent),
|
||||||
|
Cursor(CodempCursor),
|
||||||
|
MaybeCursor(Option<CodempCursor>),
|
||||||
|
TextChange(CodempTextChange),
|
||||||
|
MaybeTextChange(Option<CodempTextChange>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoLua for CallbackArg {
|
||||||
|
// TODO this basically calls .into_lua() on all enum variants
|
||||||
|
// i wish i could do this with a Box<dyn IntoLua> or an impl IntoLua
|
||||||
|
// but IntoLua requires Sized so it can't be made into an object
|
||||||
|
fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
|
||||||
|
match self {
|
||||||
|
CallbackArg::Nil => Ok(LuaValue::Nil),
|
||||||
|
CallbackArg::Str(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::Client(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::CursorController(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::BufferController(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::Workspace(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::VecStr(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::Event(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::Cursor(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::MaybeCursor(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::TextChange(x) => x.into_lua(lua),
|
||||||
|
CallbackArg::MaybeTextChange(x) => x.into_lua(lua),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<()> for CallbackArg { fn from(_: ()) -> Self { CallbackArg::Nil } }
|
||||||
|
impl From<String> for CallbackArg { fn from(value: String) -> Self { CallbackArg::Str(value) } }
|
||||||
|
impl From<CodempClient> for CallbackArg { fn from(value: CodempClient) -> Self { CallbackArg::Client(value) } }
|
||||||
|
impl From<CodempCursorController> for CallbackArg { fn from(value: CodempCursorController) -> Self { CallbackArg::CursorController(value) } }
|
||||||
|
impl From<CodempBufferController> for CallbackArg { fn from(value: CodempBufferController) -> Self { CallbackArg::BufferController(value) } }
|
||||||
|
impl From<CodempWorkspace> for CallbackArg { fn from(value: CodempWorkspace) -> Self { CallbackArg::Workspace(value) } }
|
||||||
|
impl From<Vec<String>> for CallbackArg { fn from(value: Vec<String>) -> Self { CallbackArg::VecStr(value) } }
|
||||||
|
impl From<CodempEvent> for CallbackArg { fn from(value: CodempEvent) -> Self { CallbackArg::Event(value) } }
|
||||||
|
impl From<CodempCursor> for CallbackArg { fn from(value: CodempCursor) -> Self { CallbackArg::Cursor(value) } }
|
||||||
|
impl From<Option<CodempCursor>> for CallbackArg { fn from(value: Option<CodempCursor>) -> Self { CallbackArg::MaybeCursor(value) } }
|
||||||
|
impl From<CodempTextChange> for CallbackArg { fn from(value: CodempTextChange) -> Self { CallbackArg::TextChange(value) } }
|
||||||
|
impl From<Option<CodempTextChange>> for CallbackArg { fn from(value: Option<CodempTextChange>) -> Self { CallbackArg::MaybeTextChange(value) } }
|
||||||
|
|
||||||
struct CallbackChannel {
|
struct CallbackChannel {
|
||||||
tx: tokio::sync::mpsc::UnboundedSender<(LuaFunction, CallbackArg)>,
|
tx: std::sync::Arc<tokio::sync::mpsc::UnboundedSender<(LuaFunction, CallbackArg)>>,
|
||||||
rx: std::sync::Mutex<tokio::sync::mpsc::UnboundedReceiver<(LuaFunction, CallbackArg)>>
|
rx: std::sync::Mutex<tokio::sync::mpsc::UnboundedReceiver<(LuaFunction, CallbackArg)>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,31 +107,31 @@ impl Default for CallbackChannel {
|
||||||
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
|
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
|
||||||
let rx = std::sync::Mutex::new(rx);
|
let rx = std::sync::Mutex::new(rx);
|
||||||
Self {
|
Self {
|
||||||
tx, rx,
|
tx: std::sync::Arc::new(tx),
|
||||||
|
rx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallbackChannel {
|
impl CallbackChannel {
|
||||||
fn send(&self, cb: LuaFunction, _arg: impl IntoLuaMulti) {
|
fn send(&self, cb: LuaFunction, arg: impl Into<CallbackArg>) {
|
||||||
// let (tx, rx) = tokio::sync::oneshot::channel();
|
self.tx.send((cb, arg.into()))
|
||||||
// tx.send(arg);
|
.unwrap_or_warn("error scheduling callback")
|
||||||
self.tx.send((cb, CallbackArg)).unwrap_or_warn("error scheduling callback")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv(&self) -> Option<(LuaFunction, CallbackArg)> {
|
fn recv(&self) -> Option<(LuaFunction, CallbackArg)> {
|
||||||
match self.rx.try_lock() {
|
match self.rx.try_lock() {
|
||||||
|
Err(e) => {
|
||||||
|
tracing::warn!("could not acquire callback channel mutex: {e}");
|
||||||
|
None
|
||||||
|
},
|
||||||
Ok(mut lock) => match lock.try_recv() {
|
Ok(mut lock) => match lock.try_recv() {
|
||||||
Ok(res) => Some(res),
|
|
||||||
Err(TryRecvError::Empty) => None,
|
Err(TryRecvError::Empty) => None,
|
||||||
Err(TryRecvError::Disconnected) => {
|
Err(TryRecvError::Disconnected) => {
|
||||||
tracing::error!("callback channel closed");
|
tracing::error!("callback channel closed");
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
},
|
Ok((cb, arg)) => Some((cb, arg)),
|
||||||
Err(e) => {
|
|
||||||
tracing::warn!("could not acquire callback channel mutex: {e}");
|
|
||||||
None
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,9 +144,9 @@ lazy_static::lazy_static! {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Promise<T: Send + Sync + IntoLuaMulti>(Option<tokio::task::JoinHandle<LuaResult<T>>>);
|
struct Promise(Option<tokio::task::JoinHandle<LuaResult<CallbackArg>>>);
|
||||||
|
|
||||||
impl<T: Send + Sync + IntoLuaMulti + 'static> LuaUserData for Promise<T> {
|
impl LuaUserData for Promise {
|
||||||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("ready", |_, this|
|
fields.add_field_method_get("ready", |_, this|
|
||||||
Ok(this.0.as_ref().map_or(true, |x| x.is_finished()))
|
Ok(this.0.as_ref().map_or(true, |x| x.is_finished()))
|
||||||
|
@ -118,24 +163,20 @@ impl<T: Send + Sync + IntoLuaMulti + 'static> LuaUserData for Promise<T> {
|
||||||
.map_err(LuaError::runtime)?
|
.map_err(LuaError::runtime)?
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// methods.add_method_mut("and_then", |_, this, (cb,):(LuaFunction,)| match this.0.take() {
|
methods.add_method_mut("and_then", |_, this, (cb,):(LuaFunction,)| match this.0.take() {
|
||||||
// None => Err(LuaError::runtime("Promise already awaited")),
|
None => Err(LuaError::runtime("Promise already awaited")),
|
||||||
// Some(x) => {
|
Some(x) => {
|
||||||
// tokio()
|
tokio()
|
||||||
// .spawn(async move {
|
.spawn(async move {
|
||||||
// match x.await {
|
match x.await {
|
||||||
// Err(e) => tracing::error!("could not join promise to run callback: {e}"),
|
Err(e) => tracing::error!("could not join promise to run callback: {e}"),
|
||||||
// Ok(Err(e)) => tracing::error!("promise returned error: {e}"),
|
Ok(Err(e)) => tracing::error!("promise returned error: {e}"),
|
||||||
// Ok(Ok(res)) => {
|
Ok(Ok(res)) => CHANNEL.send(cb, res),
|
||||||
// if let Err(e) = cb.call::<()>(res) {
|
}
|
||||||
// tracing::error!("error running promise callback: {e}");
|
});
|
||||||
// }
|
Ok(())
|
||||||
// },
|
},
|
||||||
// }
|
});
|
||||||
// });
|
|
||||||
// Ok(())
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +184,7 @@ macro_rules! a_sync {
|
||||||
($($clone:ident)* => $x:expr) => {
|
($($clone:ident)* => $x:expr) => {
|
||||||
{
|
{
|
||||||
$(let $clone = $clone.clone();)*
|
$(let $clone = $clone.clone();)*
|
||||||
Ok(Promise(Some(tokio().spawn(async move { $x }))))
|
Ok(Promise(Some(tokio().spawn(async move { Ok(CallbackArg::from($x)) }))))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -206,27 +247,27 @@ impl LuaUserData for CodempClient {
|
||||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
||||||
|
|
||||||
methods.add_method("refresh", |_, this, ()|
|
methods.add_method("refresh", |_, this, ()|
|
||||||
a_sync! { this => Ok(this.refresh().await?) }
|
a_sync! { this => this.refresh().await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("join_workspace", |_, this, (ws,):(String,)|
|
methods.add_method("join_workspace", |_, this, (ws,):(String,)|
|
||||||
a_sync! { this => Ok(this.join_workspace(ws).await?) }
|
a_sync! { this => this.join_workspace(ws).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("create_workspace", |_, this, (ws,):(String,)|
|
methods.add_method("create_workspace", |_, this, (ws,):(String,)|
|
||||||
a_sync! { this => Ok(this.create_workspace(ws).await?) }
|
a_sync! { this => this.create_workspace(ws).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("delete_workspace", |_, this, (ws,):(String,)|
|
methods.add_method("delete_workspace", |_, this, (ws,):(String,)|
|
||||||
a_sync! { this => Ok(this.delete_workspace(ws).await?) }
|
a_sync! { this => this.delete_workspace(ws).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("invite_to_workspace", |_, this, (ws,user):(String,String)|
|
methods.add_method("invite_to_workspace", |_, this, (ws,user):(String,String)|
|
||||||
a_sync! { this => Ok(this.invite_to_workspace(ws, user).await?) }
|
a_sync! { this => this.invite_to_workspace(ws, user).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("list_workspaces", |_, this, (owned,invited):(Option<bool>,Option<bool>)|
|
methods.add_method("list_workspaces", |_, this, (owned,invited):(Option<bool>,Option<bool>)|
|
||||||
a_sync! { this => Ok(this.list_workspaces(owned.unwrap_or(true), invited.unwrap_or(true)).await?) }
|
a_sync! { this => this.list_workspaces(owned.unwrap_or(true), invited.unwrap_or(true)).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("leave_workspace", |_, this, (ws,):(String,)|
|
methods.add_method("leave_workspace", |_, this, (ws,):(String,)|
|
||||||
|
@ -242,11 +283,11 @@ impl LuaUserData for CodempWorkspace {
|
||||||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
||||||
methods.add_method("create", |_, this, (name,):(String,)|
|
methods.add_method("create", |_, this, (name,):(String,)|
|
||||||
a_sync! { this => Ok(this.create(&name).await?) }
|
a_sync! { this => this.create(&name).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("attach", |_, this, (name,):(String,)|
|
methods.add_method("attach", |_, this, (name,):(String,)|
|
||||||
a_sync! { this => Ok(this.attach(&name).await?) }
|
a_sync! { this => this.attach(&name).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("detach", |_, this, (name,):(String,)|
|
methods.add_method("detach", |_, this, (name,):(String,)|
|
||||||
|
@ -254,34 +295,22 @@ impl LuaUserData for CodempWorkspace {
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("delete", |_, this, (name,):(String,)|
|
methods.add_method("delete", |_, this, (name,):(String,)|
|
||||||
a_sync! { this => Ok(this.delete(&name).await?) }
|
a_sync! { this => this.delete(&name).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("get_buffer", |_, this, (name,):(String,)| Ok(this.buffer_by_name(&name)));
|
methods.add_method("get_buffer", |_, this, (name,):(String,)| Ok(this.buffer_by_name(&name)));
|
||||||
|
|
||||||
methods.add_method("event", |_, this, ()|
|
methods.add_method("event", |_, this, ()|
|
||||||
a_sync! { this => Ok(this.event().await?) }
|
a_sync! { this => this.event().await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("fetch_buffers", |_, this, ()|
|
methods.add_method("fetch_buffers", |_, this, ()|
|
||||||
a_sync! { this => Ok(this.fetch_buffers().await?) }
|
a_sync! { this => this.fetch_buffers().await? }
|
||||||
);
|
);
|
||||||
methods.add_method("fetch_users", |_, this, ()|
|
methods.add_method("fetch_users", |_, this, ()|
|
||||||
a_sync! { this => Ok(this.fetch_users().await?) }
|
a_sync! { this => this.fetch_users().await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
// methods.add_method("callback", |_, this, (cb,):(LuaFunction,)| {
|
|
||||||
// let _this = this.clone();
|
|
||||||
// tokio().spawn(async move {
|
|
||||||
// while let Ok(ev) = _this.event().await {
|
|
||||||
// if let Err(e) = cb.call::<()>(ev) {
|
|
||||||
// tracing::error!("error running workspace callback: {e}");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// Ok(())
|
|
||||||
// });
|
|
||||||
|
|
||||||
methods.add_method("filetree", |_, this, (filter, strict,):(Option<String>, Option<bool>,)|
|
methods.add_method("filetree", |_, this, (filter, strict,):(Option<String>, Option<bool>,)|
|
||||||
Ok(this.filetree(filter.as_deref(), strict.unwrap_or(false)))
|
Ok(this.filetree(filter.as_deref(), strict.unwrap_or(false)))
|
||||||
);
|
);
|
||||||
|
@ -322,13 +351,13 @@ impl LuaUserData for CodempCursorController {
|
||||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
||||||
|
|
||||||
methods.add_method("send", |_, this, (cursor,):(CodempCursor,)|
|
methods.add_method("send", |_, this, (cursor,):(CodempCursor,)|
|
||||||
a_sync! { this => Ok(this.send(cursor).await?) }
|
a_sync! { this => this.send(cursor).await? }
|
||||||
);
|
);
|
||||||
methods.add_method("try_recv", |_, this, ()|
|
methods.add_method("try_recv", |_, this, ()|
|
||||||
a_sync! { this => Ok(this.try_recv().await?) }
|
a_sync! { this => this.try_recv().await? }
|
||||||
);
|
);
|
||||||
methods.add_method("recv", |_, this, ()| a_sync! { this => Ok(this.recv().await?) });
|
methods.add_method("recv", |_, this, ()| a_sync! { this => this.recv().await? });
|
||||||
methods.add_method("poll", |_, this, ()| a_sync! { this => Ok(this.poll().await?) });
|
methods.add_method("poll", |_, this, ()| a_sync! { this => this.poll().await? });
|
||||||
|
|
||||||
methods.add_method("stop", |_, this, ()| Ok(this.stop()));
|
methods.add_method("stop", |_, this, ()| Ok(this.stop()));
|
||||||
|
|
||||||
|
@ -361,16 +390,16 @@ impl LuaUserData for CodempBufferController {
|
||||||
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| Ok(format!("{:?}", this)));
|
||||||
|
|
||||||
methods.add_method("send", |_, this, (change,): (CodempTextChange,)|
|
methods.add_method("send", |_, this, (change,): (CodempTextChange,)|
|
||||||
a_sync! { this => Ok(this.send(change).await?)}
|
a_sync! { this => this.send(change).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("try_recv", |_, this, ()| a_sync! { this => Ok(this.try_recv().await?) });
|
methods.add_method("try_recv", |_, this, ()| a_sync! { this => this.try_recv().await? });
|
||||||
methods.add_method("recv", |_, this, ()| a_sync! { this => Ok(this.recv().await?) });
|
methods.add_method("recv", |_, this, ()| a_sync! { this => this.recv().await? });
|
||||||
methods.add_method("poll", |_, this, ()| a_sync! { this => Ok(this.poll().await?) });
|
methods.add_method("poll", |_, this, ()| a_sync! { this => this.poll().await? });
|
||||||
|
|
||||||
methods.add_method("stop", |_, this, ()| Ok(this.stop()));
|
methods.add_method("stop", |_, this, ()| Ok(this.stop()));
|
||||||
|
|
||||||
methods.add_method("content", |_, this, ()| a_sync! { this => Ok(this.content().await?) });
|
methods.add_method("content", |_, this, ()| a_sync! { this => this.content().await? });
|
||||||
|
|
||||||
methods.add_method("clear_callback", |_, this, ()| { this.clear_callback(); Ok(()) });
|
methods.add_method("clear_callback", |_, this, ()| { this.clear_callback(); Ok(()) });
|
||||||
methods.add_method("callback", |_, this, (cb,):(LuaFunction,)| {
|
methods.add_method("callback", |_, this, (cb,):(LuaFunction,)| {
|
||||||
|
@ -510,7 +539,7 @@ fn entrypoint(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
|
|
||||||
// entrypoint
|
// entrypoint
|
||||||
exports.set("connect", lua.create_function(|_, (config,):(CodempConfig,)|
|
exports.set("connect", lua.create_function(|_, (config,):(CodempConfig,)|
|
||||||
a_sync! { => Ok(CodempClient::connect(config).await?) }
|
a_sync! { => CodempClient::connect(config).await? }
|
||||||
)?)?;
|
)?)?;
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
|
@ -520,13 +549,14 @@ fn entrypoint(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
|
|
||||||
// runtime
|
// runtime
|
||||||
exports.set("spawn_runtime_driver", lua.create_function(spawn_runtime_driver)?)?;
|
exports.set("spawn_runtime_driver", lua.create_function(spawn_runtime_driver)?)?;
|
||||||
exports.set("poll_callback", lua.create_function(|_, ()| {
|
exports.set("poll_callback", lua.create_function(|lua, ()| {
|
||||||
// TODO pass args too
|
// TODO pass args too
|
||||||
if let Some((cb, _arg)) = CHANNEL.recv() {
|
let mut val = LuaMultiValue::new();
|
||||||
Ok(Some(cb))
|
if let Some((cb, arg)) = CHANNEL.recv() {
|
||||||
} else {
|
val.push_back(LuaValue::Function(cb));
|
||||||
Ok(None)
|
val.push_back(arg.into_lua(lua)?);
|
||||||
}
|
}
|
||||||
|
Ok(val)
|
||||||
})?)?;
|
})?)?;
|
||||||
|
|
||||||
// logging
|
// logging
|
||||||
|
|
Loading…
Reference in a new issue