Create channel and task libs

This commit is contained in:
lumi 2025-06-25 10:43:00 +10:00
parent e0898c22a0
commit a295107bac
Signed by: luaneko
GPG Key ID: 406809B8763FF07A
4 changed files with 177 additions and 0 deletions

64
crates/lb/src/channel.rs Normal file
View File

@ -0,0 +1,64 @@
// use flume::{Receiver, Sender};
use luaffi::{cdef, metatype};
#[cdef]
pub struct lb_libchannel;
#[metatype]
impl lb_libchannel {
#[new]
extern "Lua-C" fn new() -> Self {
Self
}
extern "Lua" fn unbounded(self) {
let (send, recv) = (__new(__ct.lb_sender), __new(__ct.lb_receiver));
self.__unbounded(send, recv);
(send, recv)
}
extern "Lua" fn bounded(self, cap: number) {
assert(cap >= 0, "channel capacity must be nonnegative");
let (send, recv) = (__new(__ct.lb_sender), __new(__ct.lb_receiver));
self.__bounded(cap, send, recv);
(send, recv)
}
// extern "Lua-C" fn __unbounded(&self, s: *mut lb_sender, r: *mut lb_receiver) {
// let (send, recv) = flume::unbounded();
// unsafe {
// ptr::write(s, lb_sender { send });
// ptr::write(r, lb_receiver { recv });
// }
// }
// extern "Lua-C" fn __bounded(&self, cap: usize, s: *mut lb_sender, r: *mut lb_receiver) {
// let (send, recv) = flume::bounded(cap);
// unsafe {
// ptr::write(s, lb_sender { send });
// ptr::write(r, lb_receiver { recv });
// }
// }
}
// #[cdef]
// pub struct lb_sender {
// #[opaque]
// send: Sender<c_int>,
// }
// #[metatype]
// impl lb_sender {
// extern "Lua" fn send(self, value: _) {
// let key = __ref(value);
// }
// }
// #[cdef]
// pub struct lb_receiver {
// #[opaque]
// recv: Receiver<c_int>,
// }
// #[metatype]
// impl lb_receiver {}

46
crates/lb/src/task.rs Normal file
View File

@ -0,0 +1,46 @@
use crate::runtime::spawn;
use luaffi::{cdef, metatype};
use std::{ffi::c_int, process};
use tokio::task::JoinHandle;
#[cdef]
pub struct lb_libtask;
#[metatype]
impl lb_libtask {
#[new]
extern "Lua-C" fn new() -> Self {
Self
}
pub extern "Lua" fn spawn(self, f: function, ...) {
// pack the function and its arguments into a table and pass its ref to rust
self.__spawn(__ref(__tpack(f, variadic!())))
}
extern "Lua-C" fn __spawn(&self, key: c_int) -> lb_task {
let handle = spawn(async move |s| {
// SAFETY: key is always unique, created by __ref above
let arg = unsafe { s.new_ref_unchecked(key) };
s.resize(0);
s.push(arg);
let narg = s.unpack(1, 1, None) - 1;
println!("{s:?}");
if let Err(_err) = s.call_async(narg, 0).await {
process::exit(1)
}
println!("{s:?}");
});
lb_task { handle }
}
}
#[cdef]
pub struct lb_task {
#[opaque]
handle: JoinHandle<()>,
}
#[metatype]
impl lb_task {}

32
crates/lb/tests/net.rs Normal file
View File

@ -0,0 +1,32 @@
use lb::runtime;
use luaify::luaify;
use luajit::{Chunk, LoadMode};
use tokio::test;
async fn run_lua(s: &'static str) {
let rt = runtime::Builder::new().build().unwrap();
let task = rt.spawn(async move |state| {
println!("executing test chunk: {s}");
state
.load(Chunk::new(s).mode(LoadMode::TEXT))
.unwrap_or_else(|err| panic!("{err}"));
state
.call_async(0, 0)
.await
.unwrap_or_else(|err| panic!("{err}"));
});
rt.await;
task.await.unwrap_or_else(|err| panic!("{err}"));
}
#[test]
async fn ipaddr() {
run_lua(luaify!({
let net = require("lb:net");
print(net.ipaddr("127.0.0.1"));
}))
.await
}

35
crates/lb/tests/task.rs Normal file
View File

@ -0,0 +1,35 @@
use lb::runtime;
use luaify::luaify;
use luajit::{Chunk, LoadMode};
use tokio::test;
async fn run_lua(s: &'static str) {
let rt = runtime::Builder::new().build().unwrap();
let task = rt.spawn(async move |state| {
println!("executing test chunk: {s}");
state
.load(Chunk::new(s).mode(LoadMode::TEXT))
.unwrap_or_else(|err| panic!("{err}"));
state
.call_async(0, 0)
.await
.unwrap_or_else(|err| panic!("{err}"));
});
rt.await;
task.await.unwrap_or_else(|err| panic!("{err}"));
}
#[test]
async fn task_test() {
run_lua(luaify!({
let thing = spawn(|| {
print("spawn callback!!!!!!!!!!!!!");
});
print("thing is", thing);
//
}))
.await
}