mirror of
https://github.com/CompeyDev/lune-packaging.git
synced 2025-01-09 12:19:09 +00:00
Lune library internal util improvements, type definition improvements
This commit is contained in:
parent
2eb12c9aed
commit
d4ad835fd8
10 changed files with 118 additions and 105 deletions
6
lune.yml
6
lune.yml
|
@ -78,17 +78,17 @@ globals:
|
||||||
task.defer:
|
task.defer:
|
||||||
args:
|
args:
|
||||||
- type: thread | function
|
- type: thread | function
|
||||||
- type: "..."
|
# - type: "..."
|
||||||
task.delay:
|
task.delay:
|
||||||
args:
|
args:
|
||||||
- required: false
|
- required: false
|
||||||
type: number
|
type: number
|
||||||
- type: thread | function
|
- type: thread | function
|
||||||
- type: "..."
|
# - type: "..."
|
||||||
task.spawn:
|
task.spawn:
|
||||||
args:
|
args:
|
||||||
- type: thread | function
|
- type: thread | function
|
||||||
- type: "..."
|
# - type: "..."
|
||||||
task.wait:
|
task.wait:
|
||||||
args:
|
args:
|
||||||
- required: false
|
- required: false
|
||||||
|
|
|
@ -52,6 +52,15 @@ declare process: {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare task: {
|
||||||
|
cancel: (t: thread) -> (),
|
||||||
|
defer: (f: thread | (...any) -> (...any)) -> thread,
|
||||||
|
delay: (duration: number?, f: thread | (...any) -> (...any)) -> thread,
|
||||||
|
spawn: (f: thread | (...any) -> (...any)) -> thread,
|
||||||
|
wait: (duration: number?) -> (number),
|
||||||
|
}
|
||||||
|
|
||||||
|
--[[
|
||||||
declare task: {
|
declare task: {
|
||||||
cancel: (t: thread) -> (),
|
cancel: (t: thread) -> (),
|
||||||
defer: <T...>(f: thread | (T...) -> (...any), T...) -> thread,
|
defer: <T...>(f: thread | (T...) -> (...any), T...) -> thread,
|
||||||
|
@ -59,3 +68,4 @@ declare task: {
|
||||||
spawn: <T...>(f: thread | (T...) -> (...any), T...) -> thread,
|
spawn: <T...>(f: thread | (T...) -> (...any), T...) -> thread,
|
||||||
wait: (duration: number?) -> (number),
|
wait: (duration: number?) -> (number),
|
||||||
}
|
}
|
||||||
|
]]
|
||||||
|
|
|
@ -2,7 +2,7 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
formatting::{flush_stdout, pretty_format_multi_value, print_color, print_label, print_style},
|
formatting::{flush_stdout, pretty_format_multi_value, print_color, print_label, print_style},
|
||||||
table_builder::TableBuilder,
|
table::TableBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<()> {
|
pub fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::path::{PathBuf, MAIN_SEPARATOR};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use smol::{fs, prelude::*};
|
use smol::{fs, prelude::*};
|
||||||
|
|
||||||
use crate::utils::table_builder::TableBuilder;
|
use crate::utils::table::TableBuilder;
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<()> {
|
pub fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::utils::{net::get_request_user_agent_header, table_builder::TableBuilder};
|
use crate::utils::{net::get_request_user_agent_header, table::TableBuilder};
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<()> {
|
pub fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
|
|
|
@ -4,7 +4,7 @@ use mlua::prelude::*;
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
use smol::{channel::Sender, process::Command, LocalExecutor};
|
use smol::{channel::Sender, process::Command, LocalExecutor};
|
||||||
|
|
||||||
use crate::{utils::table_builder::TableBuilder, LuneMessage};
|
use crate::{utils::table::TableBuilder, LuneMessage};
|
||||||
|
|
||||||
pub fn create(lua: &Lua, args_vec: Vec<String>) -> LuaResult<()> {
|
pub fn create(lua: &Lua, args_vec: Vec<String>) -> LuaResult<()> {
|
||||||
// Create readonly args array
|
// Create readonly args array
|
||||||
|
|
|
@ -4,14 +4,16 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use smol::{channel::Sender, LocalExecutor, Timer};
|
use smol::Timer;
|
||||||
use smol::{future::yield_now, prelude::*};
|
|
||||||
|
|
||||||
use crate::{utils::table_builder::TableBuilder, LuneMessage};
|
use crate::utils::{
|
||||||
|
table::TableBuilder,
|
||||||
|
task::{run_registered_task, TaskRunMode},
|
||||||
|
};
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<()> {
|
pub fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
// 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
|
||||||
// create, 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")?;
|
||||||
let close: LuaFunction = coroutine.raw_get("close")?;
|
let close: LuaFunction = coroutine.raw_get("close")?;
|
||||||
lua.set_named_registry_value("coroutine.close", close)?;
|
lua.set_named_registry_value("coroutine.close", close)?;
|
||||||
|
@ -43,51 +45,6 @@ fn tof_to_thread<'a>(lua: &'a Lua, tof: LuaValue<'a>) -> LuaResult<LuaThread<'a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_registered_task(
|
|
||||||
lua: &Lua,
|
|
||||||
to_run: impl Future<Output = LuaResult<()>> + 'static,
|
|
||||||
run_in_background: bool,
|
|
||||||
) -> LuaResult<()> {
|
|
||||||
// Fetch global references to task executor & message sender
|
|
||||||
let exec = lua
|
|
||||||
.app_data_ref::<Weak<LocalExecutor>>()
|
|
||||||
.unwrap()
|
|
||||||
.upgrade()
|
|
||||||
.unwrap();
|
|
||||||
let sender = lua
|
|
||||||
.app_data_ref::<Weak<Sender<LuneMessage>>>()
|
|
||||||
.unwrap()
|
|
||||||
.upgrade()
|
|
||||||
.unwrap();
|
|
||||||
// Send a message that we have started our task
|
|
||||||
sender
|
|
||||||
.send(LuneMessage::Spawned)
|
|
||||||
.await
|
|
||||||
.map_err(LuaError::external)?;
|
|
||||||
// Run the new task separately from the current one using the executor
|
|
||||||
let sender = sender.clone();
|
|
||||||
let task = exec.spawn(async move {
|
|
||||||
sender
|
|
||||||
.send(match to_run.await {
|
|
||||||
Ok(_) => LuneMessage::Finished,
|
|
||||||
Err(e) => LuneMessage::LuaError(e),
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
});
|
|
||||||
// Wait for the task to complete OR let it run in the background
|
|
||||||
// Any lua errors will be sent through the message channel back
|
|
||||||
// to the main thread which will then handle them properly
|
|
||||||
if run_in_background {
|
|
||||||
task.detach();
|
|
||||||
} else {
|
|
||||||
task.await.map_err(LuaError::external)?;
|
|
||||||
}
|
|
||||||
// Yield once right away to let the above spawned task start working
|
|
||||||
// instantly, forcing it to run until completion or until it yields
|
|
||||||
yield_now().await;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn task_cancel<'a>(lua: &'a Lua, thread: LuaThread<'a>) -> LuaResult<()> {
|
async fn task_cancel<'a>(lua: &'a 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?;
|
||||||
|
@ -100,18 +57,13 @@ async fn task_defer<'a>(lua: &'a Lua, tof: LuaValue<'a>) -> LuaResult<LuaThread<
|
||||||
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 lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
||||||
run_registered_task(
|
run_registered_task(lua, TaskRunMode::Deferred, async move {
|
||||||
lua,
|
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?;
|
||||||
async move {
|
if thread.status() == LuaThreadStatus::Resumable {
|
||||||
task_wait(&task_lua, None).await?;
|
thread.into_async::<_, LuaMultiValue>(()).await?;
|
||||||
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?;
|
}
|
||||||
if thread.status() == LuaThreadStatus::Resumable {
|
Ok(())
|
||||||
thread.into_async::<_, LuaMultiValue>(()).await?;
|
})
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
Ok(lua_thread_to_return)
|
Ok(lua_thread_to_return)
|
||||||
}
|
}
|
||||||
|
@ -125,18 +77,14 @@ async fn task_delay<'a>(
|
||||||
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 lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
||||||
run_registered_task(
|
run_registered_task(lua, TaskRunMode::Deferred, async move {
|
||||||
lua,
|
task_wait(&task_lua, duration).await?;
|
||||||
async move {
|
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?;
|
||||||
task_wait(&task_lua, duration).await?;
|
if thread.status() == LuaThreadStatus::Resumable {
|
||||||
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?;
|
thread.into_async::<_, LuaMultiValue>(()).await?;
|
||||||
if thread.status() == LuaThreadStatus::Resumable {
|
}
|
||||||
thread.into_async::<_, LuaMultiValue>(()).await?;
|
Ok(())
|
||||||
}
|
})
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
Ok(lua_thread_to_return)
|
Ok(lua_thread_to_return)
|
||||||
}
|
}
|
||||||
|
@ -147,36 +95,28 @@ async fn task_spawn<'a>(lua: &'a Lua, tof: LuaValue<'a>) -> LuaResult<LuaThread<
|
||||||
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 lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
let lua_thread_to_return = lua.registry_value(&task_thread_key)?;
|
||||||
run_registered_task(
|
run_registered_task(lua, TaskRunMode::Instant, async move {
|
||||||
lua,
|
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?;
|
||||||
async move {
|
if thread.status() == LuaThreadStatus::Resumable {
|
||||||
let thread = task_lua.registry_value::<LuaThread>(&task_thread_key)?;
|
thread.into_async::<_, LuaMultiValue>(()).await?;
|
||||||
if thread.status() == LuaThreadStatus::Resumable {
|
}
|
||||||
thread.into_async::<_, LuaMultiValue>(()).await?;
|
Ok(())
|
||||||
}
|
})
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
.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: &Lua, duration: Option<f32>) -> LuaResult<f32> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
run_registered_task(
|
run_registered_task(lua, TaskRunMode::Blocking, async move {
|
||||||
lua,
|
Timer::after(
|
||||||
async move {
|
duration
|
||||||
Timer::after(
|
.map(Duration::from_secs_f32)
|
||||||
duration
|
.unwrap_or(Duration::ZERO),
|
||||||
.map(Duration::from_secs_f32)
|
)
|
||||||
.unwrap_or(Duration::ZERO),
|
.await;
|
||||||
)
|
Ok(())
|
||||||
.await;
|
})
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
let end = Instant::now();
|
let end = Instant::now();
|
||||||
Ok((end - start).as_secs_f32())
|
Ok((end - start).as_secs_f32())
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
pub mod formatting;
|
pub mod formatting;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod table_builder;
|
pub mod table;
|
||||||
|
pub mod task;
|
||||||
|
|
62
src/lib/utils/task.rs
Normal file
62
src/lib/utils/task.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
use std::sync::Weak;
|
||||||
|
|
||||||
|
use mlua::prelude::*;
|
||||||
|
use smol::{channel::Sender, LocalExecutor};
|
||||||
|
use smol::{future::yield_now, prelude::*};
|
||||||
|
|
||||||
|
use crate::LuneMessage;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub enum TaskRunMode {
|
||||||
|
Blocking,
|
||||||
|
Instant,
|
||||||
|
Deferred,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn run_registered_task<T>(
|
||||||
|
lua: &Lua,
|
||||||
|
mode: TaskRunMode,
|
||||||
|
to_run: impl Future<Output = LuaResult<T>> + 'static,
|
||||||
|
) -> LuaResult<()> {
|
||||||
|
// Fetch global references to task executor & message sender
|
||||||
|
let exec = lua
|
||||||
|
.app_data_ref::<Weak<LocalExecutor>>()
|
||||||
|
.unwrap()
|
||||||
|
.upgrade()
|
||||||
|
.unwrap();
|
||||||
|
let sender = lua
|
||||||
|
.app_data_ref::<Weak<Sender<LuneMessage>>>()
|
||||||
|
.unwrap()
|
||||||
|
.upgrade()
|
||||||
|
.unwrap();
|
||||||
|
// Send a message that we have started our task
|
||||||
|
sender
|
||||||
|
.send(LuneMessage::Spawned)
|
||||||
|
.await
|
||||||
|
.map_err(LuaError::external)?;
|
||||||
|
// Run the new task separately from the current one using the executor
|
||||||
|
let sender = sender.clone();
|
||||||
|
let task = exec.spawn(async move {
|
||||||
|
if mode == TaskRunMode::Deferred {
|
||||||
|
yield_now().await;
|
||||||
|
}
|
||||||
|
sender
|
||||||
|
.send(match to_run.await {
|
||||||
|
Ok(_) => LuneMessage::Finished,
|
||||||
|
Err(e) => LuneMessage::LuaError(e),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
});
|
||||||
|
// Wait for the task to complete OR let it run in the background
|
||||||
|
// Any lua errors will be sent through the message channel back
|
||||||
|
// to the main thread which will then handle them properly
|
||||||
|
if mode == TaskRunMode::Blocking {
|
||||||
|
task.await.map_err(LuaError::external)?;
|
||||||
|
} else {
|
||||||
|
task.detach();
|
||||||
|
}
|
||||||
|
// Yield once right away to let the above spawned task start working
|
||||||
|
// instantly, forcing it to run until completion or until it yields
|
||||||
|
yield_now().await;
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in a new issue