diff --git a/src/args.rs b/src/args.rs deleted file mode 100644 index d45d5c2..0000000 --- a/src/args.rs +++ /dev/null @@ -1,263 +0,0 @@ -#![allow(dead_code)] - -use std::time::Duration; - -use mlua::prelude::*; - -#[derive(Debug, Default)] -pub enum Arg { - #[default] - Nil, - Bool(bool), - Number(f64), - String(String), -} - -impl IntoLua<'_> for Arg { - #[inline] - fn into_lua(self, lua: &Lua) -> LuaResult { - match self { - Arg::Nil => Ok(LuaValue::Nil), - Arg::Bool(b) => Ok(LuaValue::Boolean(b)), - Arg::Number(n) => Ok(LuaValue::Number(n)), - Arg::String(s) => Ok(LuaValue::String(lua.create_string(&s)?)), - } - } -} - -// Primitives - -impl From<()> for Arg { - #[inline] - fn from(_: ()) -> Self { - Arg::Nil - } -} - -impl From for Arg { - #[inline] - fn from(b: bool) -> Self { - Arg::Bool(b) - } -} - -impl From for Arg { - #[inline] - fn from(u: u8) -> Self { - Arg::Number(u as f64) - } -} - -impl From for Arg { - #[inline] - fn from(u: u16) -> Self { - Arg::Number(u as f64) - } -} - -impl From for Arg { - #[inline] - fn from(u: u32) -> Self { - Arg::Number(u as f64) - } -} - -impl From for Arg { - #[inline] - fn from(u: u64) -> Self { - Arg::Number(u as f64) - } -} - -impl From for Arg { - #[inline] - fn from(i: i8) -> Self { - Arg::Number(i as f64) - } -} - -impl From for Arg { - #[inline] - fn from(i: i16) -> Self { - Arg::Number(i as f64) - } -} - -impl From for Arg { - #[inline] - fn from(i: i32) -> Self { - Arg::Number(i as f64) - } -} - -impl From for Arg { - #[inline] - fn from(i: i64) -> Self { - Arg::Number(i as f64) - } -} - -impl From for Arg { - #[inline] - fn from(n: f32) -> Self { - Arg::Number(n as f64) - } -} - -impl From for Arg { - #[inline] - fn from(n: f64) -> Self { - Arg::Number(n) - } -} - -impl From for Arg { - #[inline] - fn from(s: String) -> Self { - Arg::String(s) - } -} - -impl From<&String> for Arg { - #[inline] - fn from(s: &String) -> Self { - Arg::String(s.to_owned()) - } -} - -impl From<&str> for Arg { - #[inline] - fn from(s: &str) -> Self { - Arg::String(s.to_owned()) - } -} - -// Other types - -impl From for Arg { - #[inline] - fn from(d: Duration) -> Self { - Arg::Number(d.as_secs_f64()) - } -} - -// Multi args - -#[derive(Debug, Default)] -pub struct Args { - inner: Vec, -} - -impl Args { - #[inline] - pub fn new() -> Self { - Self::default() - } -} - -impl IntoLuaMulti<'_> for Args { - #[inline] - fn into_lua_multi(self, lua: &Lua) -> LuaResult { - let mut values = Vec::new(); - for arg in self.inner { - values.push(arg.into_lua(lua)?); - } - Ok(LuaMultiValue::from_vec(values)) - } -} - -// Boilerplate - -impl From for Args -where - T: Into, -{ - #[inline] - fn from(t: T) -> Self { - Args { - inner: vec![t.into()], - } - } -} - -impl From<(T0, T1)> for Args -where - T0: Into, - T1: Into, -{ - #[inline] - fn from((t0, t1): (T0, T1)) -> Self { - Args { - inner: vec![t0.into(), t1.into()], - } - } -} - -impl From<(T0, T1, T2)> for Args -where - T0: Into, - T1: Into, - T2: Into, -{ - #[inline] - fn from((t0, t1, t2): (T0, T1, T2)) -> Self { - Args { - inner: vec![t0.into(), t1.into(), t2.into()], - } - } -} - -impl From<(T0, T1, T2, T3)> for Args -where - T0: Into, - T1: Into, - T2: Into, - T3: Into, -{ - #[inline] - fn from((t0, t1, t2, t3): (T0, T1, T2, T3)) -> Self { - Args { - inner: vec![t0.into(), t1.into(), t2.into(), t3.into()], - } - } -} - -impl From<(T0, T1, T2, T3, T4)> for Args -where - T0: Into, - T1: Into, - T2: Into, - T3: Into, - T4: Into, -{ - #[inline] - fn from((t0, t1, t2, t3, t4): (T0, T1, T2, T3, T4)) -> Self { - Args { - inner: vec![t0.into(), t1.into(), t2.into(), t3.into(), t4.into()], - } - } -} - -impl From<(T0, T1, T2, T3, T4, T5)> for Args -where - T0: Into, - T1: Into, - T2: Into, - T3: Into, - T4: Into, - T5: Into, -{ - #[inline] - fn from((t0, t1, t2, t3, t4, t5): (T0, T1, T2, T3, T4, T5)) -> Self { - Args { - inner: vec![ - t0.into(), - t1.into(), - t2.into(), - t3.into(), - t4.into(), - t5.into(), - ], - } - } -} diff --git a/src/lua_ext.rs b/src/lua_ext.rs index aa9654a..b8098d7 100644 --- a/src/lua_ext.rs +++ b/src/lua_ext.rs @@ -3,13 +3,13 @@ use std::future::Future; use mlua::prelude::*; use tokio::spawn; -use crate::{Args, Message, MessageSender, ThreadId}; +use crate::{AsyncValues, Message, MessageSender, ThreadId}; pub trait LuaSchedulerExt<'lua> { fn create_async_function(&'lua self, func: F) -> LuaResult> where A: FromLuaMulti<'lua> + 'static, - R: Into + Send + 'static, + R: Into + Send + 'static, F: Fn(&'lua Lua, A) -> FR + 'static, FR: Future> + Send + 'static; } @@ -18,7 +18,7 @@ impl<'lua> LuaSchedulerExt<'lua> for Lua { fn create_async_function(&'lua self, func: F) -> LuaResult> where A: FromLuaMulti<'lua> + 'static, - R: Into + Send + 'static, + R: Into + Send + 'static, F: Fn(&'lua Lua, A) -> FR + 'static, FR: Future> + Send + 'static, { diff --git a/src/main.rs b/src/main.rs index c3161b9..686e2bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,20 +9,20 @@ use tokio::{ time::{sleep, Instant}, }; -mod args; mod error_storage; mod lua; mod lua_ext; mod message; mod stats; mod thread_id; +mod value; -use args::*; use error_storage::*; use lua::*; use message::*; use stats::*; use thread_id::*; +use value::*; const NUM_TEST_BATCHES: usize = 20; const NUM_TEST_THREADS: usize = 50_000; @@ -82,7 +82,7 @@ fn main_lua_task(mut rx: MessageReceiver, tx: MessageSender, stats: Stats) -> Lu let main_fn = lua.load(MAIN_CHUNK).into_function()?; for _ in 0..NUM_TEST_THREADS { let thread = lua.create_thread(main_fn.clone())?; - runnable_threads.insert(ThreadId::from(&thread), (thread, Ok(Args::new()))); + runnable_threads.insert(ThreadId::from(&thread), (thread, Ok(AsyncValues::new()))); } loop { @@ -99,7 +99,7 @@ fn main_lua_task(mut rx: MessageReceiver, tx: MessageSender, stats: Stats) -> Lu Ok(a) => a, Err(e) => { error_storage.replace(e); - Args::from(()) + AsyncValues::from(()) } }; if let Err(e) = thread.resume::<_, ()>(args) { @@ -177,7 +177,7 @@ async fn main_async_task( spawn(async move { sleep(duration).await; let elapsed = Instant::now() - yielded_at; - tx.send(Message::Resume(thread_id, Ok(Args::from(elapsed)))) + tx.send(Message::Resume(thread_id, Ok(AsyncValues::from(elapsed)))) }); } Message::Error(_, e) => { diff --git a/src/message.rs b/src/message.rs index 282bd80..1563a4a 100644 --- a/src/message.rs +++ b/src/message.rs @@ -6,13 +6,13 @@ use tokio::{ time::Instant, }; -use crate::{Args, ThreadId}; +use crate::{AsyncValues, ThreadId}; pub type MessageSender = UnboundedSender; pub type MessageReceiver = UnboundedReceiver; pub enum Message { - Resume(ThreadId, LuaResult), + Resume(ThreadId, LuaResult), Cancel(ThreadId), Sleep(ThreadId, Instant, Duration), Error(ThreadId, Box), diff --git a/src/value.rs b/src/value.rs new file mode 100644 index 0000000..f6181a4 --- /dev/null +++ b/src/value.rs @@ -0,0 +1,287 @@ +#![allow(dead_code)] + +use std::time::Duration; + +use mlua::prelude::*; + +#[derive(Debug, Default)] +pub enum AsyncValue { + #[default] + Nil, + Bool(bool), + Number(f64), + String(String), + Bytes(Vec), +} + +impl IntoLua<'_> for AsyncValue { + #[inline] + fn into_lua(self, lua: &Lua) -> LuaResult { + match self { + AsyncValue::Nil => Ok(LuaValue::Nil), + AsyncValue::Bool(b) => Ok(LuaValue::Boolean(b)), + AsyncValue::Number(n) => Ok(LuaValue::Number(n)), + AsyncValue::String(s) => Ok(LuaValue::String(lua.create_string(&s)?)), + AsyncValue::Bytes(b) => Ok(LuaValue::String(lua.create_string(&b)?)), + } + } +} + +// Primitives + +impl From<()> for AsyncValue { + #[inline] + fn from(_: ()) -> Self { + AsyncValue::Nil + } +} + +impl From for AsyncValue { + #[inline] + fn from(b: bool) -> Self { + AsyncValue::Bool(b) + } +} + +impl From for AsyncValue { + #[inline] + fn from(u: u8) -> Self { + AsyncValue::Number(u as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(u: u16) -> Self { + AsyncValue::Number(u as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(u: u32) -> Self { + AsyncValue::Number(u as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(u: u64) -> Self { + AsyncValue::Number(u as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(i: i8) -> Self { + AsyncValue::Number(i as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(i: i16) -> Self { + AsyncValue::Number(i as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(i: i32) -> Self { + AsyncValue::Number(i as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(i: i64) -> Self { + AsyncValue::Number(i as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(n: f32) -> Self { + AsyncValue::Number(n as f64) + } +} + +impl From for AsyncValue { + #[inline] + fn from(n: f64) -> Self { + AsyncValue::Number(n) + } +} + +impl From for AsyncValue { + #[inline] + fn from(s: String) -> Self { + AsyncValue::String(s) + } +} + +impl From<&String> for AsyncValue { + #[inline] + fn from(s: &String) -> Self { + AsyncValue::String(s.to_owned()) + } +} + +impl From<&str> for AsyncValue { + #[inline] + fn from(s: &str) -> Self { + AsyncValue::String(s.to_owned()) + } +} + +impl From> for AsyncValue { + #[inline] + fn from(b: Vec) -> Self { + AsyncValue::Bytes(b) + } +} + +impl From<&Vec> for AsyncValue { + #[inline] + fn from(b: &Vec) -> Self { + AsyncValue::Bytes(b.to_owned()) + } +} + +impl From<&[u8]> for AsyncValue { + #[inline] + fn from(b: &[u8]) -> Self { + AsyncValue::Bytes(b.to_owned()) + } +} + +// Other types + +impl From for AsyncValue { + #[inline] + fn from(d: Duration) -> Self { + AsyncValue::Number(d.as_secs_f64()) + } +} + +// Multi args + +#[derive(Debug, Default)] +pub struct AsyncValues { + inner: Vec, +} + +impl AsyncValues { + #[inline] + pub fn new() -> Self { + Self::default() + } +} + +impl IntoLuaMulti<'_> for AsyncValues { + #[inline] + fn into_lua_multi(self, lua: &Lua) -> LuaResult { + Ok(LuaMultiValue::from_vec( + self.inner + .into_iter() + .map(|arg| arg.into_lua(lua)) + .collect::>>()?, + )) + } +} + +// Boilerplate + +impl From for AsyncValues +where + T: Into, +{ + #[inline] + fn from(t: T) -> Self { + AsyncValues { + inner: vec![t.into()], + } + } +} + +impl From<(T0, T1)> for AsyncValues +where + T0: Into, + T1: Into, +{ + #[inline] + fn from((t0, t1): (T0, T1)) -> Self { + AsyncValues { + inner: vec![t0.into(), t1.into()], + } + } +} + +impl From<(T0, T1, T2)> for AsyncValues +where + T0: Into, + T1: Into, + T2: Into, +{ + #[inline] + fn from((t0, t1, t2): (T0, T1, T2)) -> Self { + AsyncValues { + inner: vec![t0.into(), t1.into(), t2.into()], + } + } +} + +impl From<(T0, T1, T2, T3)> for AsyncValues +where + T0: Into, + T1: Into, + T2: Into, + T3: Into, +{ + #[inline] + fn from((t0, t1, t2, t3): (T0, T1, T2, T3)) -> Self { + AsyncValues { + inner: vec![t0.into(), t1.into(), t2.into(), t3.into()], + } + } +} + +impl From<(T0, T1, T2, T3, T4)> for AsyncValues +where + T0: Into, + T1: Into, + T2: Into, + T3: Into, + T4: Into, +{ + #[inline] + fn from((t0, t1, t2, t3, t4): (T0, T1, T2, T3, T4)) -> Self { + AsyncValues { + inner: vec![t0.into(), t1.into(), t2.into(), t3.into(), t4.into()], + } + } +} + +impl From<(T0, T1, T2, T3, T4, T5)> for AsyncValues +where + T0: Into, + T1: Into, + T2: Into, + T3: Into, + T4: Into, + T5: Into, +{ + #[inline] + fn from((t0, t1, t2, t3, t4, t5): (T0, T1, T2, T3, T4, T5)) -> Self { + AsyncValues { + inner: vec![ + t0.into(), + t1.into(), + t2.into(), + t3.into(), + t4.into(), + t5.into(), + ], + } + } +}