From 89aaf40fdb0e74e6295fef64a8f6a58b738b516b Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sat, 11 Mar 2023 18:38:27 +0100 Subject: [PATCH] Implement std ops for roblox datatypes --- packages/lib-roblox/src/datatypes/shared.rs | 23 ++++++ .../lib-roblox/src/datatypes/types/udim.rs | 30 ++++---- .../lib-roblox/src/datatypes/types/udim2.rs | 77 ++++++++++--------- .../lib-roblox/src/datatypes/types/vector2.rs | 44 +++++++---- .../src/datatypes/types/vector2int16.rs | 44 +++++++---- .../lib-roblox/src/datatypes/types/vector3.rs | 44 +++++++---- .../src/datatypes/types/vector3int16.rs | 44 +++++++---- 7 files changed, 202 insertions(+), 104 deletions(-) diff --git a/packages/lib-roblox/src/datatypes/shared.rs b/packages/lib-roblox/src/datatypes/shared.rs index ae95b09..10b5070 100644 --- a/packages/lib-roblox/src/datatypes/shared.rs +++ b/packages/lib-roblox/src/datatypes/shared.rs @@ -1,3 +1,5 @@ +use std::ops; + use mlua::prelude::*; pub(super) fn userdata_impl_to_string(_: &Lua, datatype: &D, _: ()) -> LuaResult @@ -21,3 +23,24 @@ where Ok(false) } } + +pub(super) fn userdata_impl_unm(_: &Lua, datatype: &D, _: ()) -> LuaResult +where + D: LuaUserData + ops::Neg + Copy, +{ + Ok(-*datatype) +} + +pub(super) fn userdata_impl_add(_: &Lua, datatype: &D, value: D) -> LuaResult +where + D: LuaUserData + ops::Add + Copy, +{ + Ok(*datatype + value) +} + +pub(super) fn userdata_impl_sub(_: &Lua, datatype: &D, value: D) -> LuaResult +where + D: LuaUserData + ops::Sub + Copy, +{ + Ok(*datatype - value) +} diff --git a/packages/lib-roblox/src/datatypes/types/udim.rs b/packages/lib-roblox/src/datatypes/types/udim.rs index 0bd79f3..5259621 100644 --- a/packages/lib-roblox/src/datatypes/types/udim.rs +++ b/packages/lib-roblox/src/datatypes/types/udim.rs @@ -31,6 +31,21 @@ impl UDim { } } +impl LuaUserData for UDim { + fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_method_get("Scale", |_, this| Ok(this.scale)); + fields.add_field_method_get("Offset", |_, this| Ok(this.offset)); + } + + 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 Default for UDim { fn default() -> Self { Self { @@ -76,21 +91,6 @@ impl ops::Sub for UDim { } } -impl LuaUserData for UDim { - fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { - fields.add_field_method_get("Scale", |_, this| Ok(this.scale)); - fields.add_field_method_get("Offset", |_, this| Ok(this.offset)); - } - - 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, |_, this, ()| Ok(-*this)); - methods.add_meta_method(LuaMetaMethod::Add, |_, this, rhs: UDim| Ok(*this + rhs)); - methods.add_meta_method(LuaMetaMethod::Sub, |_, this, rhs: UDim| Ok(*this - rhs)); - } -} - impl From<&RbxUDim> for UDim { fn from(v: &RbxUDim) -> Self { UDim { diff --git a/packages/lib-roblox/src/datatypes/types/udim2.rs b/packages/lib-roblox/src/datatypes/types/udim2.rs index d2231f1..51fd085 100644 --- a/packages/lib-roblox/src/datatypes/types/udim2.rs +++ b/packages/lib-roblox/src/datatypes/types/udim2.rs @@ -82,6 +82,46 @@ impl UDim2 { } } +impl LuaUserData for UDim2 { + 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("Width", |_, this| Ok(this.x)); + fields.add_field_method_get("Height", |_, this| Ok(this.y)); + } + + fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + // Methods + methods.add_method("Lerp", |_, this, (goal, alpha): (UDim2, f32)| { + let this_x = Vec2::new(this.x.scale, this.x.offset as f32); + let goal_x = Vec2::new(goal.x.scale, this.x.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 x = this_x.lerp(goal_x, alpha); + let y = this_y.lerp(goal_y, alpha); + + Ok(UDim2 { + x: UDim { + scale: x.x, + offset: x.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32, + }, + y: UDim { + scale: y.x, + offset: y.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32, + }, + }) + }); + // Metamethods + 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 UDim2 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}, {}", self.x, self.y) @@ -118,43 +158,6 @@ impl ops::Sub for UDim2 { } } -impl LuaUserData for UDim2 { - 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("Width", |_, this| Ok(this.x)); - fields.add_field_method_get("Height", |_, this| Ok(this.y)); - } - - fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - // Methods - methods.add_method("Lerp", |_, this, (rhs, alpha): (UDim2, f32)| { - let this_vec_x = Vec2::new(this.x.scale, this.x.offset as f32); - let this_vec_y = Vec2::new(this.y.scale, this.y.offset as f32); - let rhs_vec_x = Vec2::new(rhs.x.scale, rhs.x.offset as f32); - let rhs_vec_y = Vec2::new(rhs.y.scale, rhs.y.offset as f32); - let result_x = this_vec_x.lerp(rhs_vec_x, alpha); - let result_y = this_vec_y.lerp(rhs_vec_y, alpha); - Ok(UDim2 { - x: UDim { - scale: result_x.x, - offset: result_x.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32, - }, - y: UDim { - scale: result_y.x, - offset: result_y.y.clamp(i32::MIN as f32, i32::MAX as f32).round() as i32, - }, - }) - }); - // Metamethods - 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, |_, this, ()| Ok(-*this)); - methods.add_meta_method(LuaMetaMethod::Add, |_, this, rhs: UDim2| Ok(*this + rhs)); - methods.add_meta_method(LuaMetaMethod::Sub, |_, this, rhs: UDim2| Ok(*this - rhs)); - } -} - impl From<&RbxUDim2> for UDim2 { fn from(v: &RbxUDim2) -> Self { UDim2 { diff --git a/packages/lib-roblox/src/datatypes/types/vector2.rs b/packages/lib-roblox/src/datatypes/types/vector2.rs index 34047f6..fdd4b69 100644 --- a/packages/lib-roblox/src/datatypes/types/vector2.rs +++ b/packages/lib-roblox/src/datatypes/types/vector2.rs @@ -1,4 +1,5 @@ use core::fmt; +use std::ops; use glam::{Vec2, Vec3}; use mlua::prelude::*; @@ -36,12 +37,6 @@ impl Vector2 { } } -impl fmt::Display for Vector2 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}, {}", self.0.x, self.0.y) - } -} - impl LuaUserData for Vector2 { fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_method_get("Magnitude", |_, this| Ok(this.0.length())); @@ -70,13 +65,9 @@ impl LuaUserData for Vector2 { // Metamethods 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, |_, this, ()| Ok(Vector2(-this.0))); - methods.add_meta_method(LuaMetaMethod::Add, |_, this, rhs: Vector2| { - Ok(Vector2(this.0 + rhs.0)) - }); - methods.add_meta_method(LuaMetaMethod::Sub, |_, this, rhs: Vector2| { - Ok(Vector2(this.0 - rhs.0)) - }); + 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); methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { match &rhs { LuaValue::Number(n) => return Ok(Vector2(this.0 * Vec2::splat(*n as f32))), @@ -120,6 +111,33 @@ impl LuaUserData for Vector2 { } } +impl fmt::Display for Vector2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}, {}", self.0.x, self.0.y) + } +} + +impl ops::Neg for Vector2 { + type Output = Self; + fn neg(self) -> Self::Output { + Vector2(-self.0) + } +} + +impl ops::Add for Vector2 { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Vector2(self.0 + rhs.0) + } +} + +impl ops::Sub for Vector2 { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + Vector2(self.0 - rhs.0) + } +} + impl From<&RbxVector2> for Vector2 { fn from(v: &RbxVector2) -> Self { Vector2(Vec2 { x: v.x, y: v.y }) diff --git a/packages/lib-roblox/src/datatypes/types/vector2int16.rs b/packages/lib-roblox/src/datatypes/types/vector2int16.rs index 9c5e26c..7bde40d 100644 --- a/packages/lib-roblox/src/datatypes/types/vector2int16.rs +++ b/packages/lib-roblox/src/datatypes/types/vector2int16.rs @@ -1,4 +1,5 @@ use core::fmt; +use std::ops; use glam::IVec2; use mlua::prelude::*; @@ -30,12 +31,6 @@ impl Vector2int16 { } } -impl fmt::Display for Vector2int16 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}, {}", self.0.x, self.0.y) - } -} - impl LuaUserData for Vector2int16 { fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_method_get("X", |_, this| Ok(this.0.x)); @@ -45,13 +40,9 @@ impl LuaUserData for Vector2int16 { 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, |_, this, ()| Ok(Vector2int16(-this.0))); - methods.add_meta_method(LuaMetaMethod::Add, |_, this, rhs: Vector2int16| { - Ok(Vector2int16(this.0 + rhs.0)) - }); - methods.add_meta_method(LuaMetaMethod::Sub, |_, this, rhs: Vector2int16| { - Ok(Vector2int16(this.0 - rhs.0)) - }); + 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); methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { match &rhs { LuaValue::Number(n) => return Ok(Vector2int16(this.0 * IVec2::splat(*n as i32))), @@ -95,6 +86,33 @@ impl LuaUserData for Vector2int16 { } } +impl fmt::Display for Vector2int16 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}, {}", self.0.x, self.0.y) + } +} + +impl ops::Neg for Vector2int16 { + type Output = Self; + fn neg(self) -> Self::Output { + Vector2int16(-self.0) + } +} + +impl ops::Add for Vector2int16 { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Vector2int16(self.0 + rhs.0) + } +} + +impl ops::Sub for Vector2int16 { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + Vector2int16(self.0 - rhs.0) + } +} + impl From<&RbxVector2int16> for Vector2int16 { fn from(v: &RbxVector2int16) -> Self { Vector2int16(IVec2 { diff --git a/packages/lib-roblox/src/datatypes/types/vector3.rs b/packages/lib-roblox/src/datatypes/types/vector3.rs index 1803e88..f8d4fc4 100644 --- a/packages/lib-roblox/src/datatypes/types/vector3.rs +++ b/packages/lib-roblox/src/datatypes/types/vector3.rs @@ -1,4 +1,5 @@ use core::fmt; +use std::ops; use glam::Vec3; use mlua::prelude::*; @@ -42,12 +43,6 @@ impl Vector3 { } } -impl fmt::Display for Vector3 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}, {}, {}", self.0.x, self.0.y, self.0.z) - } -} - impl LuaUserData for Vector3 { fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_method_get("Magnitude", |_, this| Ok(this.0.length())); @@ -84,13 +79,9 @@ impl LuaUserData for Vector3 { // Metamethods 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, |_, this, ()| Ok(Vector3(-this.0))); - methods.add_meta_method(LuaMetaMethod::Add, |_, this, rhs: Vector3| { - Ok(Vector3(this.0 + rhs.0)) - }); - methods.add_meta_method(LuaMetaMethod::Sub, |_, this, rhs: Vector3| { - Ok(Vector3(this.0 - rhs.0)) - }); + 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); methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { match &rhs { LuaValue::Number(n) => return Ok(Vector3(this.0 * Vec3::splat(*n as f32))), @@ -134,6 +125,33 @@ impl LuaUserData for Vector3 { } } +impl fmt::Display for Vector3 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}, {}, {}", self.0.x, self.0.y, self.0.z) + } +} + +impl ops::Neg for Vector3 { + type Output = Self; + fn neg(self) -> Self::Output { + Vector3(-self.0) + } +} + +impl ops::Add for Vector3 { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Vector3(self.0 + rhs.0) + } +} + +impl ops::Sub for Vector3 { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + Vector3(self.0 - rhs.0) + } +} + impl From<&RbxVector3> for Vector3 { fn from(v: &RbxVector3) -> Self { Vector3(Vec3 { diff --git a/packages/lib-roblox/src/datatypes/types/vector3int16.rs b/packages/lib-roblox/src/datatypes/types/vector3int16.rs index c3279ed..964e3ab 100644 --- a/packages/lib-roblox/src/datatypes/types/vector3int16.rs +++ b/packages/lib-roblox/src/datatypes/types/vector3int16.rs @@ -1,4 +1,5 @@ use core::fmt; +use std::ops; use glam::IVec3; use mlua::prelude::*; @@ -31,12 +32,6 @@ impl Vector3int16 { } } -impl fmt::Display for Vector3int16 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}, {}", self.0.x, self.0.y) - } -} - impl LuaUserData for Vector3int16 { fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_method_get("X", |_, this| Ok(this.0.x)); @@ -47,13 +42,9 @@ impl LuaUserData for Vector3int16 { 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, |_, this, ()| Ok(Vector3int16(-this.0))); - methods.add_meta_method(LuaMetaMethod::Add, |_, this, rhs: Vector3int16| { - Ok(Vector3int16(this.0 + rhs.0)) - }); - methods.add_meta_method(LuaMetaMethod::Sub, |_, this, rhs: Vector3int16| { - Ok(Vector3int16(this.0 - rhs.0)) - }); + 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); methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { match &rhs { LuaValue::Number(n) => return Ok(Vector3int16(this.0 * IVec3::splat(*n as i32))), @@ -97,6 +88,33 @@ impl LuaUserData for Vector3int16 { } } +impl fmt::Display for Vector3int16 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}, {}", self.0.x, self.0.y) + } +} + +impl ops::Neg for Vector3int16 { + type Output = Self; + fn neg(self) -> Self::Output { + Vector3int16(-self.0) + } +} + +impl ops::Add for Vector3int16 { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Vector3int16(self.0 + rhs.0) + } +} + +impl ops::Sub for Vector3int16 { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + Vector3int16(self.0 - rhs.0) + } +} + impl From<&RbxVector3int16> for Vector3int16 { fn from(v: &RbxVector3int16) -> Self { Vector3int16(IVec3 {