mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-22 23:34:49 +01:00
fix: updated lua ffi
now the client is given to lua
This commit is contained in:
parent
a9bab2bb03
commit
e1ba683fd0
1 changed files with 44 additions and 66 deletions
102
src/ffi/lua.rs
102
src/ffi/lua.rs
|
@ -1,84 +1,60 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::atomic::AtomicBool;
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::api::Cursor;
|
use crate::api::Cursor;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use tokio::runtime::Runtime;
|
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
|
|
||||||
lazy_static::lazy_static!{
|
lazy_static::lazy_static!{
|
||||||
// TODO use a runtime::Builder::new_current_thread() runtime to not behave like malware
|
// TODO use a runtime::Builder::new_current_thread() runtime to not behave like malware
|
||||||
static ref STATE : GlobalState = GlobalState::default();
|
static ref RT : tokio::runtime::Runtime = tokio::runtime::Builder::new_current_thread().enable_all().build().expect("could not create tokio runtime");
|
||||||
static ref LOG : broadcast::Sender<String> = broadcast::channel(32).0;
|
static ref LOG : broadcast::Sender<String> = broadcast::channel(32).0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GlobalState {
|
fn runtime_drive_forever(_: &Lua, ():()) -> LuaResult<()> {
|
||||||
client: std::sync::RwLock<CodempClient>,
|
std::thread::spawn(|| RT.block_on(std::future::pending::<()>()));
|
||||||
runtime: Runtime,
|
Ok(())
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for GlobalState {
|
|
||||||
fn default() -> Self {
|
|
||||||
let rt = Runtime::new().expect("could not create tokio runtime");
|
|
||||||
let addr = std::env::var("CODEMP_SERVER_ADDRESS").unwrap_or_else(|_|"http://codemp.alemi.dev:50053".to_string());
|
|
||||||
let client = rt.block_on(
|
|
||||||
CodempClient::new(&addr)
|
|
||||||
).expect("could not connect to codemp servers");
|
|
||||||
GlobalState { client: std::sync::RwLock::new(client), runtime: rt }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GlobalState {
|
|
||||||
fn client(&self) -> std::sync::RwLockReadGuard<CodempClient> {
|
|
||||||
self.client.read().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn client_mut(&self) -> std::sync::RwLockWriteGuard<CodempClient> {
|
|
||||||
self.client.write().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rt(&self) -> &Runtime {
|
|
||||||
&self.runtime
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From::<CodempError> for LuaError {
|
impl From::<CodempError> for LuaError {
|
||||||
fn from(value: CodempError) -> Self {
|
fn from(value: CodempError) -> Self {
|
||||||
LuaError::external(value)
|
LuaError::RuntimeError(value.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id(_: &Lua, (): ()) -> LuaResult<String> {
|
fn connect(_: &Lua, (host, username, password): (String, String, String)) -> LuaResult<CodempClient> {
|
||||||
Ok(STATE.client().user_id().to_string())
|
Ok(RT.block_on(CodempClient::new(host, username, password))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LuaUserData for CodempClient {
|
||||||
|
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||||
|
fields.add_field_method_get("id", |_, this| Ok(this.user_id().to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
/// join a remote workspace and start processing cursor events
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
fn join_workspace(_: &Lua, (session,): (String,)) -> LuaResult<CodempCursorController> {
|
// join a remote workspace and start processing cursor events
|
||||||
|
methods.add_method("join_workspace", |_, this, (session,):(String,)| {
|
||||||
tracing::info!("joining workspace {}", session);
|
tracing::info!("joining workspace {}", session);
|
||||||
let ws = STATE.rt().block_on(async { STATE.client_mut().join_workspace(&session).await })?;
|
let ws = RT.block_on(async { this.join_workspace(&session).await })?;
|
||||||
let cursor = ws.cursor();
|
let cursor = ws.cursor();
|
||||||
Ok(cursor.into())
|
Ok(cursor)
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_method("get_workspace", |_, this, (session,):(String,)| Ok(this.get_workspace(&session)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn login(_: &Lua, (username, password, workspace_id):(String, String, String)) -> LuaResult<()> {
|
|
||||||
Ok(STATE.rt().block_on(STATE.client().login(username, password, Some(workspace_id)))?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_workspace(_: &Lua, (session,): (String,)) -> LuaResult<Option<CodempWorkspace>> {
|
|
||||||
Ok(STATE.client().get_workspace(&session))
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LuaUserData for CodempWorkspace {
|
impl LuaUserData for CodempWorkspace {
|
||||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
methods.add_method("create_buffer", |_, this, (name,):(String,)| {
|
methods.add_method("create_buffer", |_, this, (name,):(String,)| {
|
||||||
Ok(STATE.rt().block_on(async { this.create(&name).await })?)
|
Ok(RT.block_on(async { this.create(&name).await })?)
|
||||||
});
|
});
|
||||||
|
|
||||||
methods.add_method("attach_buffer", |_, this, (name,):(String,)| {
|
methods.add_method("attach_buffer", |_, this, (name,):(String,)| {
|
||||||
Ok(STATE.rt().block_on(async { this.attach(&name).await })?)
|
Ok(RT.block_on(async { this.attach(&name).await })?)
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO disconnect_buffer
|
// TODO disconnect_buffer
|
||||||
|
@ -107,7 +83,7 @@ impl LuaUserData for CodempCursorController {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
methods.add_method("poll", |_, this, ()| {
|
methods.add_method("poll", |_, this, ()| {
|
||||||
STATE.rt().block_on(this.poll())?;
|
RT.block_on(this.poll())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -122,9 +98,9 @@ impl LuaUserData for Cursor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RowCol {
|
struct RowCol {
|
||||||
pub row: i32,
|
row: i32,
|
||||||
pub col: i32,
|
col: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(i32, i32)> for RowCol {
|
impl From<(i32, i32)> for RowCol {
|
||||||
|
@ -147,7 +123,8 @@ impl LuaUserData for CodempBufferController {
|
||||||
Ok(
|
Ok(
|
||||||
this.send(
|
this.send(
|
||||||
CodempTextChange {
|
CodempTextChange {
|
||||||
span: start..end,
|
start: start as u32,
|
||||||
|
end: end as u32,
|
||||||
content: text,
|
content: text,
|
||||||
}
|
}
|
||||||
)?
|
)?
|
||||||
|
@ -167,7 +144,7 @@ impl LuaUserData for CodempBufferController {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
methods.add_method("poll", |_, this, ()| {
|
methods.add_method("poll", |_, this, ()| {
|
||||||
STATE.rt().block_on(this.poll())?;
|
RT.block_on(this.poll())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -182,14 +159,15 @@ impl LuaUserData for CodempOp { }
|
||||||
impl LuaUserData for CodempTextChange {
|
impl LuaUserData for CodempTextChange {
|
||||||
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("content", |_, this| Ok(this.content.clone()));
|
fields.add_field_method_get("content", |_, this| Ok(this.content.clone()));
|
||||||
fields.add_field_method_get("first", |_, this| Ok(this.span.start));
|
fields.add_field_method_get("first", |_, this| Ok(this.start));
|
||||||
fields.add_field_method_get("last", |_, this| Ok(this.span.end));
|
fields.add_field_method_get("last", |_, this| Ok(this.end));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
methods.add_meta_function(LuaMetaMethod::Call, |_, (start, end, txt): (usize, usize, String)| {
|
methods.add_meta_function(LuaMetaMethod::Call, |_, (start, end, txt): (usize, usize, String)| {
|
||||||
Ok(CodempTextChange {
|
Ok(CodempTextChange {
|
||||||
span: start..end,
|
start: start as u32,
|
||||||
|
end: end as u32,
|
||||||
content: txt,
|
content: txt,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -260,15 +238,15 @@ fn get_logger(_: &Lua, (): ()) -> LuaResult<LuaLogger> {
|
||||||
fn codemp_lua(lua: &Lua) -> LuaResult<LuaTable> {
|
fn codemp_lua(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
let exports = lua.create_table()?;
|
let exports = lua.create_table()?;
|
||||||
|
|
||||||
// core proto functions
|
// entrypoint
|
||||||
exports.set("login", lua.create_function(login)?)?;
|
exports.set("connect", lua.create_function(connect)?)?;
|
||||||
exports.set("join_workspace", lua.create_function(join_workspace)?)?;
|
|
||||||
// state helpers
|
// runtime
|
||||||
exports.set("get_workspace", lua.create_function(get_workspace)?)?;
|
exports.set("spawn_runtime_driver", lua.create_function(runtime_drive_forever)?)?;
|
||||||
// debug
|
|
||||||
exports.set("id", lua.create_function(id)?)?;
|
// logging
|
||||||
exports.set("get_logger", lua.create_function(get_logger)?)?;
|
|
||||||
exports.set("setup_logger", lua.create_function(setup_logger)?)?;
|
exports.set("setup_logger", lua.create_function(setup_logger)?)?;
|
||||||
|
exports.set("get_logger", lua.create_function(get_logger)?)?;
|
||||||
|
|
||||||
Ok(exports)
|
Ok(exports)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue