Implement std ops for roblox datatypes

This commit is contained in:
Filip Tibell 2023-03-11 18:38:27 +01:00
parent ba52396bec
commit 89aaf40fdb
No known key found for this signature in database
7 changed files with 202 additions and 104 deletions

View file

@ -1,3 +1,5 @@
use std::ops;
use mlua::prelude::*;
pub(super) fn userdata_impl_to_string<D>(_: &Lua, datatype: &D, _: ()) -> LuaResult<String>
@ -21,3 +23,24 @@ where
Ok(false)
}
}
pub(super) fn userdata_impl_unm<D>(_: &Lua, datatype: &D, _: ()) -> LuaResult<D>
where
D: LuaUserData + ops::Neg<Output = D> + Copy,
{
Ok(-*datatype)
}
pub(super) fn userdata_impl_add<D>(_: &Lua, datatype: &D, value: D) -> LuaResult<D>
where
D: LuaUserData + ops::Add<Output = D> + Copy,
{
Ok(*datatype + value)
}
pub(super) fn userdata_impl_sub<D>(_: &Lua, datatype: &D, value: D) -> LuaResult<D>
where
D: LuaUserData + ops::Sub<Output = D> + Copy,
{
Ok(*datatype - value)
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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