From c86190def1a9cf70b6158d65cf24b68d9a7b887c Mon Sep 17 00:00:00 2001 From: David C <86097860+DvvCz@users.noreply.github.com> Date: Mon, 14 Aug 2023 13:43:01 -0700 Subject: [PATCH 1/4] Implement variadic versions of CFrame methods (#85) --- src/roblox/datatypes/types/cframe.rs | 43 +++++++++++++++++++--------- tests/roblox/datatypes/CFrame.luau | 3 ++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index a9b3c5e..3c6a550 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -2,7 +2,7 @@ use core::fmt; use std::ops; use glam::{EulerRot, Mat4, Quat, Vec3}; -use mlua::prelude::*; +use mlua::{prelude::*, Variadic}; use rbx_dom_weak::types::{CFrame as DomCFrame, Matrix3 as DomMatrix3, Vector3 as DomVector3}; use super::{super::*, Vector3}; @@ -210,29 +210,46 @@ impl LuaUserData for CFrame { translation, ))) }); - methods.add_method("ToWorldSpace", |_, this, rhs: LuaUserDataRef| { - Ok(*this * *rhs) - }); - methods.add_method("ToObjectSpace", |_, this, rhs: LuaUserDataRef| { - Ok(this.inverse() * *rhs) - }); + methods.add_method( + "ToWorldSpace", + |_, this, rhs: Variadic>| { + Ok(Variadic::from_iter(rhs.into_iter().map(|cf| *this * *cf))) + }, + ); + methods.add_method( + "ToObjectSpace", + |_, this, rhs: Variadic>| { + let inverse = this.inverse(); + Ok(Variadic::from_iter(rhs.into_iter().map(|cf| inverse * *cf))) + }, + ); methods.add_method( "PointToWorldSpace", - |_, this, rhs: LuaUserDataRef| Ok(*this * *rhs), + |_, this, rhs: Variadic>| { + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| *this * *v3))) + }, ); methods.add_method( "PointToObjectSpace", - |_, this, rhs: LuaUserDataRef| Ok(this.inverse() * *rhs), + |_, this, rhs: Variadic>| { + let inverse = this.inverse(); + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| inverse * *v3))) + }, ); methods.add_method( "VectorToWorldSpace", - |_, this, rhs: LuaUserDataRef| Ok((*this - Vector3(this.position())) * *rhs), + |_, this, rhs: Variadic>| { + let result = *this - Vector3(this.position()); + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3))) + }, ); methods.add_method( "VectorToObjectSpace", - |_, this, rhs: LuaUserDataRef| { - let inv = this.inverse(); - Ok((inv - Vector3(inv.position())) * *rhs) + |_, this, rhs: Variadic>| { + let inverse = this.inverse(); + let result = inverse - Vector3(inverse.position()); + + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3))) }, ); #[rustfmt::skip] diff --git a/tests/roblox/datatypes/CFrame.luau b/tests/roblox/datatypes/CFrame.luau index 6ac32e0..85b40bb 100644 --- a/tests/roblox/datatypes/CFrame.luau +++ b/tests/roblox/datatypes/CFrame.luau @@ -103,6 +103,9 @@ local offset = CFrame.new(0, 0, -5) assert(offset:ToWorldSpace(offset).Z == offset.Z * 2) assert(offset:ToObjectSpace(offset).Z == 0) +assert(select("#", offset:ToWorldSpace(offset, offset, offset)) == 3) +assert(select("#", offset:ToObjectSpace(offset, offset, offset)) == 3) + local world = CFrame.fromOrientation(0, math.rad(90), 0) * CFrame.new(0, 0, -5) local world2 = CFrame.fromOrientation(0, -math.rad(90), 0) * CFrame.new(0, 0, -5) assertEq(CFrame.identity:ToObjectSpace(world), world) From 72adb2172f6800c22237708ad21d5f5d1a81002f Mon Sep 17 00:00:00 2001 From: David C <86097860+DvvCz@users.noreply.github.com> Date: Mon, 14 Aug 2023 13:52:53 -0700 Subject: [PATCH 2/4] Pass arguments to coroutine in `coroutine.resume` (#86) --- src/lune/builtins/task.rs | 6 +++--- tests/globals/coroutine.luau | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/lune/builtins/task.rs b/src/lune/builtins/task.rs index b29b502..98a0383 100644 --- a/src/lune/builtins/task.rs +++ b/src/lune/builtins/task.rs @@ -117,7 +117,7 @@ fn coroutine_status<'a>( fn coroutine_resume<'lua>( lua: &'lua Lua, - value: LuaThreadOrTaskReference, + (value, arguments): (LuaThreadOrTaskReference, LuaMultiValue<'lua>), ) -> LuaResult<(bool, LuaMultiValue<'lua>)> { let sched = lua.app_data_ref::<&TaskScheduler>().unwrap(); if sched.current_task().is_none() { @@ -128,10 +128,10 @@ fn coroutine_resume<'lua>( let current = sched.current_task().unwrap(); let result = match value { LuaThreadOrTaskReference::Thread(t) => { - let task = sched.create_task(TaskKind::Instant, t, None, true)?; + let task = sched.create_task(TaskKind::Instant, t, Some(arguments), true)?; sched.resume_task(task, None) } - LuaThreadOrTaskReference::TaskReference(t) => sched.resume_task(t, None), + LuaThreadOrTaskReference::TaskReference(t) => sched.resume_task(t, Some(Ok(arguments))), }; sched.force_set_current_task(Some(current)); match result { diff --git a/tests/globals/coroutine.luau b/tests/globals/coroutine.luau index 5780b78..8db0c42 100644 --- a/tests/globals/coroutine.luau +++ b/tests/globals/coroutine.luau @@ -74,3 +74,13 @@ end)() assert(not flag2, "Wait failed while inside wrap (1)") task.wait(0.2) assert(flag2, "Wait failed while inside wrap (2)") + +-- Coroutines should be passed arguments on initial resume + +local co = coroutine.create(function(a, b, c) + assert(a == 1) + assert(b == "Hello, world!") + assert(c == true) +end) + +coroutine.resume(co, 1, "Hello, world!", true) From d87d3f6cee8e635991c66125f1a32bc30e110a94 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Mon, 14 Aug 2023 16:03:39 -0500 Subject: [PATCH 3/4] Update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e816252..72dfb93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 callableFn2() ``` +- Implemented support for a variable number of arguments for `CFrame` methods in the `roblox` built-in library. ([#85]) + +### Fixed + +- Fixed not being able to pass arguments to the thread using `coroutine.resume`. ([#86]) + [#82]: https://github.com/filiptibell/lune/pull/82 +[#85]: https://github.com/filiptibell/lune/pull/85 +[#86]: https://github.com/filiptibell/lune/pull/86 ## `0.7.6` - August 9th, 2023 From 74a41c1bf12f6be62ad94b0322b702e6699e3a75 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Mon, 14 Aug 2023 16:32:06 -0500 Subject: [PATCH 4/4] Clean up LuneError type for consumers --- src/lune/error.rs | 73 +++++++++++++++++++++++++++++++++++------------ src/lune/mod.rs | 4 +-- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/lune/error.rs b/src/lune/error.rs index 5369e21..c4d9f8c 100644 --- a/src/lune/error.rs +++ b/src/lune/error.rs @@ -12,35 +12,72 @@ use crate::lune::lua::stdio::formatting::pretty_format_luau_error; */ #[derive(Debug, Clone)] pub struct LuneError { - message: String, - incomplete_input: bool, + error: LuaError, + disable_colors: bool, } impl LuneError { - pub(crate) fn from_lua_error(error: LuaError, disable_colors: bool) -> Self { - Self { - message: pretty_format_luau_error(&error, !disable_colors), - incomplete_input: matches!( - error, - LuaError::SyntaxError { - incomplete_input: true, - .. - } - ), - } + /** + Enables colorization of the error message when formatted using the [`Display`] trait. + + Colorization is enabled by default. + */ + #[doc(hidden)] + pub fn enable_colors(mut self) -> Self { + self.disable_colors = false; + self + } + + /** + Disables colorization of the error message when formatted using the [`Display`] trait. + + Colorization is enabled by default. + */ + #[doc(hidden)] + pub fn disable_colors(mut self) -> Self { + self.disable_colors = true; + self + } + + /** + Returns `true` if the error can likely be fixed by appending more input to the source code. + + See [`mlua::Error::SyntaxError`] for more information. + */ + pub fn is_incomplete_input(&self) -> bool { + matches!( + self.error, + LuaError::SyntaxError { + incomplete_input: true, + .. + } + ) } } -impl LuneError { - pub fn is_incomplete_input(&self) -> bool { - self.incomplete_input +impl From for LuneError { + fn from(value: LuaError) -> Self { + Self { + error: value, + disable_colors: false, + } } } impl Display for LuneError { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "{}", self.message) + write!( + f, + "{}", + pretty_format_luau_error(&self.error, !self.disable_colors) + ) } } -impl Error for LuneError {} +impl Error for LuneError { + // TODO: Comment this out when we are ready to also re-export + // `mlua` as part of our public library interface in Lune + // fn cause(&self) -> Option<&dyn Error> { + // Some(&self.error) + // } +} diff --git a/src/lune/mod.rs b/src/lune/mod.rs index f4f49c8..098b7ad 100644 --- a/src/lune/mod.rs +++ b/src/lune/mod.rs @@ -56,7 +56,7 @@ impl Lune { ) -> Result { self.run_inner(script_name, script_contents) .await - .map_err(|err| LuneError::from_lua_error(err, false)) + .map_err(LuneError::from) } async fn run_inner( @@ -87,7 +87,7 @@ impl Lune { loop { let result = sched.resume_queue().await; if let Some(err) = result.get_lua_error() { - eprintln!("{}", LuneError::from_lua_error(err, false)); + eprintln!("{}", LuneError::from(err)); got_error = true; } if result.is_done() {