From ea834635c1b994e10abd020ffc18c03fa7cfbda0 Mon Sep 17 00:00:00 2001 From: kyren Date: Sun, 11 Feb 2018 17:53:25 -0500 Subject: [PATCH] Add `UserDataMethods::` `add_function_mut` and `add_meta_function_mut` --- src/userdata.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/userdata.rs b/src/userdata.rs index e10f251..7929de5 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -127,6 +127,22 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> { .insert(name.to_owned(), Self::box_function(function)); } + /// Add a regular method as a mutable function which accepts generic arguments, the first + /// argument will always be a `UserData` of type T. + /// + /// This is a version of [`add_function`] that accepts a FnMut argument. + /// + /// [`add_function`]: #method.add_function + pub fn add_function_mut(&mut self, name: &str, function: F) + where + A: FromLuaMulti<'lua>, + R: ToLuaMulti<'lua>, + F: 'static + Send + FnMut(&'lua Lua, A) -> Result, + { + self.methods + .insert(name.to_owned(), Self::box_function_mut(function)); + } + /// Add a metamethod which accepts a `&T` as the first parameter. /// /// # Note @@ -175,6 +191,21 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> { self.meta_methods.insert(meta, Self::box_function(function)); } + /// Add a metamethod as a mutable function which accepts generic arguments. + /// + /// This is a version of [`add_meta_function`] that accepts a FnMut argument. + /// + /// [`add_meta_function`]: #method.add_meta_function + pub fn add_meta_function_mut(&mut self, meta: MetaMethod, function: F) + where + A: FromLuaMulti<'lua>, + R: ToLuaMulti<'lua>, + F: 'static + Send + FnMut(&'lua Lua, A) -> Result, + { + self.meta_methods + .insert(meta, Self::box_function_mut(function)); + } + fn box_function(function: F) -> Callback<'lua, 'static> where A: FromLuaMulti<'lua>, @@ -184,6 +215,21 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> { Box::new(move |lua, args| function(lua, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua)) } + fn box_function_mut(function: F) -> Callback<'lua, 'static> + where + A: FromLuaMulti<'lua>, + R: ToLuaMulti<'lua>, + F: 'static + Send + FnMut(&'lua Lua, A) -> Result, + { + let function = RefCell::new(function); + Box::new(move |lua, args| { + let function = &mut *function + .try_borrow_mut() + .map_err(|_| Error::RecursiveMutCallback)?; + function(lua, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) + }) + } + fn box_method(method: M) -> Callback<'lua, 'static> where A: FromLuaMulti<'lua>,