goofy ahh once cell function storage code

This commit is contained in:
Quaternions 2024-10-18 21:24:01 -07:00
parent 22d6087b3c
commit 61b9aaba84
2 changed files with 41 additions and 5 deletions

View File

@ -137,7 +137,7 @@ impl Runnable<'_>{
})?; })?;
if let Some(render_stepped)=render_stepped{ if let Some(render_stepped)=render_stepped{
let signal:&super::script_signal::ScriptSignal=&*render_stepped.borrow()?; let signal:&super::script_signal::ScriptSignal=&*render_stepped.borrow()?;
signal.fire(mlua::MultiValue::new()); signal.fire(&mlua::MultiValue::new());
} }
Ok(()) Ok(())
} }

View File

@ -44,6 +44,7 @@ pub struct ScriptSignal{
callbacks:RcFunctionList, callbacks:RcFunctionList,
once:RcFunctionList, once:RcFunctionList,
wait:Rc<RefCell<Vec<mlua::Thread>>>, wait:Rc<RefCell<Vec<mlua::Thread>>>,
wait_function:std::cell::OnceCell<mlua::Function>,
} }
pub struct ScriptConnection{ pub struct ScriptConnection{
connection:RcFunctionList, connection:RcFunctionList,
@ -55,6 +56,7 @@ impl ScriptSignal{
callbacks:RcFunctionList::new(), callbacks:RcFunctionList::new(),
once:RcFunctionList::new(), once:RcFunctionList::new(),
wait:Rc::new(RefCell::new(Vec::new())), wait:Rc::new(RefCell::new(Vec::new())),
wait_function:std::cell::OnceCell::new(),
} }
} }
pub fn fire(&self,args:&mlua::MultiValue){ pub fn fire(&self,args:&mlua::MultiValue){
@ -94,7 +96,45 @@ impl ScriptConnection{
} }
} }
fn wait_thread(lua:&mlua::Lua,this:ScriptSignal)->Result<(),mlua::Error>{
Ok(this.wait(lua.current_thread()))
}
// This is used to avoid calling coroutine.yield from the rust side.
const LUA_WAIT:&str=
"local coroutine_yield=coroutine.yield
local wait_thread=wait_thread
return function()
wait_thread()
return coroutine_yield()
end";
impl mlua::UserData for ScriptSignal{ impl mlua::UserData for ScriptSignal{
fn add_fields<F:mlua::UserDataFields<Self>>(fields:&mut F){
fields.add_field_method_get("Wait",|lua,this|{
Ok(match this.wait_function.get(){
Some(f)=>f.clone(),
None=>{
let coroutine_table=lua.globals().get::<mlua::Table>("coroutine")?;
let wait_thread=lua.create_function(wait_thread)?;
//create wait function environment
let wait_env=lua.create_table()?;
wait_env.raw_set("coroutine",coroutine_table)?;
wait_env.raw_set("wait_thread",wait_thread)?;
//construct wait function from Lua code
let wait=lua.load(LUA_WAIT)
.set_name("wait")
.set_environment(wait_env)
.call::<mlua::Function>(())?;
this.wait_function.set(wait.clone()).unwrap();
wait
}
})
});
}
fn add_methods<M:mlua::UserDataMethods<Self>>(methods:&mut M){ fn add_methods<M:mlua::UserDataMethods<Self>>(methods:&mut M){
methods.add_method("Connect",|_lua,this,f:mlua::Function| methods.add_method("Connect",|_lua,this,f:mlua::Function|
Ok(this.connect(f)) Ok(this.connect(f))
@ -102,10 +142,6 @@ impl mlua::UserData for ScriptSignal{
methods.add_method("Once",|_lua,this,f:mlua::Function| methods.add_method("Once",|_lua,this,f:mlua::Function|
Ok(this.once(f)) Ok(this.once(f))
); );
methods.add_method("Wait",|lua,this,()|
Ok(this.wait(lua.current_thread()))
todo!("coroutine.yield");
);
// Fire is not allowed to be called from Lua // Fire is not allowed to be called from Lua
// methods.add_method("Fire",|_lua,this,args:mlua::MultiValue| // methods.add_method("Fire",|_lua,this,args:mlua::MultiValue|
// Ok(this.fire(args)) // Ok(this.fire(args))