mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Implement Rect roblox datatype
This commit is contained in:
parent
75188d3e35
commit
72f3e2157b
6 changed files with 167 additions and 2 deletions
|
@ -127,7 +127,6 @@ impl<'lua> RbxVariantToLua<'lua> for LuaAnyUserData<'lua> {
|
|||
// Rbx::OptionalCFrame(_) => todo!(),
|
||||
// Rbx::PhysicalProperties(_) => todo!(),
|
||||
// Rbx::Ray(_) => todo!(),
|
||||
// Rbx::Rect(_) => todo!(),
|
||||
// Rbx::Region3(_) => todo!(),
|
||||
// Rbx::Region3int16(_) => todo!(),
|
||||
|
||||
|
@ -139,6 +138,7 @@ impl<'lua> RbxVariantToLua<'lua> for LuaAnyUserData<'lua> {
|
|||
Rbx::Color3uint8(value) => lua.create_userdata(Color3::from(value))?,
|
||||
Rbx::ColorSequence(value) => lua.create_userdata(ColorSequence::from(value))?,
|
||||
|
||||
Rbx::Rect(value) => lua.create_userdata(Rect::from(value))?,
|
||||
Rbx::UDim(value) => lua.create_userdata(UDim::from(value))?,
|
||||
Rbx::UDim2(value) => lua.create_userdata(UDim2::from(value))?,
|
||||
|
||||
|
@ -179,6 +179,7 @@ impl<'lua> LuaToRbxVariant<'lua> for LuaAnyUserData<'lua> {
|
|||
|
||||
RbxVariantType::Enum => convert::<EnumItem, rbx::Enum>,
|
||||
|
||||
RbxVariantType::Rect => convert::<Rect, rbx::Rect>,
|
||||
RbxVariantType::UDim => convert::<UDim, rbx::UDim>,
|
||||
RbxVariantType::UDim2 => convert::<UDim2, rbx::UDim2>,
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ mod r#enum;
|
|||
mod r#enum_item;
|
||||
mod r#enums;
|
||||
mod faces;
|
||||
mod rect;
|
||||
mod udim;
|
||||
mod udim2;
|
||||
mod vector2;
|
||||
|
@ -23,6 +24,7 @@ pub use faces::Faces;
|
|||
pub use r#enum::Enum;
|
||||
pub use r#enum_item::EnumItem;
|
||||
pub use r#enums::Enums;
|
||||
pub use rect::Rect;
|
||||
pub use udim::UDim;
|
||||
pub use udim2::UDim2;
|
||||
pub use vector2::Vector2;
|
||||
|
@ -79,6 +81,7 @@ mod tests {
|
|||
color_sequence_keypoint: "datatypes/ColorSequenceKeypoint",
|
||||
r#enum: "datatypes/Enum",
|
||||
faces: "datatypes/Faces",
|
||||
rect: "datatypes/Rect",
|
||||
udim: "datatypes/UDim",
|
||||
udim2: "datatypes/UDim2",
|
||||
vector2: "datatypes/Vector2",
|
||||
|
|
118
packages/lib-roblox/src/datatypes/types/rect.rs
Normal file
118
packages/lib-roblox/src/datatypes/types/rect.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
use core::fmt;
|
||||
use std::ops;
|
||||
|
||||
use glam::Vec2;
|
||||
use mlua::prelude::*;
|
||||
use rbx_dom_weak::types::Rect as RbxRect;
|
||||
|
||||
use super::{super::*, Vector2};
|
||||
|
||||
/**
|
||||
An implementation of the [Rect](https://create.roblox.com/docs/reference/engine/datatypes/Rect)
|
||||
Roblox datatype, backed by [`glam::Vec2`].
|
||||
|
||||
This implements all documented properties, methods & constructors of the Rect class as of March 2023.
|
||||
*/
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Rect {
|
||||
pub(crate) min: Vec2,
|
||||
pub(crate) max: Vec2,
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
fn new(lhs: Vec2, rhs: Vec2) -> Self {
|
||||
Self {
|
||||
min: lhs.min(rhs),
|
||||
max: lhs.max(rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
|
||||
type ArgsVector2s = (Option<Vector2>, Option<Vector2>);
|
||||
type ArgsNums = (Option<f32>, Option<f32>, Option<f32>, Option<f32>);
|
||||
datatype_table.set(
|
||||
"new",
|
||||
lua.create_function(|lua, args: LuaMultiValue| {
|
||||
if let Ok((min, max)) = ArgsVector2s::from_lua_multi(args.clone(), lua) {
|
||||
Ok(Rect::new(
|
||||
min.unwrap_or_default().0,
|
||||
max.unwrap_or_default().0,
|
||||
))
|
||||
} 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 max = Vec2::new(x1.unwrap_or_default(), y1.unwrap_or_default());
|
||||
Ok(Rect::new(min, max))
|
||||
} else {
|
||||
// FUTURE: Better error message here using given arg types
|
||||
Err(LuaError::RuntimeError(
|
||||
"Invalid arguments to constructor".to_string(),
|
||||
))
|
||||
}
|
||||
})?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl LuaUserData for Rect {
|
||||
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("Min", |_, this| Ok(Vector2(this.min)));
|
||||
fields.add_field_method_get("Max", |_, this| Ok(Vector2(this.max)));
|
||||
fields.add_field_method_get("Width", |_, this| Ok(this.max.x - this.min.x));
|
||||
fields.add_field_method_get("Height", |_, this| Ok(this.max.y - this.min.y));
|
||||
}
|
||||
|
||||
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);
|
||||
methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm);
|
||||
methods.add_meta_method(LuaMetaMethod::Add, userdata_impl_add);
|
||||
methods.add_meta_method(LuaMetaMethod::Sub, userdata_impl_sub);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Rect {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}, {}", self.min, self.max)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Neg for Rect {
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self::Output {
|
||||
Rect::new(-self.min, -self.max)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Add for Rect {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Rect::new(self.min + rhs.min, self.max + rhs.max)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Sub for Rect {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Rect::new(self.min - rhs.min, self.max - rhs.max)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RbxRect> for Rect {
|
||||
fn from(v: RbxRect) -> Self {
|
||||
Rect {
|
||||
min: Vec2::new(v.min.x, v.min.y),
|
||||
max: Vec2::new(v.max.x, v.max.y),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rect> for RbxRect {
|
||||
fn from(v: Rect) -> Self {
|
||||
RbxRect {
|
||||
min: Vector2(v.min).into(),
|
||||
max: Vector2(v.max).into(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ use super::super::*;
|
|||
This implements all documented properties, methods &
|
||||
constructors of the Vector2 class as of March 2023.
|
||||
*/
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
pub struct Vector2(pub Vec2);
|
||||
|
||||
impl Vector2 {
|
||||
|
|
|
@ -25,6 +25,7 @@ fn make_all_datatypes(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
|
|||
("ColorSequence", make_dt(lua, ColorSequence::make_table)?),
|
||||
("ColorSequenceKeypoint", make_dt(lua, ColorSequenceKeypoint::make_table)?),
|
||||
("Faces", make_dt(lua, Faces::make_table)?),
|
||||
("Rect", make_dt(lua, Rect::make_table)?),
|
||||
("UDim", make_dt(lua, UDim::make_table)?),
|
||||
("UDim2", make_dt(lua, UDim2::make_table)?),
|
||||
("Vector2", make_dt(lua, Vector2::make_table)?),
|
||||
|
|
42
tests/roblox/datatypes/Rect.luau
Normal file
42
tests/roblox/datatypes/Rect.luau
Normal file
|
@ -0,0 +1,42 @@
|
|||
-- HACK: Make luau happy, with the mlua rust
|
||||
-- crate all globals are also present in _G
|
||||
local Vector2 = _G.Vector2
|
||||
local Rect = _G.Rect
|
||||
|
||||
-- Constructors & properties
|
||||
|
||||
Rect.new()
|
||||
Rect.new(0)
|
||||
Rect.new(0, 0)
|
||||
Rect.new(0, 0, 0)
|
||||
Rect.new(0, 0, 0, 0)
|
||||
Rect.new(0 / 0, 0, 0 / 0, 0)
|
||||
|
||||
Rect.new(Vector2.zero)
|
||||
Rect.new(Vector2.zero, Vector2.zero)
|
||||
|
||||
assert(not pcall(function()
|
||||
return Rect.new(false)
|
||||
end))
|
||||
assert(not pcall(function()
|
||||
return Rect.new("", "")
|
||||
end))
|
||||
assert(not pcall(function()
|
||||
return Rect.new(newproxy(true))
|
||||
end))
|
||||
|
||||
assert(Rect.new(1, 0, 2, 4).Min == Vector2.new(1, 0))
|
||||
assert(Rect.new(1, 0, 2, 4).Max == Vector2.new(2, 4))
|
||||
assert(Rect.new(0, 0, 1, 2).Width == 1)
|
||||
assert(Rect.new(0, 0, 1, 2).Height == 2)
|
||||
|
||||
assert(Rect.new(Vector2.new(1, 0), Vector2.new(2, 4)).Min == Vector2.new(1, 0))
|
||||
assert(Rect.new(Vector2.new(1, 0), Vector2.new(2, 4)).Max == Vector2.new(2, 4))
|
||||
assert(Rect.new(Vector2.new(1, 0), Vector2.new(2, 4)).Width == 1)
|
||||
assert(Rect.new(Vector2.new(1, 0), Vector2.new(2, 4)).Height == 4)
|
||||
|
||||
-- Ops
|
||||
|
||||
assert(Rect.new(2, 4, 6, 8) + Rect.new(1, 1, 1, 1) == Rect.new(3, 5, 7, 9))
|
||||
assert(Rect.new(2, 4, 6, 8) - -Rect.new(1, 1, 1, 1) == Rect.new(3, 5, 7, 9))
|
||||
assert(Rect.new(2, 4, 6, 8) - Rect.new(1, 1, 1, 1) == Rect.new(1, 3, 5, 7))
|
Loading…
Reference in a new issue