mirror of
https://github.com/lune-org/mlua-luau-scheduler.git
synced 2025-04-10 21:40:55 +01:00
lua -> Lua
This commit is contained in:
parent
053b85e0c1
commit
577fa2e272
7 changed files with 22 additions and 28 deletions
|
@ -33,7 +33,7 @@ use mlua::prelude::*;
|
||||||
use mlua_luau_runtime::*;
|
use mlua_luau_runtime::*;
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Set up lua environment
|
### 2. Set up Lua environment
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
let lua = Lua::new();
|
let lua = Lua::new();
|
||||||
|
|
|
@ -8,7 +8,7 @@ use mlua_luau_runtime::*;
|
||||||
const MAIN_SCRIPT: &str = include_str!("./lua/basic_sleep.luau");
|
const MAIN_SCRIPT: &str = include_str!("./lua/basic_sleep.luau");
|
||||||
|
|
||||||
pub fn main() -> LuaResult<()> {
|
pub fn main() -> LuaResult<()> {
|
||||||
// Set up persistent lua environment
|
// Set up persistent Lua environment
|
||||||
let lua = Lua::new();
|
let lua = Lua::new();
|
||||||
lua.globals().set(
|
lua.globals().set(
|
||||||
"sleep",
|
"sleep",
|
||||||
|
|
|
@ -9,12 +9,12 @@ use mlua_luau_runtime::*;
|
||||||
const MAIN_SCRIPT: &str = include_str!("./lua/basic_spawn.luau");
|
const MAIN_SCRIPT: &str = include_str!("./lua/basic_spawn.luau");
|
||||||
|
|
||||||
pub fn main() -> LuaResult<()> {
|
pub fn main() -> LuaResult<()> {
|
||||||
// Set up persistent lua environment
|
// Set up persistent Lua environment
|
||||||
let lua = Lua::new();
|
let lua = Lua::new();
|
||||||
lua.globals().set(
|
lua.globals().set(
|
||||||
"readFile",
|
"readFile",
|
||||||
lua.create_async_function(|lua, path: String| async move {
|
lua.create_async_function(|lua, path: String| async move {
|
||||||
// Spawn background task that does not take up resources on the lua thread
|
// Spawn background task that does not take up resources on the Lua thread
|
||||||
let task = lua.spawn(async move {
|
let task = lua.spawn(async move {
|
||||||
match read_to_string(path).await {
|
match read_to_string(path).await {
|
||||||
Ok(s) => Ok(Some(s)),
|
Ok(s) => Ok(Some(s)),
|
||||||
|
|
|
@ -6,7 +6,7 @@ use async_io::block_on;
|
||||||
const MAIN_SCRIPT: &str = include_str!("./lua/callbacks.luau");
|
const MAIN_SCRIPT: &str = include_str!("./lua/callbacks.luau");
|
||||||
|
|
||||||
pub fn main() -> LuaResult<()> {
|
pub fn main() -> LuaResult<()> {
|
||||||
// Set up persistent lua environment
|
// Set up persistent Lua environment
|
||||||
let lua = Lua::new();
|
let lua = Lua::new();
|
||||||
|
|
||||||
// Create a new runtime with custom callbacks
|
// Create a new runtime with custom callbacks
|
||||||
|
|
|
@ -10,14 +10,8 @@ const MAIN_SCRIPT: &str = include_str!("./lua/lots_of_threads.luau");
|
||||||
const ONE_NANOSECOND: Duration = Duration::from_nanos(1);
|
const ONE_NANOSECOND: Duration = Duration::from_nanos(1);
|
||||||
|
|
||||||
pub fn main() -> LuaResult<()> {
|
pub fn main() -> LuaResult<()> {
|
||||||
// Set up persistent lua environment, note that we enable thread reuse for
|
// Set up persistent Lua environment
|
||||||
// mlua's internal async handling since we will be spawning lots of threads
|
let lua = Lua::new();
|
||||||
let lua = Lua::new_with(
|
|
||||||
LuaStdLib::ALL,
|
|
||||||
LuaOptions::new()
|
|
||||||
.catch_rust_panics(false)
|
|
||||||
.thread_pool_size(10_000),
|
|
||||||
)?;
|
|
||||||
let rt = Runtime::new(&lua)?;
|
let rt = Runtime::new(&lua)?;
|
||||||
|
|
||||||
lua.globals().set("spawn", rt.create_spawn_function()?)?;
|
lua.globals().set("spawn", rt.create_spawn_function()?)?;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use mlua_luau_runtime::*;
|
||||||
const MAIN_SCRIPT: &str = include_str!("./lua/scheduler_ordering.luau");
|
const MAIN_SCRIPT: &str = include_str!("./lua/scheduler_ordering.luau");
|
||||||
|
|
||||||
pub fn main() -> LuaResult<()> {
|
pub fn main() -> LuaResult<()> {
|
||||||
// Set up persistent lua environment
|
// Set up persistent Lua environment
|
||||||
let lua = Lua::new();
|
let lua = Lua::new();
|
||||||
let rt = Runtime::new(&lua)?;
|
let rt = Runtime::new(&lua)?;
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ impl<'lua> Runtime<'lua> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a lua function that can be used to spawn threads / functions onto the runtime queue.
|
Creates a Lua function that can be used to spawn threads / functions onto the runtime queue.
|
||||||
|
|
||||||
The function takes a thread or function as the first argument, and any variadic arguments as the rest.
|
The function takes a thread or function as the first argument, and any variadic arguments as the rest.
|
||||||
*/
|
*/
|
||||||
|
@ -118,7 +118,7 @@ impl<'lua> Runtime<'lua> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a lua function that can be used to defer threads / functions onto the runtime queue.
|
Creates a Lua function that can be used to defer threads / functions onto the runtime queue.
|
||||||
|
|
||||||
The function takes a thread or function as the first argument, and any variadic arguments as the rest.
|
The function takes a thread or function as the first argument, and any variadic arguments as the rest.
|
||||||
|
|
||||||
|
@ -147,22 +147,22 @@ impl<'lua> Runtime<'lua> {
|
||||||
/*
|
/*
|
||||||
Create new executors to use - note that we do not need create multiple executors
|
Create new executors to use - note that we do not need create multiple executors
|
||||||
for work stealing, the user may do that themselves if they want to and it will work
|
for work stealing, the user may do that themselves if they want to and it will work
|
||||||
just fine, as long as anything async is .await-ed from within a lua async function.
|
just fine, as long as anything async is .await-ed from within a Lua async function.
|
||||||
|
|
||||||
The main purpose of the two executors here is just to have one with
|
The main purpose of the two executors here is just to have one with
|
||||||
the Send bound, and another (local) one without it, for lua scheduling.
|
the Send bound, and another (local) one without it, for Lua scheduling.
|
||||||
|
|
||||||
We also use the main executor to drive the main loop below forward,
|
We also use the main executor to drive the main loop below forward,
|
||||||
saving a tiny bit of processing from going on the lua executor itself.
|
saving a tiny bit of processing from going on the Lua executor itself.
|
||||||
*/
|
*/
|
||||||
let lua_exec = LocalExecutor::new();
|
let lua_exec = LocalExecutor::new();
|
||||||
let main_exec = Arc::new(Executor::new());
|
let main_exec = Arc::new(Executor::new());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Store the main executor in lua, so that it may be used with LuaSpawnExt.
|
Store the main executor in Lua, so that it may be used with LuaSpawnExt.
|
||||||
|
|
||||||
Also ensure we do not already have an executor - this is a definite user error
|
Also ensure we do not already have an executor - this is a definite user error
|
||||||
and may happen if the user tries to run multiple runtimes on the same lua state.
|
and may happen if the user tries to run multiple runtimes on the same Lua state.
|
||||||
*/
|
*/
|
||||||
if self.lua.app_data_ref::<Weak<Executor>>().is_some() {
|
if self.lua.app_data_ref::<Weak<Executor>>().is_some() {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -174,15 +174,15 @@ impl<'lua> Runtime<'lua> {
|
||||||
self.lua.set_app_data(Arc::downgrade(&main_exec));
|
self.lua.set_app_data(Arc::downgrade(&main_exec));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Manually tick the lua executor, while running under the main executor.
|
Manually tick the Lua executor, while running under the main executor.
|
||||||
Each tick we wait for the next action to perform, in prioritized order:
|
Each tick we wait for the next action to perform, in prioritized order:
|
||||||
|
|
||||||
1. A lua thread is available to run on the spawned queue
|
1. A Lua thread is available to run on the spawned queue
|
||||||
2. A lua thread is available to run on the deferred queue
|
2. A Lua thread is available to run on the deferred queue
|
||||||
3. Task(s) scheduled on the lua executor have made progress and should be polled again
|
3. Task(s) scheduled on the Lua executor have made progress and should be polled again
|
||||||
|
|
||||||
This ordering is vital to ensure that we don't accidentally exit the main loop
|
This ordering is vital to ensure that we don't accidentally exit the main loop
|
||||||
when there are new lua threads to enqueue and potentially more work to be done.
|
when there are new Lua threads to enqueue and potentially more work to be done.
|
||||||
*/
|
*/
|
||||||
let fut = async {
|
let fut = async {
|
||||||
loop {
|
loop {
|
||||||
|
@ -193,7 +193,7 @@ impl<'lua> Runtime<'lua> {
|
||||||
fut_spawn.or(fut_defer).or(fut_tick).await;
|
fut_spawn.or(fut_defer).or(fut_tick).await;
|
||||||
|
|
||||||
let process_thread = |thread: LuaThread<'lua>, args| {
|
let process_thread = |thread: LuaThread<'lua>, args| {
|
||||||
// NOTE: Thread may have been cancelled from lua
|
// NOTE: Thread may have been cancelled from Lua
|
||||||
// before we got here, so we need to check it again
|
// before we got here, so we need to check it again
|
||||||
if thread.status() == LuaThreadStatus::Resumable {
|
if thread.status() == LuaThreadStatus::Resumable {
|
||||||
let mut stream = thread.clone().into_async::<_, LuaValue>(args);
|
let mut stream = thread.clone().into_async::<_, LuaValue>(args);
|
||||||
|
@ -219,7 +219,7 @@ impl<'lua> Runtime<'lua> {
|
||||||
process_thread(thread, args);
|
process_thread(thread, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty executor = we didn't spawn any new lua tasks
|
// Empty executor = we didn't spawn any new Lua tasks
|
||||||
// above, and there are no remaining tasks to run later
|
// above, and there are no remaining tasks to run later
|
||||||
if lua_exec.is_empty() {
|
if lua_exec.is_empty() {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue