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()
```
- 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

View file

@ -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 {

View file

@ -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<LuaError> 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)
// }
}

View file

@ -56,7 +56,7 @@ impl Lune {
) -> Result<ExitCode, LuneError> {
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() {

View file

@ -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<CFrame>| {
Ok(*this * *rhs)
});
methods.add_method("ToObjectSpace", |_, this, rhs: LuaUserDataRef<CFrame>| {
Ok(this.inverse() * *rhs)
});
methods.add_method(
"ToWorldSpace",
|_, this, rhs: Variadic<LuaUserDataRef<CFrame>>| {
Ok(Variadic::from_iter(rhs.into_iter().map(|cf| *this * *cf)))
},
);
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(
"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(
"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(
"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(
"VectorToObjectSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| {
let inv = this.inverse();
Ok((inv - Vector3(inv.position())) * *rhs)
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
let inverse = this.inverse();
let result = inverse - Vector3(inverse.position());
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3)))
},
);
#[rustfmt::skip]

View file

@ -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)

View file

@ -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)