Merge branch 'main' into feature/repl

This commit is contained in:
Erica Marigold 2023-08-15 11:34:07 +05:30 committed by GitHub
commit 5d16f4cef6
Signed by: DevComp
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 111 additions and 36 deletions

View file

@ -31,7 +31,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
callableFn2() 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 [#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 ## `0.7.6` - August 9th, 2023

View file

@ -117,7 +117,7 @@ fn coroutine_status<'a>(
fn coroutine_resume<'lua>( fn coroutine_resume<'lua>(
lua: &'lua Lua, lua: &'lua Lua,
value: LuaThreadOrTaskReference, (value, arguments): (LuaThreadOrTaskReference, LuaMultiValue<'lua>),
) -> LuaResult<(bool, LuaMultiValue<'lua>)> { ) -> LuaResult<(bool, LuaMultiValue<'lua>)> {
let sched = lua.app_data_ref::<&TaskScheduler>().unwrap(); let sched = lua.app_data_ref::<&TaskScheduler>().unwrap();
if sched.current_task().is_none() { if sched.current_task().is_none() {
@ -128,10 +128,10 @@ fn coroutine_resume<'lua>(
let current = sched.current_task().unwrap(); let current = sched.current_task().unwrap();
let result = match value { let result = match value {
LuaThreadOrTaskReference::Thread(t) => { 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) 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)); sched.force_set_current_task(Some(current));
match result { match result {

View file

@ -12,35 +12,72 @@ use crate::lune::lua::stdio::formatting::pretty_format_luau_error;
*/ */
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct LuneError { pub struct LuneError {
message: String, error: LuaError,
incomplete_input: bool, disable_colors: bool,
} }
impl LuneError { impl LuneError {
pub(crate) fn from_lua_error(error: LuaError, disable_colors: bool) -> Self { /**
Self { Enables colorization of the error message when formatted using the [`Display`] trait.
message: pretty_format_luau_error(&error, !disable_colors),
incomplete_input: matches!( Colorization is enabled by default.
error, */
LuaError::SyntaxError { #[doc(hidden)]
incomplete_input: true, 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 { impl From<LuaError> for LuneError {
pub fn is_incomplete_input(&self) -> bool { fn from(value: LuaError) -> Self {
self.incomplete_input Self {
error: value,
disable_colors: false,
}
} }
} }
impl Display for LuneError { impl Display for LuneError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { 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)
// }
}

View file

@ -56,7 +56,7 @@ impl Lune {
) -> Result<ExitCode, LuneError> { ) -> Result<ExitCode, LuneError> {
self.run_inner(script_name, script_contents) self.run_inner(script_name, script_contents)
.await .await
.map_err(|err| LuneError::from_lua_error(err, false)) .map_err(LuneError::from)
} }
async fn run_inner( async fn run_inner(
@ -87,7 +87,7 @@ impl Lune {
loop { loop {
let result = sched.resume_queue().await; let result = sched.resume_queue().await;
if let Some(err) = result.get_lua_error() { if let Some(err) = result.get_lua_error() {
eprintln!("{}", LuneError::from_lua_error(err, false)); eprintln!("{}", LuneError::from(err));
got_error = true; got_error = true;
} }
if result.is_done() { if result.is_done() {

View file

@ -2,7 +2,7 @@ use core::fmt;
use std::ops; use std::ops;
use glam::{EulerRot, Mat4, Quat, Vec3}; 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 rbx_dom_weak::types::{CFrame as DomCFrame, Matrix3 as DomMatrix3, Vector3 as DomVector3};
use super::{super::*, Vector3}; use super::{super::*, Vector3};
@ -210,29 +210,46 @@ impl LuaUserData for CFrame {
translation, translation,
))) )))
}); });
methods.add_method("ToWorldSpace", |_, this, rhs: LuaUserDataRef<CFrame>| { methods.add_method(
Ok(*this * *rhs) "ToWorldSpace",
}); |_, this, rhs: Variadic<LuaUserDataRef<CFrame>>| {
methods.add_method("ToObjectSpace", |_, this, rhs: LuaUserDataRef<CFrame>| { Ok(Variadic::from_iter(rhs.into_iter().map(|cf| *this * *cf)))
Ok(this.inverse() * *rhs) },
}); );
methods.add_method(
"ToObjectSpace",
|_, this, rhs: Variadic<LuaUserDataRef<CFrame>>| {
let inverse = this.inverse();
Ok(Variadic::from_iter(rhs.into_iter().map(|cf| inverse * *cf)))
},
);
methods.add_method( methods.add_method(
"PointToWorldSpace", "PointToWorldSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| Ok(*this * *rhs), |_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| *this * *v3)))
},
); );
methods.add_method( methods.add_method(
"PointToObjectSpace", "PointToObjectSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| Ok(this.inverse() * *rhs), |_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
let inverse = this.inverse();
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| inverse * *v3)))
},
); );
methods.add_method( methods.add_method(
"VectorToWorldSpace", "VectorToWorldSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| Ok((*this - Vector3(this.position())) * *rhs), |_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
let result = *this - Vector3(this.position());
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3)))
},
); );
methods.add_method( methods.add_method(
"VectorToObjectSpace", "VectorToObjectSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| { |_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
let inv = this.inverse(); let inverse = this.inverse();
Ok((inv - Vector3(inv.position())) * *rhs) let result = inverse - Vector3(inverse.position());
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3)))
}, },
); );
#[rustfmt::skip] #[rustfmt::skip]

View file

@ -74,3 +74,13 @@ end)()
assert(not flag2, "Wait failed while inside wrap (1)") assert(not flag2, "Wait failed while inside wrap (1)")
task.wait(0.2) task.wait(0.2)
assert(flag2, "Wait failed while inside wrap (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)

View file

@ -103,6 +103,9 @@ local offset = CFrame.new(0, 0, -5)
assert(offset:ToWorldSpace(offset).Z == offset.Z * 2) assert(offset:ToWorldSpace(offset).Z == offset.Z * 2)
assert(offset:ToObjectSpace(offset).Z == 0) 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 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) local world2 = CFrame.fromOrientation(0, -math.rad(90), 0) * CFrame.new(0, 0, -5)
assertEq(CFrame.identity:ToObjectSpace(world), world) assertEq(CFrame.identity:ToObjectSpace(world), world)