mirror of
https://github.com/lune-org/lune.git
synced 2024-12-13 13:30:38 +00:00
Use static lua lifetime
This commit is contained in:
parent
709a69aa82
commit
6c49ef7e4a
11 changed files with 74 additions and 79 deletions
|
@ -5,7 +5,7 @@ use tokio::fs;
|
||||||
|
|
||||||
use crate::utils::table::TableBuilder;
|
use crate::utils::table::TableBuilder;
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_async_function("readFile", fs_read_file)?
|
.with_async_function("readFile", fs_read_file)?
|
||||||
.with_async_function("readDir", fs_read_dir)?
|
.with_async_function("readDir", fs_read_dir)?
|
||||||
|
@ -18,11 +18,11 @@ pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
.build_readonly()
|
.build_readonly()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_read_file(_: &Lua, path: String) -> LuaResult<String> {
|
async fn fs_read_file(_: &'static Lua, path: String) -> LuaResult<String> {
|
||||||
fs::read_to_string(&path).await.map_err(LuaError::external)
|
fs::read_to_string(&path).await.map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_read_dir(_: &Lua, path: String) -> LuaResult<Vec<String>> {
|
async fn fs_read_dir(_: &'static Lua, path: String) -> LuaResult<Vec<String>> {
|
||||||
let mut dir_strings = Vec::new();
|
let mut dir_strings = Vec::new();
|
||||||
let mut dir = fs::read_dir(&path).await.map_err(LuaError::external)?;
|
let mut dir = fs::read_dir(&path).await.map_err(LuaError::external)?;
|
||||||
while let Some(dir_entry) = dir.next_entry().await.map_err(LuaError::external)? {
|
while let Some(dir_entry) = dir.next_entry().await.map_err(LuaError::external)? {
|
||||||
|
@ -52,25 +52,25 @@ async fn fs_read_dir(_: &Lua, path: String) -> LuaResult<Vec<String>> {
|
||||||
Ok(dir_strings_no_prefix)
|
Ok(dir_strings_no_prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_write_file(_: &Lua, (path, contents): (String, String)) -> LuaResult<()> {
|
async fn fs_write_file(_: &'static Lua, (path, contents): (String, String)) -> LuaResult<()> {
|
||||||
fs::write(&path, &contents)
|
fs::write(&path, &contents)
|
||||||
.await
|
.await
|
||||||
.map_err(LuaError::external)
|
.map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_write_dir(_: &Lua, path: String) -> LuaResult<()> {
|
async fn fs_write_dir(_: &'static Lua, path: String) -> LuaResult<()> {
|
||||||
fs::create_dir_all(&path).await.map_err(LuaError::external)
|
fs::create_dir_all(&path).await.map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_remove_file(_: &Lua, path: String) -> LuaResult<()> {
|
async fn fs_remove_file(_: &'static Lua, path: String) -> LuaResult<()> {
|
||||||
fs::remove_file(&path).await.map_err(LuaError::external)
|
fs::remove_file(&path).await.map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_remove_dir(_: &Lua, path: String) -> LuaResult<()> {
|
async fn fs_remove_dir(_: &'static Lua, path: String) -> LuaResult<()> {
|
||||||
fs::remove_dir_all(&path).await.map_err(LuaError::external)
|
fs::remove_dir_all(&path).await.map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_is_file(_: &Lua, path: String) -> LuaResult<bool> {
|
async fn fs_is_file(_: &'static Lua, path: String) -> LuaResult<bool> {
|
||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
Ok(fs::metadata(path)
|
Ok(fs::metadata(path)
|
||||||
|
@ -82,7 +82,7 @@ async fn fs_is_file(_: &Lua, path: String) -> LuaResult<bool> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_is_dir(_: &Lua, path: String) -> LuaResult<bool> {
|
async fn fs_is_dir(_: &'static Lua, path: String) -> LuaResult<bool> {
|
||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
Ok(fs::metadata(path)
|
Ok(fs::metadata(path)
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl LuneGlobal {
|
||||||
Note that proxy globals should be handled with special care and that [`LuneGlobal::inject()`]
|
Note that proxy globals should be handled with special care and that [`LuneGlobal::inject()`]
|
||||||
should be preferred over manually creating and manipulating the value(s) of any Lune global.
|
should be preferred over manually creating and manipulating the value(s) of any Lune global.
|
||||||
*/
|
*/
|
||||||
pub fn value<'a>(&'a self, lua: &'a Lua) -> LuaResult<LuaTable> {
|
pub fn value(&self, lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
match self {
|
match self {
|
||||||
LuneGlobal::Fs => fs::create(lua),
|
LuneGlobal::Fs => fs::create(lua),
|
||||||
LuneGlobal::Net => net::create(lua),
|
LuneGlobal::Net => net::create(lua),
|
||||||
|
@ -98,7 +98,7 @@ impl LuneGlobal {
|
||||||
|
|
||||||
Refer to [`LuneGlobal::is_top_level()`] for more info on proxy globals.
|
Refer to [`LuneGlobal::is_top_level()`] for more info on proxy globals.
|
||||||
*/
|
*/
|
||||||
pub fn inject(self, lua: &Lua) -> LuaResult<()> {
|
pub fn inject(self, lua: &'static Lua) -> LuaResult<()> {
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
let table = self.value(lua)?;
|
let table = self.value(lua)?;
|
||||||
// NOTE: Top level globals are special, the values
|
// NOTE: Top level globals are special, the values
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::utils::{
|
||||||
table::TableBuilder,
|
table::TableBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
// Create a reusable client for performing our
|
// Create a reusable client for performing our
|
||||||
// web requests and store it in the lua registry
|
// web requests and store it in the lua registry
|
||||||
let mut default_headers = HeaderMap::new();
|
let mut default_headers = HeaderMap::new();
|
||||||
|
@ -43,7 +43,7 @@ pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
.build_readonly()
|
.build_readonly()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn net_json_encode(_: &Lua, (val, pretty): (LuaValue, Option<bool>)) -> LuaResult<String> {
|
fn net_json_encode(_: &'static Lua, (val, pretty): (LuaValue, Option<bool>)) -> LuaResult<String> {
|
||||||
if let Some(true) = pretty {
|
if let Some(true) = pretty {
|
||||||
serde_json::to_string_pretty(&val).map_err(LuaError::external)
|
serde_json::to_string_pretty(&val).map_err(LuaError::external)
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,12 +51,12 @@ fn net_json_encode(_: &Lua, (val, pretty): (LuaValue, Option<bool>)) -> LuaResul
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn net_json_decode(lua: &Lua, json: String) -> LuaResult<LuaValue> {
|
fn net_json_decode(lua: &'static Lua, json: String) -> LuaResult<LuaValue> {
|
||||||
let json: serde_json::Value = serde_json::from_str(&json).map_err(LuaError::external)?;
|
let json: serde_json::Value = serde_json::from_str(&json).map_err(LuaError::external)?;
|
||||||
lua.to_value(&json)
|
lua.to_value(&json)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn net_request<'lua>(lua: &'lua Lua, config: LuaValue<'lua>) -> LuaResult<LuaTable<'lua>> {
|
async fn net_request<'a>(lua: &'static Lua, config: LuaValue<'a>) -> LuaResult<LuaTable<'a>> {
|
||||||
let client: NetClient = lua.named_registry_value("NetClient")?;
|
let client: NetClient = lua.named_registry_value("NetClient")?;
|
||||||
// Extract stuff from config and make sure its all valid
|
// Extract stuff from config and make sure its all valid
|
||||||
let (url, method, headers, body) = match config {
|
let (url, method, headers, body) = match config {
|
||||||
|
@ -147,20 +147,16 @@ async fn net_request<'lua>(lua: &'lua Lua, config: LuaValue<'lua>) -> LuaResult<
|
||||||
.build_readonly()
|
.build_readonly()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn net_serve<'lua>(
|
async fn net_serve(lua: &'static Lua, (port, callback): (u16, LuaFunction<'_>)) -> LuaResult<()> {
|
||||||
lua: &'lua Lua,
|
|
||||||
(port, callback): (u16, LuaFunction<'lua>),
|
|
||||||
) -> LuaResult<()> {
|
|
||||||
let server_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap();
|
|
||||||
let server_sender = lua
|
let server_sender = lua
|
||||||
.app_data_ref::<Weak<Sender<LuneMessage>>>()
|
.app_data_ref::<Weak<Sender<LuneMessage>>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let server_callback = server_lua.create_registry_value(callback)?;
|
let server_callback = lua.create_registry_value(callback)?;
|
||||||
let server = Server::bind(&([127, 0, 0, 1], port).into())
|
let server = Server::bind(&([127, 0, 0, 1], port).into())
|
||||||
.executor(LocalExec)
|
.executor(LocalExec)
|
||||||
.serve(MakeNetService(server_lua, server_callback.into()));
|
.serve(MakeNetService(lua, server_callback.into()));
|
||||||
if let Err(err) = server.await.map_err(LuaError::external) {
|
if let Err(err) = server.await.map_err(LuaError::external) {
|
||||||
server_sender
|
server_sender
|
||||||
.send(LuneMessage::LuaError(err))
|
.send(LuneMessage::LuaError(err))
|
||||||
|
@ -173,7 +169,7 @@ async fn net_serve<'lua>(
|
||||||
// Hyper service implementation for net, lots of boilerplate here
|
// Hyper service implementation for net, lots of boilerplate here
|
||||||
// but make_svc and make_svc_function do not work for what we need
|
// but make_svc and make_svc_function do not work for what we need
|
||||||
|
|
||||||
pub struct NetService(Arc<Lua>, Arc<LuaRegistryKey>);
|
pub struct NetService(&'static Lua, Arc<LuaRegistryKey>);
|
||||||
|
|
||||||
impl Service<Request<Body>> for NetService {
|
impl Service<Request<Body>> for NetService {
|
||||||
type Response = Response<Body>;
|
type Response = Response<Body>;
|
||||||
|
@ -185,7 +181,7 @@ impl Service<Request<Body>> for NetService {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: Request<Body>) -> Self::Future {
|
fn call(&mut self, req: Request<Body>) -> Self::Future {
|
||||||
let lua = self.0.clone();
|
let lua = self.0;
|
||||||
let key = self.1.clone();
|
let key = self.1.clone();
|
||||||
let (parts, body) = req.into_parts();
|
let (parts, body) = req.into_parts();
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
|
@ -199,7 +195,7 @@ impl Service<Request<Body>> for NetService {
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// Create a readonly table for the request query params
|
// Create a readonly table for the request query params
|
||||||
let query_params = TableBuilder::new(&lua)?
|
let query_params = TableBuilder::new(lua)?
|
||||||
.with_values(
|
.with_values(
|
||||||
parts
|
parts
|
||||||
.uri
|
.uri
|
||||||
|
@ -211,7 +207,7 @@ impl Service<Request<Body>> for NetService {
|
||||||
)?
|
)?
|
||||||
.build_readonly()?;
|
.build_readonly()?;
|
||||||
// Do the same for headers
|
// Do the same for headers
|
||||||
let header_map = TableBuilder::new(&lua)?
|
let header_map = TableBuilder::new(lua)?
|
||||||
.with_values(
|
.with_values(
|
||||||
parts
|
parts
|
||||||
.headers
|
.headers
|
||||||
|
@ -223,7 +219,7 @@ impl Service<Request<Body>> for NetService {
|
||||||
)?
|
)?
|
||||||
.build_readonly()?;
|
.build_readonly()?;
|
||||||
// Create a readonly table with request info to pass to the handler
|
// Create a readonly table with request info to pass to the handler
|
||||||
let request = TableBuilder::new(&lua)?
|
let request = TableBuilder::new(lua)?
|
||||||
.with_value("path", parts.uri.path())?
|
.with_value("path", parts.uri.path())?
|
||||||
.with_value("query", query_params)?
|
.with_value("query", query_params)?
|
||||||
.with_value("method", parts.method.as_str())?
|
.with_value("method", parts.method.as_str())?
|
||||||
|
@ -287,7 +283,7 @@ impl Service<Request<Body>> for NetService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MakeNetService(Arc<Lua>, Arc<LuaRegistryKey>);
|
struct MakeNetService(&'static Lua, Arc<LuaRegistryKey>);
|
||||||
|
|
||||||
impl Service<&AddrStream> for MakeNetService {
|
impl Service<&AddrStream> for MakeNetService {
|
||||||
type Response = NetService;
|
type Response = NetService;
|
||||||
|
@ -299,7 +295,7 @@ impl Service<&AddrStream> for MakeNetService {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, _: &AddrStream) -> Self::Future {
|
fn call(&mut self, _: &AddrStream) -> Self::Future {
|
||||||
let lua = self.0.clone();
|
let lua = self.0;
|
||||||
let key = self.1.clone();
|
let key = self.1.clone();
|
||||||
Box::pin(async move { Ok(NetService(lua, key)) })
|
Box::pin(async move { Ok(NetService(lua, key)) })
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::utils::{
|
||||||
table::TableBuilder,
|
table::TableBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(lua: &Lua, args_vec: Vec<String>) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua, args_vec: Vec<String>) -> LuaResult<LuaTable> {
|
||||||
let cwd = env::current_dir()?.canonicalize()?;
|
let cwd = env::current_dir()?.canonicalize()?;
|
||||||
let mut cwd_str = cwd.to_string_lossy().to_string();
|
let mut cwd_str = cwd.to_string_lossy().to_string();
|
||||||
if !cwd_str.ends_with('/') {
|
if !cwd_str.ends_with('/') {
|
||||||
|
@ -40,10 +40,10 @@ pub fn create(lua: &Lua, args_vec: Vec<String>) -> LuaResult<LuaTable> {
|
||||||
.build_readonly()
|
.build_readonly()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_env_get<'lua>(
|
fn process_env_get<'a>(
|
||||||
lua: &'lua Lua,
|
lua: &'static Lua,
|
||||||
(_, key): (LuaValue<'lua>, String),
|
(_, key): (LuaValue<'a>, String),
|
||||||
) -> LuaResult<LuaValue<'lua>> {
|
) -> LuaResult<LuaValue<'a>> {
|
||||||
match env::var_os(key) {
|
match env::var_os(key) {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
let raw_value = RawOsString::new(value);
|
let raw_value = RawOsString::new(value);
|
||||||
|
@ -55,7 +55,10 @@ fn process_env_get<'lua>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_env_set(_: &Lua, (_, key, value): (LuaValue, String, Option<String>)) -> LuaResult<()> {
|
fn process_env_set(
|
||||||
|
_: &'static Lua,
|
||||||
|
(_, key, value): (LuaValue, String, Option<String>),
|
||||||
|
) -> LuaResult<()> {
|
||||||
// Make sure key is valid, otherwise set_var will panic
|
// Make sure key is valid, otherwise set_var will panic
|
||||||
if key.is_empty() {
|
if key.is_empty() {
|
||||||
Err(LuaError::RuntimeError("Key must not be empty".to_string()))
|
Err(LuaError::RuntimeError("Key must not be empty".to_string()))
|
||||||
|
@ -106,12 +109,12 @@ fn process_env_iter<'lua>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_exit(lua: &Lua, exit_code: Option<u8>) -> LuaResult<()> {
|
async fn process_exit(lua: &'static Lua, exit_code: Option<u8>) -> LuaResult<()> {
|
||||||
exit_and_yield_forever(lua, exit_code).await
|
exit_and_yield_forever(lua, exit_code).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_spawn<'a>(
|
async fn process_spawn<'a>(
|
||||||
lua: &'a Lua,
|
lua: &'static Lua,
|
||||||
(mut program, args, options): (String, Option<Vec<String>>, Option<LuaTable<'a>>),
|
(mut program, args, options): (String, Option<Vec<String>>, Option<LuaTable<'a>>),
|
||||||
) -> LuaResult<LuaTable<'a>> {
|
) -> LuaResult<LuaTable<'a>> {
|
||||||
// Parse any given options or create defaults
|
// Parse any given options or create defaults
|
||||||
|
|
|
@ -9,7 +9,7 @@ use os_str_bytes::{OsStrBytes, RawOsStr};
|
||||||
|
|
||||||
use crate::utils::table::TableBuilder;
|
use crate::utils::table::TableBuilder;
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
let require: LuaFunction = lua.globals().raw_get("require")?;
|
let require: LuaFunction = lua.globals().raw_get("require")?;
|
||||||
// Preserve original require behavior if we have a special env var set
|
// Preserve original require behavior if we have a special env var set
|
||||||
if env::var_os("LUAU_PWD_REQUIRE").is_some() {
|
if env::var_os("LUAU_PWD_REQUIRE").is_some() {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::utils::{
|
||||||
table::TableBuilder,
|
table::TableBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_function("color", |_, color: String| {
|
.with_function("color", |_, color: String| {
|
||||||
let ansi_string = format_style(style_from_color_str(&color)?);
|
let ansi_string = format_style(style_from_color_str(&color)?);
|
||||||
|
@ -38,7 +38,7 @@ fn prompt_theme() -> ColorfulTheme {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt<'a>(
|
fn prompt<'a>(
|
||||||
lua: &'a Lua,
|
lua: &'static Lua,
|
||||||
(kind, message, options): (Option<String>, Option<String>, LuaValue<'a>),
|
(kind, message, options): (Option<String>, Option<String>, LuaValue<'a>),
|
||||||
) -> LuaResult<LuaValue<'a>> {
|
) -> LuaResult<LuaValue<'a>> {
|
||||||
match kind.map(|k| k.trim().to_ascii_lowercase()).as_deref() {
|
match kind.map(|k| k.trim().to_ascii_lowercase()).as_deref() {
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use std::{
|
use std::time::{Duration, Instant};
|
||||||
sync::Weak,
|
|
||||||
time::{Duration, Instant},
|
|
||||||
};
|
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
|
@ -13,7 +10,7 @@ use crate::utils::{
|
||||||
|
|
||||||
const MINIMUM_WAIT_OR_DELAY_DURATION: f32 = 10.0 / 1_000.0; // 10ms
|
const MINIMUM_WAIT_OR_DELAY_DURATION: f32 = 10.0 / 1_000.0; // 10ms
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
// HACK: There is no way to call coroutine.close directly from the mlua
|
// HACK: There is no way to call coroutine.close directly from the mlua
|
||||||
// crate, so we need to fetch the function and store it in the registry
|
// crate, so we need to fetch the function and store it in the registry
|
||||||
let coroutine: LuaTable = lua.globals().raw_get("coroutine")?;
|
let coroutine: LuaTable = lua.globals().raw_get("coroutine")?;
|
||||||
|
@ -33,8 +30,11 @@ pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
.build_readonly()
|
.build_readonly()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tof_to_thread<'a>(lua: &'a Lua, tof: LuaValue<'a>) -> LuaResult<LuaThread<'a>> {
|
fn tof_to_thread<'a>(
|
||||||
match tof {
|
lua: &'static Lua,
|
||||||
|
thread_or_function: LuaValue<'a>,
|
||||||
|
) -> LuaResult<LuaThread<'a>> {
|
||||||
|
match thread_or_function {
|
||||||
LuaValue::Thread(t) => Ok(t),
|
LuaValue::Thread(t) => Ok(t),
|
||||||
LuaValue::Function(f) => Ok(lua.create_thread(f)?),
|
LuaValue::Function(f) => Ok(lua.create_thread(f)?),
|
||||||
value => Err(LuaError::RuntimeError(format!(
|
value => Err(LuaError::RuntimeError(format!(
|
||||||
|
@ -44,31 +44,29 @@ fn tof_to_thread<'a>(lua: &'a Lua, tof: LuaValue<'a>) -> LuaResult<LuaThread<'a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_cancel<'a>(lua: &'a Lua, thread: LuaThread<'a>) -> LuaResult<()> {
|
async fn task_cancel<'a>(lua: &'static Lua, thread: LuaThread<'a>) -> LuaResult<()> {
|
||||||
let close: LuaFunction = lua.named_registry_value("coroutine.close")?;
|
let close: LuaFunction = lua.named_registry_value("coroutine.close")?;
|
||||||
close.call_async::<_, LuaMultiValue>(thread).await?;
|
close.call_async::<_, LuaMultiValue>(thread).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_defer<'a>(
|
async fn task_defer<'a>(
|
||||||
lua: &'a Lua,
|
lua: &'static Lua,
|
||||||
(tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
|
(tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
|
||||||
) -> LuaResult<LuaThread<'a>> {
|
) -> LuaResult<LuaThread<'a>> {
|
||||||
// Spawn a new detached task using a lua reference that we can use inside of our task
|
|
||||||
let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap();
|
|
||||||
let task_thread = tof_to_thread(lua, tof)?;
|
let task_thread = tof_to_thread(lua, tof)?;
|
||||||
let task_thread_key = lua.create_registry_value(task_thread)?;
|
let task_thread_key = lua.create_registry_value(task_thread)?;
|
||||||
let task_args_key = lua.create_registry_value(args.into_vec())?;
|
let task_args_key = lua.create_registry_value(args.into_vec())?;
|
||||||
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
||||||
run_registered_task(lua, TaskRunMode::Deferred, async move {
|
run_registered_task(lua, TaskRunMode::Deferred, async move {
|
||||||
let thread: LuaThread = task_lua.registry_value(&task_thread_key)?;
|
let thread: LuaThread = lua.registry_value(&task_thread_key)?;
|
||||||
let argsv: Vec<LuaValue> = task_lua.registry_value(&task_args_key)?;
|
let argsv: Vec<LuaValue> = lua.registry_value(&task_args_key)?;
|
||||||
let args = LuaMultiValue::from_vec(argsv);
|
let args = LuaMultiValue::from_vec(argsv);
|
||||||
if thread.status() == LuaThreadStatus::Resumable {
|
if thread.status() == LuaThreadStatus::Resumable {
|
||||||
let _: LuaMultiValue = thread.into_async(args).await?;
|
let _: LuaMultiValue = thread.into_async(args).await?;
|
||||||
}
|
}
|
||||||
task_lua.remove_registry_value(task_thread_key)?;
|
lua.remove_registry_value(task_thread_key)?;
|
||||||
task_lua.remove_registry_value(task_args_key)?;
|
lua.remove_registry_value(task_args_key)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -76,25 +74,23 @@ async fn task_defer<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_delay<'a>(
|
async fn task_delay<'a>(
|
||||||
lua: &'a Lua,
|
lua: &'static Lua,
|
||||||
(duration, tof, args): (Option<f32>, LuaValue<'a>, LuaMultiValue<'a>),
|
(duration, tof, args): (Option<f32>, LuaValue<'a>, LuaMultiValue<'a>),
|
||||||
) -> LuaResult<LuaThread<'a>> {
|
) -> LuaResult<LuaThread<'a>> {
|
||||||
// Spawn a new detached task using a lua reference that we can use inside of our task
|
|
||||||
let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap();
|
|
||||||
let task_thread = tof_to_thread(lua, tof)?;
|
let task_thread = tof_to_thread(lua, tof)?;
|
||||||
let task_thread_key = lua.create_registry_value(task_thread)?;
|
let task_thread_key = lua.create_registry_value(task_thread)?;
|
||||||
let task_args_key = lua.create_registry_value(args.into_vec())?;
|
let task_args_key = lua.create_registry_value(args.into_vec())?;
|
||||||
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
||||||
run_registered_task(lua, TaskRunMode::Deferred, async move {
|
run_registered_task(lua, TaskRunMode::Deferred, async move {
|
||||||
task_wait(&task_lua, duration).await?;
|
task_wait(lua, duration).await?;
|
||||||
let thread: LuaThread = task_lua.registry_value(&task_thread_key)?;
|
let thread: LuaThread = lua.registry_value(&task_thread_key)?;
|
||||||
let argsv: Vec<LuaValue> = task_lua.registry_value(&task_args_key)?;
|
let argsv: Vec<LuaValue> = lua.registry_value(&task_args_key)?;
|
||||||
let args = LuaMultiValue::from_vec(argsv);
|
let args = LuaMultiValue::from_vec(argsv);
|
||||||
if thread.status() == LuaThreadStatus::Resumable {
|
if thread.status() == LuaThreadStatus::Resumable {
|
||||||
let _: LuaMultiValue = thread.into_async(args).await?;
|
let _: LuaMultiValue = thread.into_async(args).await?;
|
||||||
}
|
}
|
||||||
task_lua.remove_registry_value(task_thread_key)?;
|
lua.remove_registry_value(task_thread_key)?;
|
||||||
task_lua.remove_registry_value(task_args_key)?;
|
lua.remove_registry_value(task_args_key)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -102,31 +98,29 @@ async fn task_delay<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_spawn<'a>(
|
async fn task_spawn<'a>(
|
||||||
lua: &'a Lua,
|
lua: &'static Lua,
|
||||||
(tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
|
(tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
|
||||||
) -> LuaResult<LuaThread<'a>> {
|
) -> LuaResult<LuaThread<'a>> {
|
||||||
// Spawn a new detached task using a lua reference that we can use inside of our task
|
|
||||||
let task_lua = lua.app_data_ref::<Weak<Lua>>().unwrap().upgrade().unwrap();
|
|
||||||
let task_thread = tof_to_thread(lua, tof)?;
|
let task_thread = tof_to_thread(lua, tof)?;
|
||||||
let task_thread_key = lua.create_registry_value(task_thread)?;
|
let task_thread_key = lua.create_registry_value(task_thread)?;
|
||||||
let task_args_key = lua.create_registry_value(args.into_vec())?;
|
let task_args_key = lua.create_registry_value(args.into_vec())?;
|
||||||
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
||||||
run_registered_task(lua, TaskRunMode::Instant, async move {
|
run_registered_task(lua, TaskRunMode::Instant, async move {
|
||||||
let thread: LuaThread = task_lua.registry_value(&task_thread_key)?;
|
let thread: LuaThread = lua.registry_value(&task_thread_key)?;
|
||||||
let argsv: Vec<LuaValue> = task_lua.registry_value(&task_args_key)?;
|
let argsv: Vec<LuaValue> = lua.registry_value(&task_args_key)?;
|
||||||
let args = LuaMultiValue::from_vec(argsv);
|
let args = LuaMultiValue::from_vec(argsv);
|
||||||
if thread.status() == LuaThreadStatus::Resumable {
|
if thread.status() == LuaThreadStatus::Resumable {
|
||||||
let _: LuaMultiValue = thread.into_async(args).await?;
|
let _: LuaMultiValue = thread.into_async(args).await?;
|
||||||
}
|
}
|
||||||
task_lua.remove_registry_value(task_thread_key)?;
|
lua.remove_registry_value(task_thread_key)?;
|
||||||
task_lua.remove_registry_value(task_args_key)?;
|
lua.remove_registry_value(task_args_key)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
Ok(lua_thread_to_return)
|
Ok(lua_thread_to_return)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_wait(lua: &Lua, duration: Option<f32>) -> LuaResult<f32> {
|
async fn task_wait(lua: &'static Lua, duration: Option<f32>) -> LuaResult<f32> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
run_registered_task(lua, TaskRunMode::Blocking, async move {
|
run_registered_task(lua, TaskRunMode::Blocking, async move {
|
||||||
time::sleep(Duration::from_secs_f32(
|
time::sleep(Duration::from_secs_f32(
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::utils::{
|
||||||
table::TableBuilder,
|
table::TableBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
// HACK: We need to preserve the default behavior of the
|
// HACK: We need to preserve the default behavior of the
|
||||||
// print and error functions, for pcall and such, which
|
// print and error functions, for pcall and such, which
|
||||||
|
|
|
@ -76,6 +76,10 @@ impl Lune {
|
||||||
Some Lune globals such as [`LuneGlobal::Process`] may spawn
|
Some Lune globals such as [`LuneGlobal::Process`] may spawn
|
||||||
separate tokio tasks on other threads, but the Luau environment
|
separate tokio tasks on other threads, but the Luau environment
|
||||||
itself is guaranteed to run on a single thread in the local set.
|
itself is guaranteed to run on a single thread in the local set.
|
||||||
|
|
||||||
|
Note that this will create a static Lua instance that will live
|
||||||
|
for the remainer of the program, and that this leaks memory using
|
||||||
|
[`Box::leak`] that will then get deallocated when the program exits.
|
||||||
*/
|
*/
|
||||||
pub async fn run(
|
pub async fn run(
|
||||||
&self,
|
&self,
|
||||||
|
@ -84,18 +88,16 @@ impl Lune {
|
||||||
) -> Result<ExitCode, LuaError> {
|
) -> Result<ExitCode, LuaError> {
|
||||||
let task_set = task::LocalSet::new();
|
let task_set = task::LocalSet::new();
|
||||||
let (sender, mut receiver) = mpsc::channel::<LuneMessage>(64);
|
let (sender, mut receiver) = mpsc::channel::<LuneMessage>(64);
|
||||||
let lua = Arc::new(mlua::Lua::new());
|
let lua = Lua::new().into_static();
|
||||||
let snd = Arc::new(sender);
|
let snd = Arc::new(sender);
|
||||||
lua.set_app_data(Arc::downgrade(&lua));
|
|
||||||
lua.set_app_data(Arc::downgrade(&snd));
|
lua.set_app_data(Arc::downgrade(&snd));
|
||||||
// Add in wanted lune globals
|
// Add in wanted lune globals
|
||||||
for global in self.includes.clone() {
|
for global in self.includes.clone() {
|
||||||
if !self.excludes.contains(&global) {
|
if !self.excludes.contains(&global) {
|
||||||
global.inject(&lua)?;
|
global.inject(lua)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Spawn the main thread from our entrypoint script
|
// Spawn the main thread from our entrypoint script
|
||||||
let script_lua = lua.clone();
|
|
||||||
let script_name = script_name.to_string();
|
let script_name = script_name.to_string();
|
||||||
let script_chunk = script_contents.to_string();
|
let script_chunk = script_contents.to_string();
|
||||||
let script_sender = snd.clone();
|
let script_sender = snd.clone();
|
||||||
|
@ -104,7 +106,7 @@ impl Lune {
|
||||||
.await
|
.await
|
||||||
.map_err(LuaError::external)?;
|
.map_err(LuaError::external)?;
|
||||||
task_set.spawn_local(async move {
|
task_set.spawn_local(async move {
|
||||||
let result = script_lua
|
let result = lua
|
||||||
.load(&script_chunk)
|
.load(&script_chunk)
|
||||||
.set_name(&format!("={script_name}"))
|
.set_name(&format!("={script_name}"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub async fn pipe_and_inherit_child_process_stdio(
|
||||||
Ok::<_, LuaError>((status, stdout_buffer?, stderr_buffer?))
|
Ok::<_, LuaError>((status, stdout_buffer?, stderr_buffer?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn exit_and_yield_forever(lua: &Lua, exit_code: Option<u8>) -> LuaResult<()> {
|
pub async fn exit_and_yield_forever(lua: &'static Lua, exit_code: Option<u8>) -> LuaResult<()> {
|
||||||
let sender = lua
|
let sender = lua
|
||||||
.app_data_ref::<Weak<Sender<LuneMessage>>>()
|
.app_data_ref::<Weak<Sender<LuneMessage>>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl fmt::Display for TaskRunMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_registered_task<T>(
|
pub async fn run_registered_task<T>(
|
||||||
lua: &Lua,
|
lua: &'static Lua,
|
||||||
mode: TaskRunMode,
|
mode: TaskRunMode,
|
||||||
to_run: impl Future<Output = LuaResult<T>> + 'static,
|
to_run: impl Future<Output = LuaResult<T>> + 'static,
|
||||||
) -> LuaResult<()> {
|
) -> LuaResult<()> {
|
||||||
|
|
Loading…
Reference in a new issue