Upgrade to mlua version 0.9

This commit is contained in:
Filip Tibell 2023-06-08 14:25:44 +02:00
parent 63f623647b
commit 1247196c35
No known key found for this signature in database
42 changed files with 429 additions and 288 deletions

45
Cargo.lock generated
View file

@ -290,11 +290,12 @@ dependencies = [
[[package]] [[package]]
name = "bstr" name = "bstr"
version = "0.2.17" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5"
dependencies = [ dependencies = [
"memchr", "memchr",
"serde",
] ]
[[package]] [[package]]
@ -1288,19 +1289,30 @@ dependencies = [
[[package]] [[package]]
name = "mlua" name = "mlua"
version = "0.8.9" version = "0.9.0-beta.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07366ed2cd22a3b000aed076e2b68896fb46f06f1f5786c5962da73c0af01577" checksum = "19b5bc62c9f83dc5c6bb36714e30aceca2fb3ac5c91a21590b0cf382b22e65e0"
dependencies = [ dependencies = [
"bstr", "bstr",
"cc",
"erased-serde", "erased-serde",
"luau0-src", "mlua-sys",
"num-traits", "num-traits",
"once_cell", "once_cell",
"pkg-config",
"rustc-hash", "rustc-hash",
"serde", "serde",
"serde-value",
]
[[package]]
name = "mlua-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b5013b291cbd5edd9259173f1ca1e62fc2f5b670c35424361acbbccddf9c679"
dependencies = [
"cc",
"cfg-if",
"luau0-src",
"pkg-config",
] ]
[[package]] [[package]]
@ -1334,6 +1346,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-float"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "os_str_bytes" name = "os_str_bytes"
version = "6.5.0" version = "6.5.0"
@ -1834,6 +1855,16 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float",
"serde",
]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.164" version = "1.0.164"

View file

@ -22,7 +22,7 @@ directories = "5.0"
futures-util = "0.3" futures-util = "0.3"
once_cell = "1.17" once_cell = "1.17"
mlua = { version = "0.8", features = ["luau", "serialize"] } mlua = { version = "0.9.0-beta.3", features = ["luau", "serialize"] }
tokio = { version = "1.24", features = ["full"] } tokio = { version = "1.24", features = ["full"] }
# Serde dependencies, supporting user-facing formats: json, yaml, toml # Serde dependencies, supporting user-facing formats: json, yaml, toml

View file

@ -50,7 +50,7 @@ impl<'lua> DomValueToLua<'lua> for LuaValue<'lua> {
DomValue::Float64(n) => Ok(LuaValue::Number(*n)), DomValue::Float64(n) => Ok(LuaValue::Number(*n)),
DomValue::Float32(n) => Ok(LuaValue::Number(*n as f64)), DomValue::Float32(n) => Ok(LuaValue::Number(*n as f64)),
DomValue::String(s) => Ok(LuaValue::String(lua.create_string(s)?)), DomValue::String(s) => Ok(LuaValue::String(lua.create_string(s)?)),
DomValue::BinaryString(s) => Ok(LuaValue::String(lua.create_string(&s)?)), DomValue::BinaryString(s) => Ok(LuaValue::String(lua.create_string(s)?)),
DomValue::Content(s) => Ok(LuaValue::String( DomValue::Content(s) => Ok(LuaValue::String(
lua.create_string(AsRef::<str>::as_ref(s))?, lua.create_string(AsRef::<str>::as_ref(s))?,
)), )),
@ -59,7 +59,7 @@ impl<'lua> DomValueToLua<'lua> for LuaValue<'lua> {
// no longer exist, so we handle that here instead of // no longer exist, so we handle that here instead of
// in the userdata conversion to be able to return nils // in the userdata conversion to be able to return nils
DomValue::Ref(value) => match Instance::new_opt(*value) { DomValue::Ref(value) => match Instance::new_opt(*value) {
Some(inst) => Ok(inst.to_lua(lua)?), Some(inst) => Ok(inst.into_lua(lua)?),
None => Ok(LuaValue::Nil), None => Ok(LuaValue::Nil),
}, },

View file

@ -25,7 +25,7 @@ impl BrickColor {
type ArgsNumber = u16; type ArgsNumber = u16;
type ArgsName = String; type ArgsName = String;
type ArgsRgb = (u8, u8, u8); type ArgsRgb = (u8, u8, u8);
type ArgsColor3 = Color3; type ArgsColor3<'lua> = LuaUserDataRef<'lua, Color3>;
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|lua, args: LuaMultiValue| { lua.create_function(|lua, args: LuaMultiValue| {
@ -36,7 +36,7 @@ impl BrickColor {
} else if let Ok((r, g, b)) = ArgsRgb::from_lua_multi(args.clone(), lua) { } else if let Ok((r, g, b)) = ArgsRgb::from_lua_multi(args.clone(), lua) {
Ok(color_from_rgb(r, g, b)) Ok(color_from_rgb(r, g, b))
} else if let Ok(color) = ArgsColor3::from_lua_multi(args.clone(), lua) { } else if let Ok(color) = ArgsColor3::from_lua_multi(args.clone(), lua) {
Ok(Self::from(color)) Ok(Self::from(*color))
} else { } else {
// FUTURE: Better error message here using given arg types // FUTURE: Better error message here using given arg types
Err(LuaError::RuntimeError( Err(LuaError::RuntimeError(

View file

@ -42,13 +42,20 @@ impl CFrame {
// Strict args constructors // Strict args constructors
datatype_table.set( datatype_table.set(
"lookAt", "lookAt",
lua.create_function(|_, (from, to, up): (Vector3, Vector3, Option<Vector3>)| { lua.create_function(
Ok(CFrame(look_at( |_,
from.0, (from, to, up): (
to.0, LuaUserDataRef<Vector3>,
up.unwrap_or(Vector3(Vec3::Y)).0, LuaUserDataRef<Vector3>,
))) Option<LuaUserDataRef<Vector3>>,
})?, )| {
Ok(CFrame(look_at(
from.0,
to.0,
up.as_deref().unwrap_or(&Vector3(Vec3::Y)).0,
)))
},
)?,
)?; )?;
datatype_table.set( datatype_table.set(
"fromEulerAnglesXYZ", "fromEulerAnglesXYZ",
@ -76,14 +83,20 @@ impl CFrame {
)?; )?;
datatype_table.set( datatype_table.set(
"fromAxisAngle", "fromAxisAngle",
lua.create_function(|_, (v, r): (Vector3, f32)| { lua.create_function(|_, (v, r): (LuaUserDataRef<Vector3>, f32)| {
Ok(CFrame(Mat4::from_axis_angle(v.0, r))) Ok(CFrame(Mat4::from_axis_angle(v.0, r)))
})?, })?,
)?; )?;
datatype_table.set( datatype_table.set(
"fromMatrix", "fromMatrix",
lua.create_function( lua.create_function(
|_, (pos, rx, ry, rz): (Vector3, Vector3, Vector3, Option<Vector3>)| { |_,
(pos, rx, ry, rz): (
LuaUserDataRef<Vector3>,
LuaUserDataRef<Vector3>,
LuaUserDataRef<Vector3>,
Option<LuaUserDataRef<Vector3>>,
)| {
Ok(CFrame(Mat4::from_cols( Ok(CFrame(Mat4::from_cols(
rx.0.extend(0.0), rx.0.extend(0.0),
ry.0.extend(0.0), ry.0.extend(0.0),
@ -96,8 +109,12 @@ impl CFrame {
)?, )?,
)?; )?;
// Dynamic args constructor // Dynamic args constructor
type ArgsPos = Vector3; type ArgsPos<'lua> = LuaUserDataRef<'lua, Vector3>;
type ArgsLook = (Vector3, Vector3, Option<Vector3>); type ArgsLook<'lua> = (
LuaUserDataRef<'lua, Vector3>,
LuaUserDataRef<'lua, Vector3>,
Option<LuaUserDataRef<'lua, Vector3>>,
);
type ArgsPosXYZ = (f32, f32, f32); type ArgsPosXYZ = (f32, f32, f32);
type ArgsPosXYZQuat = (f32, f32, f32, f32, f32, f32, f32); type ArgsPosXYZQuat = (f32, f32, f32, f32, f32, f32, f32);
type ArgsMatrix = (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32); type ArgsMatrix = (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32);
@ -112,7 +129,7 @@ impl CFrame {
Ok(CFrame(look_at( Ok(CFrame(look_at(
from.0, from.0,
to.0, to.0,
up.unwrap_or(Vector3(Vec3::Y)).0, up.as_deref().unwrap_or(&Vector3(Vec3::Y)).0,
))) )))
} else if let Ok((x, y, z)) = ArgsPosXYZ::from_lua_multi(args.clone(), lua) { } else if let Ok((x, y, z)) = ArgsPosXYZ::from_lua_multi(args.clone(), lua) {
Ok(CFrame(Mat4::from_translation(Vec3::new(x, y, z)))) Ok(CFrame(Mat4::from_translation(Vec3::new(x, y, z))))
@ -168,20 +185,23 @@ impl LuaUserData for CFrame {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Inverse", |_, this, ()| Ok(this.inverse())); methods.add_method("Inverse", |_, this, ()| Ok(this.inverse()));
methods.add_method("Lerp", |_, this, (goal, alpha): (CFrame, f32)| { methods.add_method(
let quat_this = Quat::from_mat4(&this.0); "Lerp",
let quat_goal = Quat::from_mat4(&goal.0); |_, this, (goal, alpha): (LuaUserDataRef<CFrame>, f32)| {
let translation = this let quat_this = Quat::from_mat4(&this.0);
.0 let quat_goal = Quat::from_mat4(&goal.0);
.w_axis let translation = this
.truncate() .0
.lerp(goal.0.w_axis.truncate(), alpha); .w_axis
let rotation = quat_this.slerp(quat_goal, alpha); .truncate()
Ok(CFrame(Mat4::from_rotation_translation( .lerp(goal.0.w_axis.truncate(), alpha);
rotation, let rotation = quat_this.slerp(quat_goal, alpha);
translation, Ok(CFrame(Mat4::from_rotation_translation(
))) rotation,
}); translation,
)))
},
);
methods.add_method("Orthonormalize", |_, this, ()| { methods.add_method("Orthonormalize", |_, this, ()| {
let rotation = Quat::from_mat4(&this.0); let rotation = Quat::from_mat4(&this.0);
let translation = this.0.w_axis.truncate(); let translation = this.0.w_axis.truncate();
@ -190,21 +210,31 @@ impl LuaUserData for CFrame {
translation, translation,
))) )))
}); });
methods.add_method("ToWorldSpace", |_, this, rhs: CFrame| Ok(*this * rhs)); methods.add_method("ToWorldSpace", |_, this, rhs: LuaUserDataRef<CFrame>| {
methods.add_method("ToObjectSpace", |_, this, rhs: CFrame| { Ok(*this * *rhs)
Ok(this.inverse() * rhs)
}); });
methods.add_method("PointToWorldSpace", |_, this, rhs: Vector3| Ok(*this * rhs)); methods.add_method("ToObjectSpace", |_, this, rhs: LuaUserDataRef<CFrame>| {
methods.add_method("PointToObjectSpace", |_, this, rhs: Vector3| { Ok(this.inverse() * *rhs)
Ok(this.inverse() * rhs)
});
methods.add_method("VectorToWorldSpace", |_, this, rhs: Vector3| {
Ok((*this - Vector3(this.position())) * rhs)
});
methods.add_method("VectorToObjectSpace", |_, this, rhs: Vector3| {
let inv = this.inverse();
Ok((inv - Vector3(inv.position())) * rhs)
}); });
methods.add_method(
"PointToWorldSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| Ok(*this * *rhs),
);
methods.add_method(
"PointToObjectSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| Ok(this.inverse() * *rhs),
);
methods.add_method(
"VectorToWorldSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| Ok((*this - Vector3(this.position())) * *rhs),
);
methods.add_method(
"VectorToObjectSpace",
|_, this, rhs: LuaUserDataRef<Vector3>| {
let inv = this.inverse();
Ok((inv - Vector3(inv.position())) * *rhs)
},
);
#[rustfmt::skip] #[rustfmt::skip]
methods.add_method("GetComponents", |_, this, ()| { methods.add_method("GetComponents", |_, this, ()| {
let pos = this.position(); let pos = this.position();
@ -251,8 +281,14 @@ impl LuaUserData for CFrame {
)), )),
}) })
}); });
methods.add_meta_method(LuaMetaMethod::Add, |_, this, vec: Vector3| Ok(*this + vec)); methods.add_meta_method(
methods.add_meta_method(LuaMetaMethod::Sub, |_, this, vec: Vector3| Ok(*this - vec)); LuaMetaMethod::Add,
|_, this, vec: LuaUserDataRef<Vector3>| Ok(*this + *vec),
);
methods.add_meta_method(
LuaMetaMethod::Sub,
|_, this, vec: LuaUserDataRef<Vector3>| Ok(*this - *vec),
);
} }
} }

View file

@ -116,16 +116,19 @@ impl LuaUserData for Color3 {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Lerp", |_, this, (rhs, alpha): (Color3, f32)| { methods.add_method(
let v3_this = Vec3::new(this.r, this.g, this.b); "Lerp",
let v3_rhs = Vec3::new(rhs.r, rhs.g, rhs.b); |_, this, (rhs, alpha): (LuaUserDataRef<Color3>, f32)| {
let v3 = v3_this.lerp(v3_rhs, alpha); let v3_this = Vec3::new(this.r, this.g, this.b);
Ok(Color3 { let v3_rhs = Vec3::new(rhs.r, rhs.g, rhs.b);
r: v3.x, let v3 = v3_this.lerp(v3_rhs, alpha);
g: v3.y, Ok(Color3 {
b: v3.z, r: v3.x,
}) g: v3.y,
}); b: v3.z,
})
},
);
methods.add_method("ToHSV", |_, this, ()| { methods.add_method("ToHSV", |_, this, ()| {
// https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c // https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
let (r, g, b) = (this.r, this.g, this.b); let (r, g, b) = (this.r, this.g, this.b);

View file

@ -19,17 +19,23 @@ pub struct ColorSequence {
impl ColorSequence { impl ColorSequence {
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
type ArgsColor = Color3; type ArgsColor<'lua> = LuaUserDataRef<'lua, Color3>;
type ArgsColors = (Color3, Color3); type ArgsColors<'lua> = (LuaUserDataRef<'lua, Color3>, LuaUserDataRef<'lua, Color3>);
type ArgsKeypoints = Vec<ColorSequenceKeypoint>; type ArgsKeypoints<'lua> = Vec<LuaUserDataRef<'lua, ColorSequenceKeypoint>>;
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|lua, args: LuaMultiValue| { lua.create_function(|lua, args: LuaMultiValue| {
if let Ok(color) = ArgsColor::from_lua_multi(args.clone(), lua) { if let Ok(color) = ArgsColor::from_lua_multi(args.clone(), lua) {
Ok(ColorSequence { Ok(ColorSequence {
keypoints: vec![ keypoints: vec![
ColorSequenceKeypoint { time: 0.0, color }, ColorSequenceKeypoint {
ColorSequenceKeypoint { time: 1.0, color }, time: 0.0,
color: *color,
},
ColorSequenceKeypoint {
time: 1.0,
color: *color,
},
], ],
}) })
} else if let Ok((c0, c1)) = ArgsColors::from_lua_multi(args.clone(), lua) { } else if let Ok((c0, c1)) = ArgsColors::from_lua_multi(args.clone(), lua) {
@ -37,16 +43,18 @@ impl ColorSequence {
keypoints: vec![ keypoints: vec![
ColorSequenceKeypoint { ColorSequenceKeypoint {
time: 0.0, time: 0.0,
color: c0, color: *c0,
}, },
ColorSequenceKeypoint { ColorSequenceKeypoint {
time: 1.0, time: 1.0,
color: c1, color: *c1,
}, },
], ],
}) })
} else if let Ok(keypoints) = ArgsKeypoints::from_lua_multi(args, lua) { } else if let Ok(keypoints) = ArgsKeypoints::from_lua_multi(args, lua) {
Ok(ColorSequence { keypoints }) Ok(ColorSequence {
keypoints: keypoints.iter().map(|k| **k).collect(),
})
} else { } else {
// FUTURE: Better error message here using given arg types // FUTURE: Better error message here using given arg types
Err(LuaError::RuntimeError( Err(LuaError::RuntimeError(

View file

@ -20,8 +20,11 @@ impl ColorSequenceKeypoint {
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|_, (time, color): (f32, Color3)| { lua.create_function(|_, (time, color): (f32, LuaUserDataRef<Color3>)| {
Ok(ColorSequenceKeypoint { time, color }) Ok(ColorSequenceKeypoint {
time,
color: *color,
})
})?, })?,
)?; )?;
Ok(()) Ok(())

View file

@ -51,7 +51,7 @@ impl Font {
)?; )?;
datatype_table.set( datatype_table.set(
"fromEnum", "fromEnum",
lua.create_function(|_, value: EnumItem| { lua.create_function(|_, value: LuaUserDataRef<EnumItem>| {
if value.parent.desc.name == "Font" { if value.parent.desc.name == "Font" {
match Font::from_enum_item(&value) { match Font::from_enum_item(&value) {
Some(props) => Ok(props), Some(props) => Ok(props),
@ -308,8 +308,8 @@ impl<'lua> FromLua<'lua> for FontWeight {
} }
} }
impl<'lua> ToLua<'lua> for FontWeight { impl<'lua> IntoLua<'lua> for FontWeight {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match EnumItem::from_enum_name_and_name("FontWeight", self.to_string()) { match EnumItem::from_enum_name_and_name("FontWeight", self.to_string()) {
Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)), Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)),
None => Err(LuaError::ToLuaConversionError { None => Err(LuaError::ToLuaConversionError {
@ -403,8 +403,8 @@ impl<'lua> FromLua<'lua> for FontStyle {
} }
} }
impl<'lua> ToLua<'lua> for FontStyle { impl<'lua> IntoLua<'lua> for FontStyle {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match EnumItem::from_enum_name_and_name("FontStyle", self.to_string()) { match EnumItem::from_enum_name_and_name("FontStyle", self.to_string()) {
Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)), Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)),
None => Err(LuaError::ToLuaConversionError { None => Err(LuaError::ToLuaConversionError {

View file

@ -21,7 +21,7 @@ impl NumberSequence {
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
type ArgsColor = f32; type ArgsColor = f32;
type ArgsColors = (f32, f32); type ArgsColors = (f32, f32);
type ArgsKeypoints = Vec<NumberSequenceKeypoint>; type ArgsKeypoints<'lua> = Vec<LuaUserDataRef<'lua, NumberSequenceKeypoint>>;
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|lua, args: LuaMultiValue| { lua.create_function(|lua, args: LuaMultiValue| {
@ -56,7 +56,9 @@ impl NumberSequence {
], ],
}) })
} else if let Ok(keypoints) = ArgsKeypoints::from_lua_multi(args, lua) { } else if let Ok(keypoints) = ArgsKeypoints::from_lua_multi(args, lua) {
Ok(NumberSequence { keypoints }) Ok(NumberSequence {
keypoints: keypoints.iter().map(|k| **k).collect(),
})
} else { } else {
// FUTURE: Better error message here using given arg types // FUTURE: Better error message here using given arg types
Err(LuaError::RuntimeError( Err(LuaError::RuntimeError(

View file

@ -34,7 +34,7 @@ impl PhysicalProperties {
} }
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
type ArgsMaterial = EnumItem; type ArgsMaterial<'lua> = LuaUserDataRef<'lua, EnumItem>;
type ArgsNumbers = (f32, f32, f32, Option<f32>, Option<f32>); type ArgsNumbers = (f32, f32, f32, Option<f32>, Option<f32>);
datatype_table.set( datatype_table.set(
"new", "new",

View file

@ -30,12 +30,14 @@ impl Ray {
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|_, (origin, direction): (Vector3, Vector3)| { lua.create_function(
Ok(Ray { |_, (origin, direction): (LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>)| {
origin: origin.0, Ok(Ray {
direction: direction.0, origin: origin.0,
}) direction: direction.0,
})?, })
},
)?,
) )
} }
} }
@ -54,10 +56,10 @@ impl LuaUserData for Ray {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("ClosestPoint", |_, this, to: Vector3| { methods.add_method("ClosestPoint", |_, this, to: LuaUserDataRef<Vector3>| {
Ok(Vector3(this.closest_point(to.0))) Ok(Vector3(this.closest_point(to.0)))
}); });
methods.add_method("Distance", |_, this, to: Vector3| { methods.add_method("Distance", |_, this, to: LuaUserDataRef<Vector3>| {
let closest = this.closest_point(to.0); let closest = this.closest_point(to.0);
Ok((closest - to.0).length()) Ok((closest - to.0).length())
}); });

View file

@ -30,15 +30,18 @@ impl Rect {
impl Rect { impl Rect {
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
type ArgsVector2s = (Option<Vector2>, Option<Vector2>); type ArgsVector2s<'lua> = (
Option<LuaUserDataRef<'lua, Vector2>>,
Option<LuaUserDataRef<'lua, Vector2>>,
);
type ArgsNums = (Option<f32>, Option<f32>, Option<f32>, Option<f32>); type ArgsNums = (Option<f32>, Option<f32>, Option<f32>, Option<f32>);
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|lua, args: LuaMultiValue| { lua.create_function(|lua, args: LuaMultiValue| {
if let Ok((min, max)) = ArgsVector2s::from_lua_multi(args.clone(), lua) { if let Ok((min, max)) = ArgsVector2s::from_lua_multi(args.clone(), lua) {
Ok(Rect::new( Ok(Rect::new(
min.unwrap_or_default().0, min.map(|m| *m).unwrap_or_default().0,
max.unwrap_or_default().0, max.map(|m| *m).unwrap_or_default().0,
)) ))
} else if let Ok((x0, y0, x1, y1)) = ArgsNums::from_lua_multi(args, lua) { } else if let Ok((x0, y0, x1, y1)) = ArgsNums::from_lua_multi(args, lua) {
let min = Vec2::new(x0.unwrap_or_default(), y0.unwrap_or_default()); let min = Vec2::new(x0.unwrap_or_default(), y0.unwrap_or_default());

View file

@ -22,12 +22,14 @@ impl Region3 {
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|_, (min, max): (Vector3, Vector3)| { lua.create_function(
Ok(Region3 { |_, (min, max): (LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>)| {
min: min.0, Ok(Region3 {
max: max.0, min: min.0,
}) max: max.0,
})?, })
},
)?,
) )
} }
} }

View file

@ -22,12 +22,14 @@ impl Region3int16 {
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> { pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|_, (min, max): (Vector3int16, Vector3int16)| { lua.create_function(
Ok(Region3int16 { |_, (min, max): (LuaUserDataRef<Vector3int16>, LuaUserDataRef<Vector3int16>)| {
min: min.0, Ok(Region3int16 {
max: max.0, min: min.0,
}) max: max.0,
})?, })
},
)?,
) )
} }
} }

View file

@ -38,15 +38,18 @@ impl UDim2 {
}) })
})?, })?,
)?; )?;
type ArgsUDims = (Option<UDim>, Option<UDim>); type ArgsUDims<'lua> = (
Option<LuaUserDataRef<'lua, UDim>>,
Option<LuaUserDataRef<'lua, UDim>>,
);
type ArgsNums = (Option<f32>, Option<i32>, Option<f32>, Option<i32>); type ArgsNums = (Option<f32>, Option<i32>, Option<f32>, Option<i32>);
datatype_table.set( datatype_table.set(
"new", "new",
lua.create_function(|lua, args: LuaMultiValue| { lua.create_function(|lua, args: LuaMultiValue| {
if let Ok((x, y)) = ArgsUDims::from_lua_multi(args.clone(), lua) { if let Ok((x, y)) = ArgsUDims::from_lua_multi(args.clone(), lua) {
Ok(UDim2 { Ok(UDim2 {
x: x.unwrap_or_default(), x: x.map(|x| *x).unwrap_or_default(),
y: y.unwrap_or_default(), y: y.map(|y| *y).unwrap_or_default(),
}) })
} else if let Ok((sx, ox, sy, oy)) = ArgsNums::from_lua_multi(args, lua) { } else if let Ok((sx, ox, sy, oy)) = ArgsNums::from_lua_multi(args, lua) {
Ok(UDim2 { Ok(UDim2 {
@ -74,27 +77,30 @@ impl LuaUserData for UDim2 {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Lerp", |_, this, (goal, alpha): (UDim2, f32)| { methods.add_method(
let this_x = Vec2::new(this.x.scale, this.x.offset as f32); "Lerp",
let goal_x = Vec2::new(goal.x.scale, goal.x.offset as f32); |_, this, (goal, alpha): (LuaUserDataRef<UDim2>, f32)| {
let this_x = Vec2::new(this.x.scale, this.x.offset as f32);
let goal_x = Vec2::new(goal.x.scale, goal.x.offset as f32);
let this_y = Vec2::new(this.y.scale, this.y.offset as f32); let this_y = Vec2::new(this.y.scale, this.y.offset as f32);
let goal_y = Vec2::new(goal.y.scale, goal.y.offset as f32); let goal_y = Vec2::new(goal.y.scale, goal.y.offset as f32);
let x = this_x.lerp(goal_x, alpha); let x = this_x.lerp(goal_x, alpha);
let y = this_y.lerp(goal_y, alpha); let y = this_y.lerp(goal_y, alpha);
Ok(UDim2 { Ok(UDim2 {
x: UDim { x: UDim {
scale: x.x, scale: x.x,
offset: x.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32, offset: x.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32,
}, },
y: UDim { y: UDim {
scale: y.x, scale: y.x,
offset: y.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32, offset: y.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32,
}, },
}) })
}); },
);
// Metamethods // Metamethods
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);

View file

@ -47,19 +47,24 @@ impl LuaUserData for Vector2 {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Cross", |_, this, rhs: Vector2| { methods.add_method("Cross", |_, this, rhs: LuaUserDataRef<Vector2>| {
let this_v3 = Vec3::new(this.0.x, this.0.y, 0f32); let this_v3 = Vec3::new(this.0.x, this.0.y, 0f32);
let rhs_v3 = Vec3::new(rhs.0.x, rhs.0.y, 0f32); let rhs_v3 = Vec3::new(rhs.0.x, rhs.0.y, 0f32);
Ok(this_v3.cross(rhs_v3).z) Ok(this_v3.cross(rhs_v3).z)
}); });
methods.add_method("Dot", |_, this, rhs: Vector2| Ok(this.0.dot(rhs.0))); methods.add_method("Dot", |_, this, rhs: LuaUserDataRef<Vector2>| {
methods.add_method("Lerp", |_, this, (rhs, alpha): (Vector2, f32)| { Ok(this.0.dot(rhs.0))
Ok(Vector2(this.0.lerp(rhs.0, alpha)))
}); });
methods.add_method("Max", |_, this, rhs: Vector2| { methods.add_method(
"Lerp",
|_, this, (rhs, alpha): (LuaUserDataRef<Vector2>, f32)| {
Ok(Vector2(this.0.lerp(rhs.0, alpha)))
},
);
methods.add_method("Max", |_, this, rhs: LuaUserDataRef<Vector2>| {
Ok(Vector2(this.0.max(rhs.0))) Ok(Vector2(this.0.max(rhs.0)))
}); });
methods.add_method("Min", |_, this, rhs: Vector2| { methods.add_method("Min", |_, this, rhs: LuaUserDataRef<Vector2>| {
Ok(Vector2(this.0.min(rhs.0))) Ok(Vector2(this.0.min(rhs.0)))
}); });
// Metamethods // Metamethods

View file

@ -31,7 +31,7 @@ impl Vector3 {
// Constructors // Constructors
datatype_table.set( datatype_table.set(
"fromAxis", "fromAxis",
lua.create_function(|_, normal_id: EnumItem| { lua.create_function(|_, normal_id: LuaUserDataRef<EnumItem>| {
if normal_id.parent.desc.name == "Axis" { if normal_id.parent.desc.name == "Axis" {
Ok(match normal_id.name.as_str() { Ok(match normal_id.name.as_str() {
"X" => Vector3(Vec3::X), "X" => Vector3(Vec3::X),
@ -54,7 +54,7 @@ impl Vector3 {
)?; )?;
datatype_table.set( datatype_table.set(
"fromNormalId", "fromNormalId",
lua.create_function(|_, normal_id: EnumItem| { lua.create_function(|_, normal_id: LuaUserDataRef<EnumItem>| {
if normal_id.parent.desc.name == "NormalId" { if normal_id.parent.desc.name == "NormalId" {
Ok(match normal_id.name.as_str() { Ok(match normal_id.name.as_str() {
"Left" => Vector3(Vec3::X), "Left" => Vector3(Vec3::X),
@ -102,26 +102,34 @@ impl LuaUserData for Vector3 {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Angle", |_, this, rhs: Vector3| { methods.add_method("Angle", |_, this, rhs: LuaUserDataRef<Vector3>| {
Ok(this.0.angle_between(rhs.0)) Ok(this.0.angle_between(rhs.0))
}); });
methods.add_method("Cross", |_, this, rhs: Vector3| { methods.add_method("Cross", |_, this, rhs: LuaUserDataRef<Vector3>| {
Ok(Vector3(this.0.cross(rhs.0))) Ok(Vector3(this.0.cross(rhs.0)))
}); });
methods.add_method("Dot", |_, this, rhs: Vector3| Ok(this.0.dot(rhs.0))); methods.add_method("Dot", |_, this, rhs: LuaUserDataRef<Vector3>| {
methods.add_method("FuzzyEq", |_, this, (rhs, epsilon): (Vector3, f32)| { Ok(this.0.dot(rhs.0))
let eq_x = (rhs.0.x - this.0.x).abs() <= epsilon;
let eq_y = (rhs.0.y - this.0.y).abs() <= epsilon;
let eq_z = (rhs.0.z - this.0.z).abs() <= epsilon;
Ok(eq_x && eq_y && eq_z)
}); });
methods.add_method("Lerp", |_, this, (rhs, alpha): (Vector3, f32)| { methods.add_method(
Ok(Vector3(this.0.lerp(rhs.0, alpha))) "FuzzyEq",
}); |_, this, (rhs, epsilon): (LuaUserDataRef<Vector3>, f32)| {
methods.add_method("Max", |_, this, rhs: Vector3| { let eq_x = (rhs.0.x - this.0.x).abs() <= epsilon;
let eq_y = (rhs.0.y - this.0.y).abs() <= epsilon;
let eq_z = (rhs.0.z - this.0.z).abs() <= epsilon;
Ok(eq_x && eq_y && eq_z)
},
);
methods.add_method(
"Lerp",
|_, this, (rhs, alpha): (LuaUserDataRef<Vector3>, f32)| {
Ok(Vector3(this.0.lerp(rhs.0, alpha)))
},
);
methods.add_method("Max", |_, this, rhs: LuaUserDataRef<Vector3>| {
Ok(Vector3(this.0.max(rhs.0))) Ok(Vector3(this.0.max(rhs.0)))
}); });
methods.add_method("Min", |_, this, rhs: Vector3| { methods.add_method("Min", |_, this, rhs: LuaUserDataRef<Vector3>| {
Ok(Vector3(this.0.min(rhs.0))) Ok(Vector3(this.0.min(rhs.0)))
}); });
// Metamethods // Metamethods

View file

@ -830,7 +830,7 @@ impl Instance {
"new", "new",
lua.create_function(|lua, class_name: String| { lua.create_function(|lua, class_name: String| {
if class_exists(&class_name) { if class_exists(&class_name) {
Instance::new_orphaned(class_name).to_lua(lua) Instance::new_orphaned(class_name).into_lua(lua)
} else { } else {
Err(LuaError::RuntimeError(format!( Err(LuaError::RuntimeError(format!(
"Failed to create Instance - '{}' is not a valid class name", "Failed to create Instance - '{}' is not a valid class name",
@ -870,12 +870,12 @@ impl LuaUserData for Instance {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
match prop_name.as_str() { match prop_name.as_str() {
"ClassName" => return this.get_class_name().to_lua(lua), "ClassName" => return this.get_class_name().into_lua(lua),
"Name" => { "Name" => {
return this.get_name().to_lua(lua); return this.get_name().into_lua(lua);
} }
"Parent" => { "Parent" => {
return this.get_parent().to_lua(lua); return this.get_parent().into_lua(lua);
} }
_ => {} _ => {}
} }
@ -896,7 +896,7 @@ impl LuaUserData for Instance {
prop_name, enum_name, enum_value.to_u32() prop_name, enum_name, enum_value.to_u32()
)) ))
})? })?
.to_lua(lua) .into_lua(lua)
} else { } else {
Ok(LuaValue::dom_value_to_lua(lua, &prop)?) Ok(LuaValue::dom_value_to_lua(lua, &prop)?)
} }
@ -908,7 +908,7 @@ impl LuaUserData for Instance {
prop_name, enum_name, enum_value prop_name, enum_name, enum_value
)) ))
})? })?
.to_lua(lua) .into_lua(lua)
} else if let Some(prop_default) = info.value_default { } else if let Some(prop_default) = info.value_default {
Ok(LuaValue::dom_value_to_lua(lua, prop_default)?) Ok(LuaValue::dom_value_to_lua(lua, prop_default)?)
} else if info.value_type.is_some() { } else if info.value_type.is_some() {
@ -967,9 +967,9 @@ impl LuaUserData for Instance {
prop_name prop_name
))); )));
} }
type Parent = Option<Instance>; type Parent<'lua> = Option<LuaUserDataRef<'lua, Instance>>;
let parent = Parent::from_lua(prop_value, lua)?; let parent = Parent::from_lua(prop_value, lua)?;
this.set_parent(parent); this.set_parent(parent.map(|p| p.clone()));
return Ok(()); return Ok(());
} }
_ => {} _ => {}
@ -986,9 +986,12 @@ impl LuaUserData for Instance {
}; };
if let Some(enum_name) = info.enum_name { if let Some(enum_name) = info.enum_name {
match EnumItem::from_lua(prop_value, lua) { match LuaUserDataRef::<EnumItem>::from_lua(prop_value, lua) {
Ok(given_enum) if given_enum.parent.desc.name == enum_name => { Ok(given_enum) if given_enum.parent.desc.name == enum_name => {
this.set_property(prop_name, DomValue::Enum(given_enum.into())); this.set_property(
prop_name,
DomValue::Enum((*given_enum).clone().into()),
);
Ok(()) Ok(())
} }
Ok(given_enum) => Err(LuaError::RuntimeError(format!( Ok(given_enum) => Err(LuaError::RuntimeError(format!(
@ -1022,7 +1025,7 @@ impl LuaUserData for Instance {
*/ */
methods.add_method("Clone", |lua, this, ()| { methods.add_method("Clone", |lua, this, ()| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
this.clone_instance().to_lua(lua) this.clone_instance().into_lua(lua)
}); });
methods.add_method_mut("Destroy", |_, this, ()| { methods.add_method_mut("Destroy", |_, this, ()| {
this.destroy(); this.destroy();
@ -1034,26 +1037,26 @@ impl LuaUserData for Instance {
}); });
methods.add_method("GetChildren", |lua, this, ()| { methods.add_method("GetChildren", |lua, this, ()| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
this.get_children().to_lua(lua) this.get_children().into_lua(lua)
}); });
methods.add_method("GetDescendants", |lua, this, ()| { methods.add_method("GetDescendants", |lua, this, ()| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
this.get_descendants().to_lua(lua) this.get_descendants().into_lua(lua)
}); });
methods.add_method("GetFullName", |lua, this, ()| { methods.add_method("GetFullName", |lua, this, ()| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
this.get_full_name().to_lua(lua) this.get_full_name().into_lua(lua)
}); });
methods.add_method("FindFirstAncestor", |lua, this, name: String| { methods.add_method("FindFirstAncestor", |lua, this, name: String| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
this.find_ancestor(|child| child.name == name).to_lua(lua) this.find_ancestor(|child| child.name == name).into_lua(lua)
}); });
methods.add_method( methods.add_method(
"FindFirstAncestorOfClass", "FindFirstAncestorOfClass",
|lua, this, class_name: String| { |lua, this, class_name: String| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
this.find_ancestor(|child| child.class == class_name) this.find_ancestor(|child| child.class == class_name)
.to_lua(lua) .into_lua(lua)
}, },
); );
methods.add_method( methods.add_method(
@ -1061,7 +1064,7 @@ impl LuaUserData for Instance {
|lua, this, class_name: String| { |lua, this, class_name: String| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
this.find_ancestor(|child| class_is_a(&child.class, &class_name).unwrap_or(false)) this.find_ancestor(|child| class_is_a(&child.class, &class_name).unwrap_or(false))
.to_lua(lua) .into_lua(lua)
}, },
); );
methods.add_method( methods.add_method(
@ -1070,9 +1073,9 @@ impl LuaUserData for Instance {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
let predicate = |child: &DomInstance| child.name == name; let predicate = |child: &DomInstance| child.name == name;
if matches!(recursive, Some(true)) { if matches!(recursive, Some(true)) {
this.find_descendant(predicate).to_lua(lua) this.find_descendant(predicate).into_lua(lua)
} else { } else {
this.find_child(predicate).to_lua(lua) this.find_child(predicate).into_lua(lua)
} }
}, },
); );
@ -1082,9 +1085,9 @@ impl LuaUserData for Instance {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
let predicate = |child: &DomInstance| child.class == class_name; let predicate = |child: &DomInstance| child.class == class_name;
if matches!(recursive, Some(true)) { if matches!(recursive, Some(true)) {
this.find_descendant(predicate).to_lua(lua) this.find_descendant(predicate).into_lua(lua)
} else { } else {
this.find_child(predicate).to_lua(lua) this.find_child(predicate).into_lua(lua)
} }
}, },
); );
@ -1095,9 +1098,9 @@ impl LuaUserData for Instance {
let predicate = let predicate =
|child: &DomInstance| class_is_a(&child.class, &class_name).unwrap_or(false); |child: &DomInstance| class_is_a(&child.class, &class_name).unwrap_or(false);
if matches!(recursive, Some(true)) { if matches!(recursive, Some(true)) {
this.find_descendant(predicate).to_lua(lua) this.find_descendant(predicate).into_lua(lua)
} else { } else {
this.find_child(predicate).to_lua(lua) this.find_child(predicate).into_lua(lua)
} }
}, },
); );
@ -1105,18 +1108,24 @@ impl LuaUserData for Instance {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
Ok(class_is_a(&this.class_name, class_name).unwrap_or(false)) Ok(class_is_a(&this.class_name, class_name).unwrap_or(false))
}); });
methods.add_method("IsAncestorOf", |_, this, instance: Instance| { methods.add_method(
this.ensure_not_destroyed()?; "IsAncestorOf",
Ok(instance |_, this, instance: LuaUserDataRef<Instance>| {
.find_ancestor(|ancestor| ancestor.referent() == this.dom_ref) this.ensure_not_destroyed()?;
.is_some()) Ok(instance
}); .find_ancestor(|ancestor| ancestor.referent() == this.dom_ref)
methods.add_method("IsDescendantOf", |_, this, instance: Instance| { .is_some())
this.ensure_not_destroyed()?; },
Ok(this );
.find_ancestor(|ancestor| ancestor.referent() == instance.dom_ref) methods.add_method(
.is_some()) "IsDescendantOf",
}); |_, this, instance: LuaUserDataRef<Instance>| {
this.ensure_not_destroyed()?;
Ok(this
.find_ancestor(|ancestor| ancestor.referent() == instance.dom_ref)
.is_some())
},
);
methods.add_method("GetAttribute", |lua, this, name: String| { methods.add_method("GetAttribute", |lua, this, name: String| {
this.ensure_not_destroyed()?; this.ensure_not_destroyed()?;
match this.get_attribute(name) { match this.get_attribute(name) {

View file

@ -48,7 +48,7 @@ fn make_all_datatypes(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
// Classes // Classes
("Instance", make(lua, Instance::make_table)?), ("Instance", make(lua, Instance::make_table)?),
// Singletons // Singletons
("Enum", Enums.to_lua(lua)?), ("Enum", Enums.into_lua(lua)?),
]) ])
} }

View file

@ -12,7 +12,7 @@ pub(crate) fn add_class_restricted_getter<'lua, F: LuaUserDataFields<'lua, Insta
field_name: &'static str, field_name: &'static str,
field_getter: G, field_getter: G,
) where ) where
R: ToLua<'lua>, R: IntoLua<'lua>,
G: 'static + Fn(&'lua Lua, &Instance) -> LuaResult<R>, G: 'static + Fn(&'lua Lua, &Instance) -> LuaResult<R>,
{ {
fields.add_field_method_get(field_name, move |lua, this| { fields.add_field_method_get(field_name, move |lua, this| {
@ -56,7 +56,7 @@ pub(crate) fn add_class_restricted_method<'lua, M: LuaUserDataMethods<'lua, Inst
method: F, method: F,
) where ) where
A: FromLuaMulti<'lua>, A: FromLuaMulti<'lua>,
R: ToLuaMulti<'lua>, R: IntoLuaMulti<'lua>,
F: 'static + Fn(&'lua Lua, &Instance, A) -> LuaResult<R>, F: 'static + Fn(&'lua Lua, &Instance, A) -> LuaResult<R>,
{ {
methods.add_method(method_name, move |lua, this, args| { methods.add_method(method_name, move |lua, this, args| {
@ -85,7 +85,7 @@ pub(crate) fn add_class_restricted_method_mut<
method: F, method: F,
) where ) where
A: FromLuaMulti<'lua>, A: FromLuaMulti<'lua>,
R: ToLuaMulti<'lua>, R: IntoLuaMulti<'lua>,
F: 'static + Fn(&'lua Lua, &mut Instance, A) -> LuaResult<R>, F: 'static + Fn(&'lua Lua, &mut Instance, A) -> LuaResult<R>,
{ {
methods.add_method_mut(method_name, move |lua, this, args| { methods.add_method_mut(method_name, move |lua, this, args| {

View file

@ -50,18 +50,18 @@ where
Ok(-*datatype) Ok(-*datatype)
} }
pub fn userdata_impl_add<D>(_: &Lua, datatype: &D, value: D) -> LuaResult<D> pub fn userdata_impl_add<D>(_: &Lua, datatype: &D, value: LuaUserDataRef<D>) -> LuaResult<D>
where where
D: LuaUserData + ops::Add<Output = D> + Copy, D: LuaUserData + ops::Add<Output = D> + Copy,
{ {
Ok(*datatype + value) Ok(*datatype + *value)
} }
pub fn userdata_impl_sub<D>(_: &Lua, datatype: &D, value: D) -> LuaResult<D> pub fn userdata_impl_sub<D>(_: &Lua, datatype: &D, value: LuaUserDataRef<D>) -> LuaResult<D>
where where
D: LuaUserData + ops::Sub<Output = D> + Copy, D: LuaUserData + ops::Sub<Output = D> + Copy,
{ {
Ok(*datatype - value) Ok(*datatype - *value)
} }
pub fn userdata_impl_mul_f32<D>(_: &Lua, datatype: &D, rhs: LuaValue) -> LuaResult<D> pub fn userdata_impl_mul_f32<D>(_: &Lua, datatype: &D, rhs: LuaValue) -> LuaResult<D>

View file

@ -21,7 +21,7 @@ pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
async fn fs_read_file(lua: &'static Lua, path: String) -> LuaResult<LuaString> { async fn fs_read_file(lua: &'static Lua, path: String) -> LuaResult<LuaString> {
let bytes = fs::read(&path).await.map_err(LuaError::external)?; let bytes = fs::read(&path).await.map_err(LuaError::external)?;
lua.create_string(&bytes) lua.create_string(bytes)
} }
async fn fs_read_dir(_: &'static Lua, path: String) -> LuaResult<Vec<String>> { async fn fs_read_dir(_: &'static Lua, path: String) -> LuaResult<Vec<String>> {

View file

@ -61,7 +61,7 @@ fn net_json_decode<'a>(lua: &'static Lua, json: LuaString<'a>) -> LuaResult<LuaV
async fn net_request<'a>(lua: &'static Lua, config: RequestConfig<'a>) -> LuaResult<LuaTable<'a>> { async fn net_request<'a>(lua: &'static Lua, config: RequestConfig<'a>) -> LuaResult<LuaTable<'a>> {
// Create and send the request // Create and send the request
let client: NetClient = lua.named_registry_value("net.client")?; let client: LuaUserDataRef<NetClient> = lua.named_registry_value("net.client")?;
let mut request = client.request(config.method, &config.url); let mut request = client.request(config.method, &config.url);
for (query, value) in config.query { for (query, value) in config.query {
request = request.query(&[(query.to_str()?, value.to_str()?)]); request = request.query(&[(query.to_str()?, value.to_str()?)]);
@ -195,9 +195,9 @@ fn net_url_encode<'a>(
(lua_string, as_binary): (LuaString<'a>, Option<bool>), (lua_string, as_binary): (LuaString<'a>, Option<bool>),
) -> LuaResult<LuaValue<'a>> { ) -> LuaResult<LuaValue<'a>> {
if matches!(as_binary, Some(true)) { if matches!(as_binary, Some(true)) {
urlencoding::encode_binary(lua_string.as_bytes()).to_lua(lua) urlencoding::encode_binary(lua_string.as_bytes()).into_lua(lua)
} else { } else {
urlencoding::encode(lua_string.to_str()?).to_lua(lua) urlencoding::encode(lua_string.to_str()?).into_lua(lua)
} }
} }
@ -206,10 +206,10 @@ fn net_url_decode<'a>(
(lua_string, as_binary): (LuaString<'a>, Option<bool>), (lua_string, as_binary): (LuaString<'a>, Option<bool>),
) -> LuaResult<LuaValue<'a>> { ) -> LuaResult<LuaValue<'a>> {
if matches!(as_binary, Some(true)) { if matches!(as_binary, Some(true)) {
urlencoding::decode_binary(lua_string.as_bytes()).to_lua(lua) urlencoding::decode_binary(lua_string.as_bytes()).into_lua(lua)
} else { } else {
urlencoding::decode(lua_string.to_str()?) urlencoding::decode(lua_string.to_str()?)
.map_err(|e| LuaError::RuntimeError(format!("Encountered invalid encoding - {e}")))? .map_err(|e| LuaError::RuntimeError(format!("Encountered invalid encoding - {e}")))?
.to_lua(lua) .into_lua(lua)
} }
} }

View file

@ -61,13 +61,13 @@ pub fn create(lua: &'static Lua, args_vec: Vec<String>) -> LuaResult<LuaTable> {
})?; })?;
let process_exit = lua let process_exit = lua
.load(PROCESS_EXIT_IMPL_LUA) .load(PROCESS_EXIT_IMPL_LUA)
.set_name("=process.exit")? .set_name("=process.exit")
.set_environment( .set_environment(
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_value("yield", process_exit_env_yield)? .with_value("yield", process_exit_env_yield)?
.with_value("exit", process_exit_env_exit)? .with_value("exit", process_exit_env_exit)?
.build_readonly()?, .build_readonly()?,
)? )
.into_function()?; .into_function()?;
// Create the full process table // Create the full process table
TableBuilder::new(lua)? TableBuilder::new(lua)?

View file

@ -34,7 +34,7 @@ async fn deserialize_place<'lua>(
let data_model = doc.into_data_model_instance()?; let data_model = doc.into_data_model_instance()?;
Ok::<_, DocumentError>(data_model) Ok::<_, DocumentError>(data_model)
}); });
fut.await?.to_lua(lua) fut.await?.into_lua(lua)
} }
async fn deserialize_model<'lua>( async fn deserialize_model<'lua>(
@ -47,13 +47,14 @@ async fn deserialize_model<'lua>(
let instance_array = doc.into_instance_array()?; let instance_array = doc.into_instance_array()?;
Ok::<_, DocumentError>(instance_array) Ok::<_, DocumentError>(instance_array)
}); });
fut.await?.to_lua(lua) fut.await?.into_lua(lua)
} }
async fn serialize_place( async fn serialize_place<'lua>(
lua: &Lua, lua: &'lua Lua,
(data_model, as_xml): (Instance, Option<bool>), (data_model, as_xml): (LuaUserDataRef<'lua, Instance>, Option<bool>),
) -> LuaResult<LuaString> { ) -> LuaResult<LuaString<'lua>> {
let data_model = (*data_model).clone();
let fut = unblock(move || { let fut = unblock(move || {
let doc = Document::from_data_model_instance(data_model)?; let doc = Document::from_data_model_instance(data_model)?;
let bytes = doc.to_bytes_with_format(match as_xml { let bytes = doc.to_bytes_with_format(match as_xml {
@ -63,13 +64,14 @@ async fn serialize_place(
Ok::<_, DocumentError>(bytes) Ok::<_, DocumentError>(bytes)
}); });
let bytes = fut.await?; let bytes = fut.await?;
lua.create_string(&bytes) lua.create_string(bytes)
} }
async fn serialize_model( async fn serialize_model<'lua>(
lua: &Lua, lua: &'lua Lua,
(instances, as_xml): (Vec<Instance>, Option<bool>), (instances, as_xml): (Vec<LuaUserDataRef<'lua, Instance>>, Option<bool>),
) -> LuaResult<LuaString> { ) -> LuaResult<LuaString<'lua>> {
let instances = instances.iter().map(|i| (*i).clone()).collect();
let fut = unblock(move || { let fut = unblock(move || {
let doc = Document::from_instance_array(instances)?; let doc = Document::from_instance_array(instances)?;
let bytes = doc.to_bytes_with_format(match as_xml { let bytes = doc.to_bytes_with_format(match as_xml {
@ -79,7 +81,7 @@ async fn serialize_model(
Ok::<_, DocumentError>(bytes) Ok::<_, DocumentError>(bytes)
}); });
let bytes = fut.await?; let bytes = fut.await?;
lua.create_string(&bytes) lua.create_string(bytes)
} }
async fn get_auth_cookie(_: &Lua, raw: Option<bool>) -> LuaResult<Option<String>> { async fn get_auth_cookie(_: &Lua, raw: Option<bool>) -> LuaResult<Option<String>> {

View file

@ -37,7 +37,7 @@ async fn serde_compress<'a>(
(format, str): (CompressDecompressFormat, LuaString<'a>), (format, str): (CompressDecompressFormat, LuaString<'a>),
) -> LuaResult<LuaString<'a>> { ) -> LuaResult<LuaString<'a>> {
let bytes = compress(format, str).await?; let bytes = compress(format, str).await?;
lua.create_string(&bytes) lua.create_string(bytes)
} }
async fn serde_decompress<'a>( async fn serde_decompress<'a>(
@ -45,5 +45,5 @@ async fn serde_decompress<'a>(
(format, str): (CompressDecompressFormat, LuaString<'a>), (format, str): (CompressDecompressFormat, LuaString<'a>),
) -> LuaResult<LuaString<'a>> { ) -> LuaResult<LuaString<'a>> {
let bytes = decompress(format, str).await?; let bytes = decompress(format, str).await?;
lua.create_string(&bytes) lua.create_string(bytes)
} }

View file

@ -33,7 +33,7 @@ pub fn create(lua: &'static Lua) -> LuaResult<LuaTable<'static>> {
let task_spawn_env_yield: LuaFunction = lua.named_registry_value("co.yield")?; let task_spawn_env_yield: LuaFunction = lua.named_registry_value("co.yield")?;
let task_spawn = lua let task_spawn = lua
.load(SPAWN_IMPL_LUA) .load(SPAWN_IMPL_LUA)
.set_name("task.spawn")? .set_name("task.spawn")
.set_environment( .set_environment(
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("thread", |lua, _: ()| Ok(lua.current_thread()))? .with_function("thread", |lua, _: ()| Ok(lua.current_thread()))?
@ -46,7 +46,7 @@ pub fn create(lua: &'static Lua) -> LuaResult<LuaTable<'static>> {
}, },
)? )?
.build_readonly()?, .build_readonly()?,
)? )
.into_function()?; .into_function()?;
// Functions in the built-in coroutine library also need to be // Functions in the built-in coroutine library also need to be
// replaced, these are a bit different than the ones above because // replaced, these are a bit different than the ones above because
@ -71,9 +71,9 @@ pub fn create(lua: &'static Lua) -> LuaResult<LuaTable<'static>> {
Basic task functions Basic task functions
*/ */
fn task_cancel(lua: &Lua, task: TaskReference) -> LuaResult<()> { fn task_cancel(lua: &Lua, task: LuaUserDataRef<TaskReference>) -> LuaResult<()> {
let sched = lua.app_data_ref::<&TaskScheduler>().unwrap(); let sched = lua.app_data_ref::<&TaskScheduler>().unwrap();
sched.remove_task(task)?; sched.remove_task(*task)?;
Ok(()) Ok(())
} }
@ -136,7 +136,7 @@ fn coroutine_resume<'lua>(
sched.force_set_current_task(Some(current)); sched.force_set_current_task(Some(current));
match result { match result {
Ok(rets) => Ok((true, rets.1)), Ok(rets) => Ok((true, rets.1)),
Err(e) => Ok((false, e.to_lua_multi(lua)?)), Err(e) => Ok((false, e.into_lua_multi(lua)?)),
} }
} }

View file

@ -43,7 +43,7 @@ pub fn error(lua: &Lua, (arg, level): (LuaValue, Option<u32>)) -> LuaResult<()>
cause: LuaError::external(format!( cause: LuaError::external(format!(
"{}\n{}", "{}\n{}",
format_label("error"), format_label("error"),
pretty_format_multi_value(&arg.to_lua_multi(lua)?)? pretty_format_multi_value(&arg.into_lua_multi(lua)?)?
)) ))
.into(), .into(),
}, },
@ -58,8 +58,7 @@ pub fn proxy_type<'lua>(lua: &'lua Lua, value: LuaValue<'lua>) -> LuaResult<LuaS
return lua.create_string("thread"); return lua.create_string("thread");
} }
} }
lua.named_registry_value::<_, LuaFunction>("type")? lua.named_registry_value::<LuaFunction>("type")?.call(value)
.call(value)
} }
pub fn proxy_typeof<'lua>(lua: &'lua Lua, value: LuaValue<'lua>) -> LuaResult<LuaString<'lua>> { pub fn proxy_typeof<'lua>(lua: &'lua Lua, value: LuaValue<'lua>) -> LuaResult<LuaString<'lua>> {
@ -74,7 +73,7 @@ pub fn proxy_typeof<'lua>(lua: &'lua Lua, value: LuaValue<'lua>) -> LuaResult<Lu
} }
} }
} }
lua.named_registry_value::<_, LuaFunction>("typeof")? lua.named_registry_value::<LuaFunction>("typeof")?
.call(value) .call(value)
} }

View file

@ -44,7 +44,7 @@ impl<'lua> RequireContext<'lua> {
pub fn new<K, V>(lua: &'lua Lua, builtins_vec: Vec<(K, V)>) -> LuaResult<Self> pub fn new<K, V>(lua: &'lua Lua, builtins_vec: Vec<(K, V)>) -> LuaResult<Self>
where where
K: Into<String>, K: Into<String>,
V: ToLua<'lua>, V: IntoLua<'lua>,
{ {
let mut pwd = current_dir() let mut pwd = current_dir()
.expect("Failed to access current working directory") .expect("Failed to access current working directory")
@ -55,7 +55,7 @@ impl<'lua> RequireContext<'lua> {
} }
let mut builtins = HashMap::new(); let mut builtins = HashMap::new();
for (key, value) in builtins_vec { for (key, value) in builtins_vec {
builtins.insert(key.into(), value.to_lua_multi(lua)?); builtins.insert(key.into(), value.into_lua_multi(lua)?);
} }
Ok(Self { Ok(Self {
pwd, pwd,
@ -187,7 +187,7 @@ async fn load_file<'lua>(
// Load the file into a thread // Load the file into a thread
let loaded_func = lua let loaded_func = lua
.load(&contents) .load(&contents)
.set_name(path_relative_no_extension)? .set_name(path_relative_no_extension)
.into_function()?; .into_function()?;
let loaded_thread = lua.create_thread(loaded_func)?; let loaded_thread = lua.create_thread(loaded_func)?;
// Run the thread and wait for completion using the native task scheduler waker // Run the thread and wait for completion using the native task scheduler waker
@ -207,7 +207,7 @@ async fn load_file<'lua>(
async fn load<'lua>( async fn load<'lua>(
lua: &'lua Lua, lua: &'lua Lua,
context: RequireContext<'lua>, context: LuaUserDataRef<'lua, RequireContext<'lua>>,
absolute_path: String, absolute_path: String,
relative_path: String, relative_path: String,
has_acquired_lock: bool, has_acquired_lock: bool,
@ -247,7 +247,7 @@ async fn load<'lua>(
pub fn create<K, V>(lua: &'static Lua, builtins: Vec<(K, V)>) -> LuaResult<LuaFunction> pub fn create<K, V>(lua: &'static Lua, builtins: Vec<(K, V)>) -> LuaResult<LuaFunction>
where where
K: Clone + Into<String>, K: Clone + Into<String>,
V: Clone + ToLua<'static>, V: Clone + IntoLua<'static>,
{ {
let require_context = RequireContext::new(lua, builtins)?; let require_context = RequireContext::new(lua, builtins)?;
let require_yield: LuaFunction = lua.named_registry_value("co.yield")?; let require_yield: LuaFunction = lua.named_registry_value("co.yield")?;
@ -261,7 +261,12 @@ where
.with_value("print", require_print)? .with_value("print", require_print)?
.with_function( .with_function(
"load", "load",
|lua, (context, require_source, require_path): (RequireContext, String, String)| { |lua,
(context, require_source, require_path): (
LuaUserDataRef<RequireContext>,
String,
String,
)| {
let (absolute_path, relative_path) = let (absolute_path, relative_path) =
context.get_paths(require_source, require_path)?; context.get_paths(require_source, require_path)?;
// NOTE: We can not acquire the lock in the async part of the require // NOTE: We can not acquire the lock in the async part of the require
@ -274,7 +279,7 @@ where
.expect("Missing task scheduler as a lua app data"); .expect("Missing task scheduler as a lua app data");
sched.queue_async_task_inherited(lua.current_thread(), None, async { sched.queue_async_task_inherited(lua.current_thread(), None, async {
let rets = fut.await?; let rets = fut.await?;
let mult = rets.to_lua_multi(lua)?; let mult = rets.into_lua_multi(lua)?;
Ok(Some(mult)) Ok(Some(mult))
}) })
}, },
@ -283,8 +288,8 @@ where
let require_fn_lua = lua let require_fn_lua = lua
.load(REQUIRE_IMPL_LUA) .load(REQUIRE_IMPL_LUA)
.set_name("require")? .set_name("require")
.set_environment(require_env)? .set_environment(require_env)
.into_function()?; .into_function()?;
Ok(require_fn_lua) Ok(require_fn_lua)
} }

View file

@ -76,10 +76,10 @@ impl Lune {
// Create the main thread and schedule it // Create the main thread and schedule it
let main_chunk = lua let main_chunk = lua
.load(script_contents.as_ref()) .load(script_contents.as_ref())
.set_name(script_name.as_ref())? .set_name(script_name.as_ref())
.into_function()?; .into_function()?;
let main_thread = lua.create_thread(main_chunk)?; let main_thread = lua.create_thread(main_chunk)?;
let main_thread_args = LuaValue::Nil.to_lua_multi(lua)?; let main_thread_args = LuaValue::Nil.into_lua_multi(lua)?;
sched.schedule_blocking(main_thread, main_thread_args)?; sched.schedule_blocking(main_thread, main_thread_args)?;
// Keep running the scheduler until there are either no tasks // Keep running the scheduler until there are either no tasks
// left to run, or until a task requests to exit the process // left to run, or until a task requests to exit the process

View file

@ -21,7 +21,7 @@ pub trait LuaAsyncExt {
fn create_async_function<'lua, A, R, F, FR>(self, func: F) -> LuaResult<LuaFunction<'lua>> fn create_async_function<'lua, A, R, F, FR>(self, func: F) -> LuaResult<LuaFunction<'lua>>
where where
A: FromLuaMulti<'static>, A: FromLuaMulti<'static>,
R: ToLuaMulti<'static>, R: IntoLuaMulti<'static>,
F: 'static + Fn(&'lua Lua, A) -> FR, F: 'static + Fn(&'lua Lua, A) -> FR,
FR: 'static + Future<Output = LuaResult<R>>; FR: 'static + Future<Output = LuaResult<R>>;
@ -36,7 +36,7 @@ impl LuaAsyncExt for &'static Lua {
fn create_async_function<'lua, A, R, F, FR>(self, func: F) -> LuaResult<LuaFunction<'lua>> fn create_async_function<'lua, A, R, F, FR>(self, func: F) -> LuaResult<LuaFunction<'lua>>
where where
A: FromLuaMulti<'static>, A: FromLuaMulti<'static>,
R: ToLuaMulti<'static>, R: IntoLuaMulti<'static>,
F: 'static + Fn(&'lua Lua, A) -> FR, F: 'static + Fn(&'lua Lua, A) -> FR,
FR: 'static + Future<Output = LuaResult<R>>, FR: 'static + Future<Output = LuaResult<R>>,
{ {
@ -53,7 +53,7 @@ impl LuaAsyncExt for &'static Lua {
.expect("Missing task scheduler as a lua app data"); .expect("Missing task scheduler as a lua app data");
sched.queue_async_task(thread, None, async { sched.queue_async_task(thread, None, async {
let rets = fut.await?; let rets = fut.await?;
let mult = rets.to_lua_multi(lua)?; let mult = rets.into_lua_multi(lua)?;
Ok(Some(mult)) Ok(Some(mult))
}) })
}, },
@ -61,8 +61,8 @@ impl LuaAsyncExt for &'static Lua {
.build_readonly()?; .build_readonly()?;
let async_func = self let async_func = self
.load(ASYNC_IMPL_LUA) .load(ASYNC_IMPL_LUA)
.set_name("async")? .set_name("async")
.set_environment(async_env)? .set_environment(async_env)
.into_function()?; .into_function()?;
Ok(async_func) Ok(async_func)
} }
@ -88,8 +88,8 @@ impl LuaAsyncExt for &'static Lua {
.build_readonly()?; .build_readonly()?;
let async_func = self let async_func = self
.load(WAIT_IMPL_LUA) .load(WAIT_IMPL_LUA)
.set_name("wait")? .set_name("wait")
.set_environment(async_env)? .set_environment(async_env)
.into_function()?; .into_function()?;
Ok(async_func) Ok(async_func)
} }

View file

@ -118,8 +118,8 @@ pub fn create() -> LuaResult<&'static Lua> {
dbg_trace_env.set("format", string.get::<_, LuaFunction>("format")?)?; dbg_trace_env.set("format", string.get::<_, LuaFunction>("format")?)?;
let dbg_trace_fn = lua let dbg_trace_fn = lua
.load(TRACE_IMPL_LUA) .load(TRACE_IMPL_LUA)
.set_name("=dbg.trace")? .set_name("=dbg.trace")
.set_environment(dbg_trace_env)? .set_environment(dbg_trace_env)
.into_function()?; .into_function()?;
lua.set_named_registry_value("dbg.trace", dbg_trace_fn)?; lua.set_named_registry_value("dbg.trace", dbg_trace_fn)?;
// Modify the _VERSION global to also contain the current version of Lune // Modify the _VERSION global to also contain the current version of Lune

View file

@ -82,8 +82,8 @@ impl<'lua> FromLua<'lua> for NetServeResponse {
} }
} }
impl<'lua> ToLua<'lua> for NetServeResponse { impl<'lua> IntoLua<'lua> for NetServeResponse {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
if self.headers.len() > i32::MAX as usize { if self.headers.len() > i32::MAX as usize {
return Err(LuaError::ToLuaConversionError { return Err(LuaError::ToLuaConversionError {
from: "NetServeResponse", from: "NetServeResponse",
@ -91,7 +91,7 @@ impl<'lua> ToLua<'lua> for NetServeResponse {
message: Some("Too many header values".to_string()), message: Some("Too many header values".to_string()),
}); });
} }
let body = self.body.map(|b| lua.create_string(&b)).transpose()?; let body = self.body.map(|b| lua.create_string(b)).transpose()?;
let headers = lua.create_table_with_capacity(0, self.headers.len() as i32)?; let headers = lua.create_table_with_capacity(0, self.headers.len() as i32)?;
for (key, value) in self.headers { for (key, value) in self.headers {
headers.set(key, lua.create_string(&value)?)?; headers.set(key, lua.create_string(&value)?)?;

View file

@ -72,8 +72,8 @@ where
env: LuaTable<'lua>, env: LuaTable<'lua>,
) -> LuaResult<LuaTable<'lua>> { ) -> LuaResult<LuaTable<'lua>> {
lua.load(WEB_SOCKET_IMPL_LUA) lua.load(WEB_SOCKET_IMPL_LUA)
.set_name("websocket")? .set_name("websocket")
.set_environment(env)? .set_environment(env)
.eval() .eval()
} }
} }
@ -89,11 +89,11 @@ impl NetWebSocket<NetWebSocketStreamClient> {
.with_async_function("next", next::<NetWebSocketStreamClient>)? .with_async_function("next", next::<NetWebSocketStreamClient>)?
.with_value( .with_value(
"setmetatable", "setmetatable",
lua.named_registry_value::<_, LuaFunction>("tab.setmeta")?, lua.named_registry_value::<LuaFunction>("tab.setmeta")?,
)? )?
.with_value( .with_value(
"freeze", "freeze",
lua.named_registry_value::<_, LuaFunction>("tab.freeze")?, lua.named_registry_value::<LuaFunction>("tab.freeze")?,
)? )?
.build_readonly()?; .build_readonly()?;
Self::into_lua_table_with_env(lua, socket_env) Self::into_lua_table_with_env(lua, socket_env)
@ -111,11 +111,11 @@ impl NetWebSocket<NetWebSocketStreamServer> {
.with_async_function("next", next::<NetWebSocketStreamServer>)? .with_async_function("next", next::<NetWebSocketStreamServer>)?
.with_value( .with_value(
"setmetatable", "setmetatable",
lua.named_registry_value::<_, LuaFunction>("tab.setmeta")?, lua.named_registry_value::<LuaFunction>("tab.setmeta")?,
)? )?
.with_value( .with_value(
"freeze", "freeze",
lua.named_registry_value::<_, LuaFunction>("tab.freeze")?, lua.named_registry_value::<LuaFunction>("tab.freeze")?,
)? )?
.build_readonly()?; .build_readonly()?;
Self::into_lua_table_with_env(lua, socket_env) Self::into_lua_table_with_env(lua, socket_env)
@ -124,7 +124,10 @@ impl NetWebSocket<NetWebSocketStreamServer> {
impl<T> LuaUserData for NetWebSocket<T> {} impl<T> LuaUserData for NetWebSocket<T> {}
fn close_code<T>(_lua: &Lua, socket: NetWebSocket<T>) -> LuaResult<LuaValue> fn close_code<'lua, T>(
_lua: &'lua Lua,
socket: LuaUserDataRef<'lua, NetWebSocket<T>>,
) -> LuaResult<LuaValue<'lua>>
where where
T: AsyncRead + AsyncWrite + Unpin, T: AsyncRead + AsyncWrite + Unpin,
{ {
@ -134,7 +137,10 @@ where
}) })
} }
async fn close<T>(_lua: &Lua, (socket, code): (NetWebSocket<T>, Option<u16>)) -> LuaResult<()> async fn close<'lua, T>(
_lua: &'lua Lua,
(socket, code): (LuaUserDataRef<'lua, NetWebSocket<T>>, Option<u16>),
) -> LuaResult<()>
where where
T: AsyncRead + AsyncWrite + Unpin, T: AsyncRead + AsyncWrite + Unpin,
{ {
@ -154,9 +160,13 @@ where
res.await.map_err(LuaError::external) res.await.map_err(LuaError::external)
} }
async fn send<T>( async fn send<'lua, T>(
_lua: &Lua, _lua: &'lua Lua,
(socket, string, as_binary): (NetWebSocket<T>, LuaString<'_>, Option<bool>), (socket, string, as_binary): (
LuaUserDataRef<'lua, NetWebSocket<T>>,
LuaString<'lua>,
Option<bool>,
),
) -> LuaResult<()> ) -> LuaResult<()>
where where
T: AsyncRead + AsyncWrite + Unpin, T: AsyncRead + AsyncWrite + Unpin,
@ -171,7 +181,10 @@ where
ws.send(msg).await.map_err(LuaError::external) ws.send(msg).await.map_err(LuaError::external)
} }
async fn next<T>(lua: &Lua, socket: NetWebSocket<T>) -> LuaResult<LuaValue> async fn next<'lua, T>(
lua: &'lua Lua,
socket: LuaUserDataRef<'lua, NetWebSocket<T>>,
) -> LuaResult<LuaValue<'lua>>
where where
T: AsyncRead + AsyncWrite + Unpin, T: AsyncRead + AsyncWrite + Unpin,
{ {
@ -188,8 +201,8 @@ where
}?; }?;
while let Some(msg) = &msg { while let Some(msg) = &msg {
let msg_string_opt = match msg { let msg_string_opt = match msg {
WsMessage::Binary(bin) => Some(lua.create_string(&bin)?), WsMessage::Binary(bin) => Some(lua.create_string(bin)?),
WsMessage::Text(txt) => Some(lua.create_string(&txt)?), WsMessage::Text(txt) => Some(lua.create_string(txt)?),
// Stop waiting for next message if we get a close message // Stop waiting for next message if we get a close message
WsMessage::Close(_) => return Ok(LuaValue::Nil), WsMessage::Close(_) => return Ok(LuaValue::Nil),
// Ignore ping/pong/frame messages, they are handled by tungstenite // Ignore ping/pong/frame messages, they are handled by tungstenite

View file

@ -70,7 +70,7 @@ impl EncodeDecodeConfig {
s.as_bytes().to_vec() s.as_bytes().to_vec()
} }
}; };
lua.create_string(&bytes) lua.create_string(bytes)
} }
pub fn deserialize_from_string<'lua>( pub fn deserialize_from_string<'lua>(

View file

@ -286,7 +286,7 @@ pub fn pretty_format_luau_error(e: &LuaError, colorized: bool) -> String {
let msg = message let msg = message
.clone() .clone()
.map_or_else(String::new, |m| format!("\nDetails:\n\t{m}")); .map_or_else(String::new, |m| format!("\nDetails:\n\t{m}"));
format!("Failed to convert Luau type '{from}' into Rust type '{to}'!{msg}") format!("Expected argument of type '{to}', got '{from}'!{msg}")
} }
e => format!("{e}"), e => format!("{e}"),
}; };
@ -455,7 +455,7 @@ fn call_table_tostring_metamethod<'a>(tab: &'a LuaTable<'a>) -> Option<String> {
fn call_userdata_tostring_metamethod<'a>(tab: &'a LuaAnyUserData<'a>) -> Option<String> { fn call_userdata_tostring_metamethod<'a>(tab: &'a LuaAnyUserData<'a>) -> Option<String> {
let f = match tab.get_metatable() { let f = match tab.get_metatable() {
Err(_) => None, Err(_) => None,
Ok(meta) => match meta.get::<_, LuaFunction>(LuaMetaMethod::ToString.name()) { Ok(meta) => match meta.get::<LuaFunction>(LuaMetaMethod::ToString.name()) {
Ok(method) => Some(method), Ok(method) => Some(method),
Err(_) => None, Err(_) => None,
}, },

View file

@ -179,13 +179,13 @@ pub enum PromptResult {
None, None,
} }
impl<'lua> ToLua<'lua> for PromptResult { impl<'lua> IntoLua<'lua> for PromptResult {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(match self { Ok(match self {
Self::String(s) => LuaValue::String(lua.create_string(&s)?), Self::String(s) => LuaValue::String(lua.create_string(&s)?),
Self::Boolean(b) => LuaValue::Boolean(b), Self::Boolean(b) => LuaValue::Boolean(b),
Self::Index(i) => LuaValue::Number(i as f64), Self::Index(i) => LuaValue::Number(i as f64),
Self::Indices(v) => v.to_lua(lua)?, Self::Indices(v) => v.into_lua(lua)?,
Self::None => LuaValue::Nil, Self::None => LuaValue::Nil,
}) })
} }

View file

@ -18,8 +18,8 @@ impl TableBuilder {
pub fn with_value<K, V>(self, key: K, value: V) -> LuaResult<Self> pub fn with_value<K, V>(self, key: K, value: V) -> LuaResult<Self>
where where
K: ToLua<'static>, K: IntoLua<'static>,
V: ToLua<'static>, V: IntoLua<'static>,
{ {
self.tab.raw_set(key, value)?; self.tab.raw_set(key, value)?;
Ok(self) Ok(self)
@ -27,8 +27,8 @@ impl TableBuilder {
pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> LuaResult<Self> pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> LuaResult<Self>
where where
K: ToLua<'static>, K: IntoLua<'static>,
V: ToLua<'static>, V: IntoLua<'static>,
{ {
for (key, value) in values { for (key, value) in values {
self.tab.raw_set(key, value)?; self.tab.raw_set(key, value)?;
@ -38,7 +38,7 @@ impl TableBuilder {
pub fn with_sequential_value<V>(self, value: V) -> LuaResult<Self> pub fn with_sequential_value<V>(self, value: V) -> LuaResult<Self>
where where
V: ToLua<'static>, V: IntoLua<'static>,
{ {
self.tab.raw_push(value)?; self.tab.raw_push(value)?;
Ok(self) Ok(self)
@ -46,7 +46,7 @@ impl TableBuilder {
pub fn with_sequential_values<V>(self, values: Vec<V>) -> LuaResult<Self> pub fn with_sequential_values<V>(self, values: Vec<V>) -> LuaResult<Self>
where where
V: ToLua<'static>, V: IntoLua<'static>,
{ {
for value in values { for value in values {
self.tab.raw_push(value)?; self.tab.raw_push(value)?;
@ -61,9 +61,9 @@ impl TableBuilder {
pub fn with_function<K, A, R, F>(self, key: K, func: F) -> LuaResult<Self> pub fn with_function<K, A, R, F>(self, key: K, func: F) -> LuaResult<Self>
where where
K: ToLua<'static>, K: IntoLua<'static>,
A: FromLuaMulti<'static>, A: FromLuaMulti<'static>,
R: ToLuaMulti<'static>, R: IntoLuaMulti<'static>,
F: 'static + Fn(&'static Lua, A) -> LuaResult<R>, F: 'static + Fn(&'static Lua, A) -> LuaResult<R>,
{ {
let f = self.lua.create_function(func)?; let f = self.lua.create_function(func)?;
@ -72,9 +72,9 @@ impl TableBuilder {
pub fn with_async_function<K, A, R, F, FR>(self, key: K, func: F) -> LuaResult<Self> pub fn with_async_function<K, A, R, F, FR>(self, key: K, func: F) -> LuaResult<Self>
where where
K: ToLua<'static>, K: IntoLua<'static>,
A: FromLuaMulti<'static>, A: FromLuaMulti<'static>,
R: ToLuaMulti<'static>, R: IntoLuaMulti<'static>,
F: 'static + Fn(&'static Lua, A) -> FR, F: 'static + Fn(&'static Lua, A) -> FR,
FR: 'static + Future<Output = LuaResult<R>>, FR: 'static + Future<Output = LuaResult<R>>,
{ {

View file

@ -32,7 +32,7 @@ pub trait TaskSchedulerAsyncExt<'fut> {
) -> LuaResult<TaskReference> ) -> LuaResult<TaskReference>
where where
'sched: 'fut, 'sched: 'fut,
R: ToLuaMulti<'static>, R: IntoLuaMulti<'static>,
F: 'static + Fn(&'static Lua) -> FR, F: 'static + Fn(&'static Lua) -> FR,
FR: 'static + Future<Output = LuaResult<R>>; FR: 'static + Future<Output = LuaResult<R>>;
@ -89,13 +89,13 @@ impl<'fut> TaskSchedulerAsyncExt<'fut> for TaskScheduler<'fut> {
) -> LuaResult<TaskReference> ) -> LuaResult<TaskReference>
where where
'sched: 'fut, // Scheduler must live at least as long as the future 'sched: 'fut, // Scheduler must live at least as long as the future
R: ToLuaMulti<'static>, R: IntoLuaMulti<'static>,
F: 'static + Fn(&'static Lua) -> FR, F: 'static + Fn(&'static Lua) -> FR,
FR: 'static + Future<Output = LuaResult<R>>, FR: 'static + Future<Output = LuaResult<R>>,
{ {
self.queue_async_task(thread, None, async move { self.queue_async_task(thread, None, async move {
match func(self.lua).await { match func(self.lua).await {
Ok(res) => match res.to_lua_multi(self.lua) { Ok(res) => match res.into_lua_multi(self.lua) {
Ok(multi) => Ok(Some(multi)), Ok(multi) => Ok(Some(multi)),
Err(e) => Err(e), Err(e) => Err(e),
}, },
@ -127,7 +127,7 @@ impl<'fut> TaskSchedulerAsyncExt<'fut> for TaskScheduler<'fut> {
)) ))
.await; .await;
let elapsed_secs = before.elapsed().as_secs_f64(); let elapsed_secs = before.elapsed().as_secs_f64();
let args = elapsed_secs.to_lua_multi(self.lua).unwrap(); let args = elapsed_secs.into_lua_multi(self.lua).unwrap();
(Some(reference), Ok(Some(args))) (Some(reference), Ok(Some(args)))
})); }));
Ok(reference) Ok(reference)

View file

@ -50,8 +50,8 @@ impl<'lua> FromLua<'lua> for LuaThreadOrFunction<'lua> {
} }
} }
impl<'lua> ToLua<'lua> for LuaThreadOrFunction<'lua> { impl<'lua> IntoLua<'lua> for LuaThreadOrFunction<'lua> {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match self { match self {
Self::Thread(t) => Ok(LuaValue::Thread(t)), Self::Thread(t) => Ok(LuaValue::Thread(t)),
Self::Function(f) => Ok(LuaValue::Function(f)), Self::Function(f) => Ok(LuaValue::Function(f)),
@ -87,8 +87,10 @@ impl<'lua> FromLua<'lua> for LuaThreadOrTaskReference<'lua> {
match value { match value {
LuaValue::Thread(t) => Ok(Self::Thread(t)), LuaValue::Thread(t) => Ok(Self::Thread(t)),
LuaValue::UserData(u) => { LuaValue::UserData(u) => {
if let Ok(task) = TaskReference::from_lua(LuaValue::UserData(u), lua) { if let Ok(task) =
Ok(Self::TaskReference(task)) LuaUserDataRef::<TaskReference>::from_lua(LuaValue::UserData(u), lua)
{
Ok(Self::TaskReference(*task))
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: tname, from: tname,
@ -106,10 +108,10 @@ impl<'lua> FromLua<'lua> for LuaThreadOrTaskReference<'lua> {
} }
} }
impl<'lua> ToLua<'lua> for LuaThreadOrTaskReference<'lua> { impl<'lua> IntoLua<'lua> for LuaThreadOrTaskReference<'lua> {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match self { match self {
Self::TaskReference(t) => t.to_lua(lua), Self::TaskReference(t) => t.into_lua(lua),
Self::Thread(t) => Ok(LuaValue::Thread(t)), Self::Thread(t) => Ok(LuaValue::Thread(t)),
} }
} }

View file

@ -70,12 +70,12 @@ impl<'fut> TaskScheduler<'fut> {
let (tx, rx) = mpsc::unbounded_channel(); let (tx, rx) = mpsc::unbounded_channel();
let tasks_current_lua_error = Arc::new(AsyncMutex::new(None)); let tasks_current_lua_error = Arc::new(AsyncMutex::new(None));
let tasks_current_lua_error_inner = tasks_current_lua_error.clone(); let tasks_current_lua_error_inner = tasks_current_lua_error.clone();
lua.set_interrupt( lua.set_interrupt(move |_| {
move || match tasks_current_lua_error_inner.try_lock().unwrap().take() { match tasks_current_lua_error_inner.try_lock().unwrap().take() {
Some(err) => Err(err), Some(err) => Err(err),
None => Ok(LuaVmState::Continue), None => Ok(LuaVmState::Continue),
}, }
); });
Ok(Self { Ok(Self {
lua, lua,
guid: Cell::new(0), guid: Cell::new(0),