mirror of
https://github.com/lune-org/lune.git
synced 2024-12-13 13:30:38 +00:00
Implement Axes roblox datatype
This commit is contained in:
parent
7aef25c316
commit
cfc9299165
5 changed files with 188 additions and 4 deletions
|
@ -116,11 +116,12 @@ impl<'lua> RbxVariantToLua<'lua> for LuaAnyUserData<'lua> {
|
|||
use super::types::*;
|
||||
use RbxVariant as Rbx;
|
||||
|
||||
// NOTE: Enum is intentionally left out here, it has a custom
|
||||
// conversion going from instance property > datatype instead,
|
||||
// check `EnumItem::from_instance_property` for specifics
|
||||
Ok(match variant.clone() {
|
||||
// Not yet implemented datatypes
|
||||
// Rbx::Axes(_) => todo!(),
|
||||
// Rbx::CFrame(_) => todo!(),
|
||||
// Rbx::Enum(_) => todo!(),
|
||||
// Rbx::Faces(_) => todo!(),
|
||||
// Rbx::NumberRange(_) => todo!(),
|
||||
// Rbx::NumberSequence(_) => todo!(),
|
||||
|
@ -131,8 +132,9 @@ impl<'lua> RbxVariantToLua<'lua> for LuaAnyUserData<'lua> {
|
|||
// Rbx::Region3(_) => todo!(),
|
||||
// Rbx::Region3int16(_) => todo!(),
|
||||
|
||||
Rbx::BrickColor(value) => lua.create_userdata(BrickColor::from(value))?,
|
||||
Rbx::Axes(value) => lua.create_userdata(Axes::from(value))?,
|
||||
|
||||
Rbx::BrickColor(value) => lua.create_userdata(BrickColor::from(value))?,
|
||||
Rbx::Color3(value) => lua.create_userdata(Color3::from(value))?,
|
||||
Rbx::Color3uint8(value) => lua.create_userdata(Color3::from(value))?,
|
||||
Rbx::ColorSequence(value) => lua.create_userdata(ColorSequence::from(value))?,
|
||||
|
@ -167,8 +169,9 @@ impl<'lua> LuaToRbxVariant<'lua> for LuaAnyUserData<'lua> {
|
|||
use rbx_dom_weak::types as rbx;
|
||||
|
||||
let f = match variant_type {
|
||||
RbxVariantType::BrickColor => convert::<BrickColor, rbx::BrickColor>,
|
||||
RbxVariantType::Axes => convert::<Axes, rbx::Axes>,
|
||||
|
||||
RbxVariantType::BrickColor => convert::<BrickColor, rbx::BrickColor>,
|
||||
RbxVariantType::Color3 => convert::<Color3, rbx::Color3>,
|
||||
RbxVariantType::Color3uint8 => convert::<Color3, rbx::Color3uint8>,
|
||||
RbxVariantType::ColorSequence => convert::<ColorSequence, rbx::ColorSequence>,
|
||||
|
|
133
packages/lib-roblox/src/datatypes/types/axes.rs
Normal file
133
packages/lib-roblox/src/datatypes/types/axes.rs
Normal file
|
@ -0,0 +1,133 @@
|
|||
use core::fmt;
|
||||
|
||||
use mlua::prelude::*;
|
||||
use rbx_dom_weak::types::Axes as RbxAxes;
|
||||
|
||||
use super::{super::*, EnumItem};
|
||||
|
||||
/**
|
||||
An implementation of the [Axes](https://create.roblox.com/docs/reference/engine/datatypes/Axes) Roblox datatype.
|
||||
|
||||
This implements all documented properties, methods & constructors of the Axes class as of March 2023.
|
||||
*/
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Axes {
|
||||
pub(crate) x: bool,
|
||||
pub(crate) y: bool,
|
||||
pub(crate) z: bool,
|
||||
}
|
||||
|
||||
impl Axes {
|
||||
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
|
||||
datatype_table.set(
|
||||
"new",
|
||||
lua.create_function(|_, args: LuaMultiValue| {
|
||||
let mut x = false;
|
||||
let mut y = false;
|
||||
let mut z = false;
|
||||
let mut check = |e: &EnumItem| {
|
||||
if e.parent.desc.name == "Axis" {
|
||||
match &e.name {
|
||||
name if name == "X" => x = true,
|
||||
name if name == "Y" => y = true,
|
||||
name if name == "Z" => z = true,
|
||||
_ => {}
|
||||
}
|
||||
} else if e.parent.desc.name == "NormalId" {
|
||||
match &e.name {
|
||||
name if name == "Left" || name == "Right" => x = true,
|
||||
name if name == "Top" || name == "Bottom" => y = true,
|
||||
name if name == "Front" || name == "Back" => z = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
};
|
||||
for (index, arg) in args.into_iter().enumerate() {
|
||||
if let LuaValue::UserData(u) = arg {
|
||||
if let Ok(e) = u.borrow::<EnumItem>() {
|
||||
check(&e);
|
||||
} else {
|
||||
return Err(LuaError::RuntimeError(format!(
|
||||
"Expected argument #{} to be an EnumItem, got userdata",
|
||||
index
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
return Err(LuaError::RuntimeError(format!(
|
||||
"Expected argument #{} to be an EnumItem, got {}",
|
||||
index,
|
||||
arg.type_name()
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(Axes { x, y, z })
|
||||
})?,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl LuaUserData for Axes {
|
||||
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("X", |_, this| Ok(this.x));
|
||||
fields.add_field_method_get("Y", |_, this| Ok(this.y));
|
||||
fields.add_field_method_get("Z", |_, this| Ok(this.z));
|
||||
fields.add_field_method_get("Left", |_, this| Ok(this.x));
|
||||
fields.add_field_method_get("Right", |_, this| Ok(this.x));
|
||||
fields.add_field_method_get("Top", |_, this| Ok(this.y));
|
||||
fields.add_field_method_get("Bottom", |_, this| Ok(this.y));
|
||||
fields.add_field_method_get("Front", |_, this| Ok(this.z));
|
||||
fields.add_field_method_get("Back", |_, this| Ok(this.z));
|
||||
}
|
||||
|
||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
|
||||
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Axes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut got_value = false;
|
||||
if self.x {
|
||||
write!(f, "X")?;
|
||||
got_value = true;
|
||||
}
|
||||
if self.y {
|
||||
if got_value {
|
||||
write!(f, ", Y")?;
|
||||
} else {
|
||||
write!(f, "Y")?;
|
||||
got_value = true;
|
||||
}
|
||||
}
|
||||
if self.z {
|
||||
if got_value {
|
||||
write!(f, ", Z")?;
|
||||
} else {
|
||||
write!(f, "Z")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RbxAxes> for Axes {
|
||||
fn from(v: RbxAxes) -> Self {
|
||||
let bits = v.bits();
|
||||
let x = (bits & 1) == 1;
|
||||
let y = ((bits >> 1) & 1) == 1;
|
||||
let z = ((bits >> 2) & 1) == 1;
|
||||
Self { x, y, z }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Axes> for RbxAxes {
|
||||
fn from(v: Axes) -> Self {
|
||||
let mut bits = 0;
|
||||
bits += v.x as u8;
|
||||
bits += (v.y as u8) << 1;
|
||||
bits += (v.z as u8) << 2;
|
||||
RbxAxes::from_bits(bits).expect("Invalid bits")
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
mod axes;
|
||||
mod brick_color;
|
||||
mod color3;
|
||||
mod color_sequence;
|
||||
|
@ -12,6 +13,7 @@ mod vector2int16;
|
|||
mod vector3;
|
||||
mod vector3int16;
|
||||
|
||||
pub use axes::Axes;
|
||||
pub use brick_color::BrickColor;
|
||||
pub use color3::Color3;
|
||||
pub use color_sequence::ColorSequence;
|
||||
|
@ -68,6 +70,7 @@ mod tests {
|
|||
}
|
||||
|
||||
create_tests! {
|
||||
axes: "datatypes/Axes",
|
||||
brick_color: "datatypes/BrickColor",
|
||||
color3: "datatypes/Color3",
|
||||
color_sequence: "datatypes/ColorSequence",
|
||||
|
|
|
@ -19,6 +19,7 @@ fn make_all_datatypes(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
|
|||
use datatypes::types::*;
|
||||
Ok(vec![
|
||||
// Classes
|
||||
("Axes", make_dt(lua, Axes::make_table)?),
|
||||
("BrickColor", make_dt(lua, BrickColor::make_table)?),
|
||||
("Color3", make_dt(lua, Color3::make_table)?),
|
||||
("ColorSequence", make_dt(lua, ColorSequence::make_table)?),
|
||||
|
|
44
tests/roblox/datatypes/Axes.luau
Normal file
44
tests/roblox/datatypes/Axes.luau
Normal file
|
@ -0,0 +1,44 @@
|
|||
-- HACK: Make luau happy, with the mlua rust
|
||||
-- crate all globals are also present in _G
|
||||
local Axes = _G.Axes
|
||||
local Enum = _G.Enum
|
||||
|
||||
-- Constructors & properties
|
||||
|
||||
Axes.new()
|
||||
Axes.new(Enum.Axis.X)
|
||||
Axes.new(Enum.Axis.X, Enum.NormalId.Top)
|
||||
|
||||
assert(not pcall(function()
|
||||
return Axes.new(false)
|
||||
end))
|
||||
assert(not pcall(function()
|
||||
return Axes.new({})
|
||||
end))
|
||||
assert(not pcall(function()
|
||||
return Axes.new(newproxy(true))
|
||||
end))
|
||||
|
||||
assert(Axes.new().X == false)
|
||||
assert(Axes.new().Y == false)
|
||||
assert(Axes.new().Z == false)
|
||||
|
||||
assert(Axes.new(Enum.Axis.X, Enum.NormalId.Top).X == true)
|
||||
assert(Axes.new(Enum.Axis.X, Enum.NormalId.Top).Y == true)
|
||||
assert(Axes.new(Enum.Axis.X, Enum.NormalId.Top).Z == false)
|
||||
|
||||
assert(Axes.new(Enum.Axis.X, Enum.NormalId.Left).X == true)
|
||||
assert(Axes.new(Enum.Axis.X, Enum.NormalId.Right).X == true)
|
||||
|
||||
assert(Axes.new(Enum.NormalId.Front, Enum.NormalId.Back).X == false)
|
||||
assert(Axes.new(Enum.NormalId.Front, Enum.NormalId.Back).Y == false)
|
||||
assert(Axes.new(Enum.NormalId.Front, Enum.NormalId.Back).Z == true)
|
||||
|
||||
-- Ops
|
||||
|
||||
assert(not pcall(function()
|
||||
return Axes.new() + Axes.new()
|
||||
end))
|
||||
assert(not pcall(function()
|
||||
return Axes.new() / Axes.new()
|
||||
end))
|
Loading…
Reference in a new issue