Skip to content

Commit

Permalink
Implement Reflect and Enum for Option
Browse files Browse the repository at this point in the history
  • Loading branch information
Davier committed Feb 1, 2021
1 parent dabdd39 commit 9261317
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 11 deletions.
12 changes: 4 additions & 8 deletions crates/bevy_reflect/bevy_reflect_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,12 +665,8 @@ fn impl_enum(
Ident::new("unused", Span::call_site())
};
let wrapper_name = match &variant.fields {
Fields::Named(struct_fields) => {
quote!(#struct_fields).to_string()
}
Fields::Unnamed(tuple_fields) => {
quote!(#tuple_fields).to_string()
}
Fields::Named(struct_fields) => quote!(#struct_fields).to_string(),
Fields::Unnamed(tuple_fields) => quote!(#tuple_fields).to_string(),
Fields::Unit => "unused".to_string(),
};
let reflect_variant = {
Expand Down Expand Up @@ -880,7 +876,7 @@ fn impl_enum(
wrapper_ident,
wrapper_name,
variant_index,
variant_name,
_variant_name,
_variant_ident,
variant_and_fields_ident,
fields,
Expand Down Expand Up @@ -1030,7 +1026,7 @@ fn impl_enum(
wrapper_ident,
wrapper_name,
variant_index,
variant_name,
_variant_name,
_variant_ident,
variant_and_fields_ident,
fields,
Expand Down
133 changes: 130 additions & 3 deletions crates/bevy_reflect/src/impls/std.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
map_partial_eq, serde::Serializable, DynamicMap, List, ListIter, Map, MapIter, Reflect,
ReflectDeserialize, ReflectMut, ReflectRef,
map_partial_eq, serde::Serializable, DynamicMap, Enum, EnumVariant, EnumVariantMut,
GetTypeRegistration, List, ListIter, Map, MapIter, Reflect, ReflectDeserialize, ReflectMut,
ReflectRef, TypeRegistration, VariantInfo, VariantInfoIter,
};

use bevy_reflect_derive::impl_reflect_value;
Expand Down Expand Up @@ -29,7 +30,6 @@ impl_reflect_value!(isize(Hash, PartialEq, Serialize, Deserialize));
impl_reflect_value!(f32(Serialize, Deserialize));
impl_reflect_value!(f64(Serialize, Deserialize));
impl_reflect_value!(String(Hash, PartialEq, Serialize, Deserialize));
impl_reflect_value!(Option<T: Serialize + Clone + for<'de> Deserialize<'de> + Reflect + 'static>(Serialize, Deserialize));
impl_reflect_value!(HashSet<T: Serialize + Hash + Eq + Clone + for<'de> Deserialize<'de> + Send + Sync + 'static>(Serialize, Deserialize));
impl_reflect_value!(Range<T: Serialize + Clone + for<'de> Deserialize<'de> + Send + Sync + 'static>(Serialize, Deserialize));

Expand Down Expand Up @@ -279,4 +279,131 @@ impl Reflect for Cow<'static, str> {
fn serializable(&self) -> Option<Serializable> {
Some(Serializable::Borrowed(self))
}

fn as_reflect(&self) -> &dyn Reflect {
self
}

fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
self
}
}

impl<T: Reflect + Clone + Send + Sync + 'static> GetTypeRegistration for Option<T> {
fn get_type_registration() -> TypeRegistration {
TypeRegistration::of::<Option<T>>()
}
}
impl<T: Reflect + Clone + Send + Sync + 'static> Enum for Option<T> {
fn variant(&self) -> EnumVariant<'_> {
match self {
Option::Some(new_type) => EnumVariant::NewType(new_type as &dyn Reflect),
Option::None => EnumVariant::Unit,
}
}

fn variant_mut(&mut self) -> EnumVariantMut<'_> {
match self {
Option::Some(new_type) => EnumVariantMut::NewType(new_type as &mut dyn Reflect),
Option::None => EnumVariantMut::Unit,
}
}

fn variant_info(&self) -> VariantInfo<'_> {
let index = match self {
Option::Some(_) => 0usize,
Option::None => 1usize,
};
VariantInfo {
index,
name: self.get_index_name(index).unwrap(),
}
}

fn get_index_name(&self, index: usize) -> Option<&'_ str> {
match index {
0usize => Some("Option::Some"),
1usize => Some("Option::None"),
_ => None,
}
}

fn get_index_from_name(&self, name: &str) -> Option<usize> {
match name {
"Option::Some" => Some(0usize),
"Option::None" => Some(1usize),
_ => None,
}
}

fn iter_variants_info(&self) -> VariantInfoIter<'_> {
VariantInfoIter::new(self)
}
}
impl<T: Reflect + Clone + Send + Sync + 'static> Reflect for Option<T> {
#[inline]
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
}

#[inline]
fn any(&self) -> &dyn std::any::Any {
self
}

#[inline]
fn any_mut(&mut self) -> &mut dyn std::any::Any {
self
}

#[inline]
fn clone_value(&self) -> Box<dyn Reflect> {
Box::new(self.clone())
}

#[inline]
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
*self = value.take()?;
Ok(())
}

#[inline]
fn apply(&mut self, value: &dyn Reflect) {
let value = value.any();
if let Some(value) = value.downcast_ref::<Self>() {
*self = value.clone();
} else {
{
panic!("Enum is not {}.", &std::any::type_name::<Self>());
};
}
}

fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Enum(self)
}

fn reflect_mut(&mut self) -> ReflectMut {
ReflectMut::Enum(self)
}

fn serializable(&self) -> Option<Serializable> {
None
}

fn reflect_hash(&self) -> Option<u64> {
None
}

fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
crate::enum_partial_eq(self, value)
}

fn as_reflect(&self) -> &dyn Reflect {
self
}

fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
self
}
}

0 comments on commit 9261317

Please sign in to comment.