refactor: intorduction of a macro enabled Object trait

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers
2024-04-29 22:18:16 -07:00
parent 2536af81e2
commit a3321636b8
3 changed files with 121 additions and 58 deletions

View File

@@ -1,27 +1,24 @@
macro_rules! __define_object_interface_for {
($trt:ident) => {
macro_rules! object_trait {
(@intf $trait_name:ident $trt:path) => {
paste::paste! {
#[allow(missing_docs)]
pub type [<$trt Ref>]<'a, T> = &'a dyn $trt<ID = <T as Object>::ID>;
pub type [<$trt Ref>]<'a, T> = &'a dyn $trt<ID = <T as $trait_name>::ID>;
#[allow(missing_docs)]
pub type [<$trt RefMut>]<'a, T> = &'a mut dyn $trt<ID = <T as Object>::ID>;
pub type [<$trt RefMut>]<'a, T> = &'a mut dyn $trt<ID = <T as $trait_name>::ID>;
}
};
}
macro_rules! object_trait_for {
( $($trt:ident),*) => {
( $trait_name:ident {$($trt:path),*}) => {
$(
__define_object_interface_for!{$trt}
object_trait!{@intf $trait_name $trt}
)*
pub trait Object {
pub trait $trait_name {
type ID;
fn id(&self) -> &Self::ID;
fn as_object(&self) -> &dyn Object<ID = Self::ID>;
fn as_object(&self) -> &dyn $trait_name<ID = Self::ID>;
fn as_object_mut(&mut self) -> &mut dyn Object<ID = Self::ID>;
fn as_object_mut(&mut self) -> &mut dyn $trait_name<ID = Self::ID>;
paste::paste!{$(
#[inline(always)]
@@ -38,57 +35,77 @@ macro_rules! object_trait_for {
};
}
macro_rules! __emit_dollar__ {
($($rules:tt)*) => {
macro_rules! __emit__ { $($rules)* }
__emit__! { $ }
};
}
pub(in crate) use object_trait;
pub(in crate) use __emit_dollar__;
macro_rules! ObjectInterface {
{
#[custom(implements($trait_name:ident {$($trt:path),*}))]
$( #[$attr:meta] )*
$viz:vis struct $struct:ident {
$(
$(#[#field1:meta])*
$field1_viz:vis
$field1_name:ident : $field1_ty:ty,
),*
#[custom(object_id)]
$(#[$id_attr:meta])*
$id_viz:vis $field_id:ident: $id_typ:ty,
$(
$(#[#field2:meta])*
$field2_viz:vis
$field2_name:ident : $field2_ty:ty,
),*
}
} => {
impl $trait_name for $struct {
type ID = $id_typ;
macro_rules! alias {
($($name:ident -> $(#[$($stuff:tt)*])+;)* ) => {
$(
$crate::vm::object::macros::__emit_dollar__! { ($_:tt) => (
#[allow(nonstandard_style)]
macro_rules! $name {($_($item:tt)*) => (
$( #[$($stuff)*] )+
$_($item)*
)}
#[allow(unused_imports)]
pub(in crate) use $name;
)}
)*
fn id(&self) -> &Self::ID {
&self.$field_id
}
#[inline(always)]
fn as_object(&self) -> &dyn $trait_name<ID = Self::ID> {
self
}
#[inline(always)]
fn as_object_mut(&mut self) -> &mut dyn $trait_name<ID = Self::ID> {
self
}
paste::paste!{$(
#[inline(always)]
fn [<as_ $trt:lower>](&self) -> Option<[<$trt Ref>]<Self>> {
Some(self)
}
#[inline(always)]
fn [<as_ $trt:lower _mut>](&mut self) -> Option<[<$trt RefMut>]<Self>> {
Some(self)
}
)*}
}
};
}
pub(in crate) use alias;
pub(in crate) use ObjectInterface;
macro_rules! impl_trait_interfaces {
( $($trt:ident),*) => {
#[inline(always)]
fn as_object(&self) -> &dyn Object<ID = Self::ID> {
self
macro_rules! ObjectTrait {
{
#[custom(object_trait = $trait_name:ident)]
$(#[$attr:meta])*
$viz:vis trait $trt:ident $(: $($bound:path)* )? {
$($tbody:tt)*
}
} => {
$(#[$attr])*
$viz trait $trt: $($($bound)* +)? $trait_name {
$($tbody)*
}
#[inline(always)]
fn as_object_mut(&mut self) -> &mut dyn Object<ID = Self::ID> {
self
}
paste::paste!{$(
#[inline(always)]
fn [<as_ $trt:lower>](&self) -> Option<[<$trt Ref>]<Self>> {
Some(self)
}
#[inline(always)]
fn [<as_ $trt:lower _mut>](&mut self) -> Option<[<$trt RefMut>]<Self>> {
Some(self)
}
)*}
};
}
pub(in crate) use ObjectTrait;

View File

@@ -1,5 +1,34 @@
use macro_rules_attribute::derive;
mod macros;
mod traits;
use macros::alias;
use macros::{object_trait, ObjectInterface};
use traits::Memory;
use crate::vm::object::traits::Test;
object_trait!(VmObject { Memory });
#[derive(ObjectInterface!)]
#[custom(implements(VmObject { Memory }))]
pub struct Generic {
mem1: Vec<u32>,
#[custom(object_id)]
id: u32,
mem2: Vec<u32>,
}
impl Memory for Generic {
fn get_memory(&self) -> &Vec<u32> {
&self.mem1
}
fn set_memory(&mut self, index: usize, val: u32) {
self.mem2[index] = val;
}
}
impl Test for Generic {}

View File

@@ -0,0 +1,17 @@
use macro_rules_attribute::apply;
use crate::vm::object::macros::ObjectTrait;
use crate::vm::object::VmObject;
#[apply(ObjectTrait!)]
#[custom(object_trait = VmObject)]
pub trait Memory: Test {
fn get_memory(&self) -> &Vec<u32>;
fn set_memory(&mut self, index: usize, val: u32);
}
pub trait Test {
fn test(&self) {
println!("test!");
}
}