diff --git a/src/runner/instance.rs b/src/runner/instance.rs index ffc29ff..00c277c 100644 --- a/src/runner/instance.rs +++ b/src/runner/instance.rs @@ -9,6 +9,7 @@ use super::vector3::Vector3; pub fn set_globals(lua:&mlua::Lua,globals:&mlua::Table)->Result<(),mlua::Error>{ //class functions store lua.set_app_data(ClassMethodsStore::default()); + lua.set_app_data(InstanceValueStore::default()); let instance_table=lua.create_table()?; @@ -30,14 +31,10 @@ pub fn set_globals(lua:&mlua::Lua,globals:&mlua::Table)->Result<(),mlua::Error>{ } // LMAO look at this function! -fn dom_mut(lua:&mlua::Lua,mut f:impl FnMut(&mut WeakDom)->mlua::Result)->mlua::Result{ +pub fn dom_mut(lua:&mlua::Lua,mut f:impl FnMut(&mut WeakDom)->mlua::Result)->mlua::Result{ let mut dom=lua.app_data_mut::<&'static mut WeakDom>().ok_or(mlua::Error::runtime("DataModel missing"))?; f(&mut *dom) } -fn class_functions_mut(lua:&mlua::Lua,mut f:impl FnMut(&mut ClassMethodsStore)->mlua::Result)->mlua::Result{ - let mut cf=lua.app_data_mut::().ok_or(mlua::Error::runtime("ClassFunctions missing"))?; - f(&mut *cf) -} fn coerce_float32(value:&mlua::Value)->Option{ match value{ @@ -262,7 +259,7 @@ impl mlua::UserData for Instance{ other=>return Err(mlua::Error::runtime(format!("Instance.__index Unsupported property type instance={} index={index_str} value={other:?}",instance.name))), } //find a function with a matching name - if let Some(function)=class_functions_mut(lua,|cf|{ + if let Some(function)=class_methods_store_mut(lua,|cf|{ let mut iter=SuperClassIter{ database:db, descriptor:Some(class), @@ -275,6 +272,17 @@ impl mlua::UserData for Instance{ })?{ return function.into_lua(lua); } + //find or create an associated userdata object + + if let Some(value)=instance_value_store_mut(lua,|ivs|{ + //TODO: walk class tree somehow + match ivs.get_or_create_instance_values(&instance){ + Some(mut instance_values)=>instance_values.get_or_create_value(lua,index_str), + None=>Ok(None) + } + })?{ + return value.into_lua(lua); + } //find a child with a matching name find_first_child(dom,instance,index_str) .map(|instance|Instance::new(instance.referent())) @@ -434,6 +442,10 @@ impl ClassMethods<'_>{ }) } } +fn class_methods_store_mut(lua:&mlua::Lua,mut f:impl FnMut(&mut ClassMethodsStore)->mlua::Result)->mlua::Result{ + let mut cf=lua.app_data_mut::().ok_or(mlua::Error::runtime("ClassMethodsStore missing"))?; + f(&mut *cf) +} /// A virtual property pointer definition shorthand. type VirtualPropertyFunctionPointer=fn(&rbx_types::Variant)->Option; @@ -499,19 +511,20 @@ static LAZY_USER_DATA:LUD=phf::phf_map!{ }, }, }; -struct InstanceValueStore{ +#[derive(Default)] +pub struct InstanceValueStore{ values:HashMap >, } -struct InstanceValues<'a>{ +pub struct InstanceValues<'a>{ named_values:&'static phf::Map<&'static str,CreateUserData>, values:&'a mut HashMap<&'static str,mlua::AnyUserData>, } impl InstanceValueStore{ - fn get_or_create_instance_values(&mut self,instance:&rbx_dom_weak::Instance)->Option{ + pub fn get_or_create_instance_values(&mut self,instance:&rbx_dom_weak::Instance)->Option{ LAZY_USER_DATA.get(instance.class.as_str()) .map(|named_values| InstanceValues{ @@ -523,7 +536,7 @@ impl InstanceValueStore{ } } impl InstanceValues<'_>{ - fn get_or_create_value(&mut self,lua:&mlua::Lua,index:&str)->mlua::Result>{ + pub fn get_or_create_value(&mut self,lua:&mlua::Lua,index:&str)->mlua::Result>{ Ok(match self.named_values.get_entry(index){ Some((&static_index_str,&function_pointer))=>Some( match self.values.entry(static_index_str){ @@ -537,3 +550,8 @@ impl InstanceValues<'_>{ }) } } + +pub fn instance_value_store_mut(lua:&mlua::Lua,mut f:impl FnMut(&mut InstanceValueStore)->mlua::Result)->mlua::Result{ + let mut cf=lua.app_data_mut::().ok_or(mlua::Error::runtime("InstanceValueStore missing"))?; + f(&mut *cf) +} diff --git a/src/runner/runner.rs b/src/runner/runner.rs index 39fa25a..15d066f 100644 --- a/src/runner/runner.rs +++ b/src/runner/runner.rs @@ -120,4 +120,23 @@ impl Runnable<'_>{ } Ok(()) } + #[cfg(feature="run-service")] + pub fn run_service_step(&self)->Result<(),mlua::Error>{ + let render_stepped=super::instance::dom_mut(&self.lua,|dom|{ + let run_service=super::instance::find_first_child_of_class(dom,dom.root(),"RunService").ok_or_else(||mlua::Error::runtime("RunService missing"))?; + super::instance::instance_value_store_mut(&self.lua,|instance_value_store|{ + //unwrap because I trust my find_first_child_of_class function to + let mut instance_values=instance_value_store.get_or_create_instance_values(run_service).unwrap(); + let render_stepped=instance_values.get_or_create_value(&self.lua,"RenderStepped")?; + //let stepped=instance_values.get_or_create_value(&self.lua,"Stepped")?; + //let heartbeat=instance_values.get_or_create_value(&self.lua,"Heartbeat")?; + Ok(render_stepped) + }) + })?; + if let Some(render_stepped)=render_stepped{ + let signal:&super::script_signal::ScriptSignal=&*render_stepped.borrow()?; + signal.fire(mlua::MultiValue::new()); + } + Ok(()) + } } diff --git a/src/runner/script_signal.rs b/src/runner/script_signal.rs index f436046..992ab95 100644 --- a/src/runner/script_signal.rs +++ b/src/runner/script_signal.rs @@ -53,7 +53,14 @@ impl mlua::UserData for ScriptSignal{ // ); } } -//type_from_lua_userdata!(ScriptSignal); +impl mlua::FromLua for ScriptSignal{ + fn from_lua(value:mlua::Value,_lua:&mlua::Lua)->Result{ + match value{ + mlua::Value::UserData(ud)=>Ok(ud.borrow::()?.clone()), + other=>Err(mlua::Error::runtime(format!("Expected {} got {:?}",stringify!(ScriptSignal),other))), + } + } +} impl mlua::UserData for ScriptConnection{ fn add_fields>(fields:&mut F){