Skip to content

Commit

Permalink
Tidy up Lua bindings via Arc
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkleiny committed Aug 7, 2024
1 parent 5b89574 commit c8956ff
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 211 deletions.
6 changes: 2 additions & 4 deletions backends/wgpu/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,10 @@ impl WinitMouseDevice {
_ => return,
};

let event = match state {
self.events.push(match state {
ElementState::Pressed => MouseEvent::MouseDown(button),
ElementState::Released => MouseEvent::MouseUp(button),
};

self.events.push(event);
});
}

pub fn clear_events(&mut self) {
Expand Down
89 changes: 60 additions & 29 deletions core/common/src/abstractions/variant.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
use std::{any::Any, cmp::Ordering, fmt::Debug};
use std::{any::Any, cmp::Ordering, fmt::Debug, sync::Arc};

use crate::{Callable, Color, Color32, Pointer, Quat, StringName, Vec2, Vec3, Vec4};

/// An error that can occur when working with variants.
#[derive(Debug)]
pub enum VariantError {
InvalidNegation,
InvalidConversion,
NonArithmetic,
}
use crate::{downcast_arc, Callable, Color, Color32, Quat, StringName, Vec2, Vec3, Vec4};

/// Allows for a type to be converted to a [`Variant`].
pub trait ToVariant {
Expand All @@ -22,6 +14,14 @@ pub trait FromVariant: Sized {
fn from_variant(variant: Variant) -> Result<Self, VariantError>;
}

/// An error that can occur when working with variants.
#[derive(Debug)]
pub enum VariantError {
InvalidNegation,
InvalidConversion,
NonArithmetic,
}

/// The different kinds of values that a [`Variant`] can hold.
#[repr(u8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down Expand Up @@ -56,7 +56,7 @@ pub enum VariantKind {
/// This is an abstraction over the different primitive types that are often
/// shuffled around in the engine. It allows for a more generic API that can
/// handle any type of value.
#[derive(Default, Debug, Clone, PartialEq)]
#[derive(Default, Debug, Clone)]
pub enum Variant {
#[default]
Null,
Expand All @@ -81,7 +81,7 @@ pub enum Variant {
Color(Color),
Color32(Color32),
Callable(Callable),
UserData(Pointer<dyn Any>),
Any(Arc<dyn Any>),
}

impl Variant {
Expand Down Expand Up @@ -110,7 +110,7 @@ impl Variant {
Variant::Color(_) => VariantKind::Color,
Variant::Color32(_) => VariantKind::Color32,
Variant::Callable(_) => VariantKind::Callable,
Variant::UserData(_) => VariantKind::UserData,
Variant::Any(_) => VariantKind::UserData,
}
}

Expand Down Expand Up @@ -304,6 +304,37 @@ impl PartialOrd for Variant {
}
}

/// Specialized equality for variant types.
impl PartialEq for Variant {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Variant::Bool(a), Variant::Bool(b)) => a == b,
(Variant::Char(a), Variant::Char(b)) => a == b,
(Variant::U8(a), Variant::U8(b)) => a == b,
(Variant::U16(a), Variant::U16(b)) => a == b,
(Variant::U32(a), Variant::U32(b)) => a == b,
(Variant::U64(a), Variant::U64(b)) => a == b,
(Variant::I8(a), Variant::I8(b)) => a == b,
(Variant::I16(a), Variant::I16(b)) => a == b,
(Variant::I32(a), Variant::I32(b)) => a == b,
(Variant::I64(a), Variant::I64(b)) => a == b,
(Variant::F32(a), Variant::F32(b)) => a == b,
(Variant::F64(a), Variant::F64(b)) => a == b,
(Variant::String(a), Variant::String(b)) => a == b,
(Variant::StringName(a), Variant::StringName(b)) => a == b,
(Variant::Vec2(a), Variant::Vec2(b)) => a == b,
(Variant::Vec3(a), Variant::Vec3(b)) => a == b,
(Variant::Vec4(a), Variant::Vec4(b)) => a == b,
(Variant::Quat(a), Variant::Quat(b)) => a == b,
(Variant::Color(a), Variant::Color(b)) => a == b,
(Variant::Color32(a), Variant::Color32(b)) => a == b,
(Variant::Callable(a), Variant::Callable(b)) => a == b,
(Variant::Any(a), Variant::Any(b)) => Arc::ptr_eq(a, b),
_ => false,
}
}
}

/// Allows conversion to/from a `Variant` for a given type.
macro_rules! impl_variant {
((), $kind:ident) => {
Expand Down Expand Up @@ -404,30 +435,30 @@ impl_variant!(Quat, Quat);
impl_variant!(Color, Color);
impl_variant!(Color32, Color32);

impl<T: Any> ToVariant for Pointer<T> {
/// Allow [`Arc`] of [`Any`] to be converted to/from Variant.
impl<T: Any> ToVariant for Arc<T> {
fn to_variant(&self) -> Variant {
Variant::UserData(self.clone())
Variant::Any(self.clone())
}
}

impl<T: Any> FromVariant for Pointer<T> {
impl<T: Any> FromVariant for Arc<T> {
fn from_variant(variant: Variant) -> Result<Self, VariantError> {
match variant {
Variant::UserData(value) => Ok(unsafe { value.cast_unchecked() }),
Variant::Any(value) => Ok(downcast_arc(value).map_err(|_| VariantError::InvalidConversion)?),
_ => Err(VariantError::InvalidConversion),
}
}
}

/// Allow [`Callable`] to be converted to/from Variant.
impl ToVariant for Callable {
#[inline]
fn to_variant(&self) -> Variant {
Variant::Callable(self.clone())
}
}

impl FromVariant for Callable {
#[inline]
fn from_variant(variant: Variant) -> Result<Self, VariantError> {
match variant {
Variant::Callable(callable) => Ok(callable),
Expand All @@ -436,6 +467,7 @@ impl FromVariant for Callable {
}
}

/// Allow [`Option`]al values to be converted from a [`Variant`].
impl<V: FromVariant> FromVariant for Option<V> {
fn from_variant(variant: Variant) -> Result<Self, VariantError> {
if variant == Variant::Null {
Expand All @@ -448,18 +480,20 @@ impl<V: FromVariant> FromVariant for Option<V> {

#[macro_export]
macro_rules! impl_variant_enum {
($type:ty, u32) => {
($type:ty as $primitive:ty) => {
/// Allow conversion of enum to/from a variant.
impl $crate::ToVariant for $type {
#[inline]
fn to_variant(&self) -> $crate::Variant {
$crate::Variant::U32(*self as u32)
(*self as $primitive).to_variant()
}
}

/// Allow conversion of enum to/from a variant.
impl $crate::FromVariant for $type {
#[inline]
fn from_variant(variant: $crate::Variant) -> Result<Self, $crate::VariantError> {
Ok(unsafe { std::mem::transmute(u32::from_variant(variant)?) })
Ok(unsafe { std::mem::transmute(<$primitive>::from_variant(variant)?) })
}
}
};
Expand All @@ -468,7 +502,6 @@ macro_rules! impl_variant_enum {
#[cfg(test)]
mod tests {
use super::*;
use crate::Pointer;

#[test]
fn test_variant_size_is_ok() {
Expand Down Expand Up @@ -503,14 +536,12 @@ mod tests {
}

#[test]
fn test_variant_user_data_equality() {
let value = Pointer::new("Hello, World!");
fn test_variant_any_equality() {
let value = Arc::new("Hello, World!");

let a = Variant::UserData(value.clone());
let b = Variant::UserData(value.clone());
let a = Variant::Any(value.clone());
let b = Variant::Any(value.clone());

assert_eq!(a, b);

value.delete();
}
}
14 changes: 14 additions & 0 deletions core/common/src/collections/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,20 @@ macro_rules! impl_arena_index {
Self::from(random.next_u64())
}
}

impl $crate::FromVariant for $name {
#[inline]
fn from_variant(variant: $crate::Variant) -> Result<Self, $crate::VariantError> {
Ok(Self::from(u64::from_variant(variant)?))
}
}

impl $crate::ToVariant for $name {
#[inline]
fn to_variant(&self) -> $crate::Variant {
$crate::Variant::U64(self.0)
}
}
};
}

Expand Down
2 changes: 1 addition & 1 deletion core/common/src/io/formats/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl Format for BinaryFormat {
stream.write_u8(value.a)?;
}
Variant::Callable(_) => todo!(),
Variant::UserData(_) => todo!(),
Variant::Any(_) => todo!(),
}
}
Chunk::Sequence(sequence) => {
Expand Down
2 changes: 1 addition & 1 deletion core/common/src/io/formats/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl Format for JsonFormat {
stream.write_string(&format!("[{}, {}, {}, {}]", value.r, value.g, value.b, value.a))?;
}
Variant::Callable(_) => todo!(),
Variant::UserData(_) => todo!(),
Variant::Any(_) => todo!(),
},
Chunk::Sequence(sequence) => {
stream.write_string("[")?;
Expand Down
11 changes: 1 addition & 10 deletions core/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,11 @@
//! This crate contains common utilities, collections, diagnostics and other
//! general purpose code for use in other systems.
#![allow(incomplete_features)]
#![allow(async_fn_in_trait)]
#![feature(anonymous_lifetime_in_impl_trait)]
#![feature(allocator_api)]
#![feature(associated_type_defaults)]
#![feature(impl_trait_in_assoc_type)]
#![feature(type_alias_impl_trait)]
#![feature(noop_waker)]
#![feature(ptr_as_ref_unchecked)]
#![feature(box_into_inner)]
#![feature(allocator_api)]
#![feature(coerce_unsized)]
#![feature(unsize)]
#![feature(downcast_unchecked)]
#![feature(async_closure)]

pub use abstractions::*;
pub use collections::*;
Expand Down
33 changes: 11 additions & 22 deletions core/common/src/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
//! Lua is a pretty solid scripting language that is easy to embed and use, so
//! let's make it a first class citizen.
use std::sync::Arc;

pub use mlua::prelude::*;

use crate::{
Callable, Callback, CallbackError, Color, Color32, FromVariant, Pointer, Quat, ToVariant, ToVirtualPath, Variant,
Vec2, Vec3, Vec4,
Callable, Callback, CallbackError, Color, Color32, FromVariant, Quat, ToVariant, ToVirtualPath, Variant, Vec2, Vec3,
Vec4,
};

/// A Lua scripting engine.
Expand Down Expand Up @@ -147,7 +149,9 @@ impl<'lua> IntoLua<'lua> for Variant {

LuaValue::Function(function)
}
Variant::UserData(value) => LuaValue::LightUserData(LuaLightUserData(value.into_void())),
Variant::Any(_value) => {
todo!("support arbitrary values in Lua")
}
})
}
}
Expand All @@ -161,7 +165,7 @@ impl<'lua> FromLua<'lua> for Variant {
LuaValue::Integer(value) => Variant::I64(value),
LuaValue::Number(value) => Variant::F64(value),
LuaValue::String(value) => Variant::String(value.to_str()?.to_string()),
LuaValue::Table(value) => Variant::UserData(Pointer::new(value.into_owned())),
LuaValue::Table(value) => Variant::Any(Arc::new(value.into_owned())),
LuaValue::Function(function) => {
// create a callable that calls the Lua function
let function = function.into_owned();
Expand All @@ -173,7 +177,9 @@ impl<'lua> FromLua<'lua> for Variant {

Variant::Callable(callable)
}
LuaValue::LightUserData(value) => Variant::UserData(Pointer::from_raw_mut(value.0)),
LuaValue::LightUserData(_value) => {
todo!("support arbitrary values in Lua")
}
LuaValue::UserData(value) => match () {
_ if value.is::<LuaVec2>() => Variant::Vec2(value.borrow::<LuaVec2>()?.0),
_ if value.is::<LuaVec3>() => Variant::Vec3(value.borrow::<LuaVec3>()?.0),
Expand Down Expand Up @@ -544,23 +550,6 @@ impl<'lua> FromLua<'lua> for LuaColor32 {
mod tests {
use super::*;

#[test]
fn test_table_coercion_through_pointer() {
let lua = Lua::new();
let globals = lua.globals();

globals.set("Key", "Hello, world!").unwrap();

let pointer_a = Pointer::new(globals);
let pointer_b: Pointer<LuaTable> = unsafe { pointer_a.cast_unchecked() };

let value: String = pointer_b.get("Key").unwrap();

assert_eq!(value, "Hello, world!");

pointer_b.delete();
}

#[test]
fn test_basic_wrapper_operations_for_vec2() {
let lua = LuaScriptEngine::new().unwrap();
Expand Down
2 changes: 0 additions & 2 deletions core/common/src/memory.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Memory management tools
pub use pointer::*;
pub use stack::*;

mod pointer;
mod stack;
Loading

0 comments on commit c8956ff

Please sign in to comment.