Skip to content

Commit

Permalink
Updated Enum API with direct field access
Browse files Browse the repository at this point in the history
This prevents the Vec/HashMap allocations needed by the previous one.
  • Loading branch information
MrGVSV committed Jul 21, 2022
1 parent 42e4bb3 commit 71d27ab
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 260 deletions.
57 changes: 52 additions & 5 deletions crates/bevy_reflect/src/enums/enum_trait.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
use crate::{Reflect, ReflectRef, Struct, Tuple, VariantInfo, VariantMut, VariantRef};
use crate::{Reflect, ReflectRef, Struct, Tuple, VariantInfo, VariantType};
use bevy_utils::HashMap;
use std::any::{Any, TypeId};
use std::borrow::Cow;
use std::slice::Iter;

pub trait Enum: Reflect {
/// Returns an immutable reference to the current variant.
fn variant(&self) -> VariantRef;
/// Returns a mutable reference to the current variant.
fn variant_mut(&mut self) -> VariantMut;
/// Returns a reference to the value of the field (in the current variant) with the given name.
fn field(&self, name: &str) -> Option<&dyn Reflect>;
/// Returns a reference to the value of the field (in the current variant) at the given index.
fn field_at(&self, index: usize) -> Option<&dyn Reflect>;
/// Returns a mutable reference to the value of the field (in the current variant) with the given name.
fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>;
/// Returns a mutable reference to the value of the field (in the current variant) at the given index.
fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
/// Returns the index of the field (in the current variant) with the given name.
fn index_of(&self, name: &str) -> Option<usize>;
/// Returns an iterator over the values of the current variant's fields.
fn iter_fields(&self) -> VariantFieldIter;
/// Returns the number of fields in the current variant.
fn field_len(&self) -> usize;
/// The name of the current variant.
fn variant_name(&self) -> &str;
/// The type of the current variant.
fn variant_type(&self) -> VariantType;
/// Returns true if the current variant's type matches the given one.
fn is_variant(&self, variant_type: VariantType) -> bool {
self.variant_type() == variant_type
}
}

/// A container for compile-time enum info.
Expand Down Expand Up @@ -92,6 +108,37 @@ impl EnumInfo {
}
}

pub struct VariantFieldIter<'a> {
pub(crate) container: &'a dyn Enum,
pub(crate) index: usize,
}

impl<'a> VariantFieldIter<'a> {
pub fn new(container: &'a dyn Enum) -> Self {
Self {
container,
index: 0,
}
}
}

impl<'a> Iterator for VariantFieldIter<'a> {
type Item = &'a dyn Reflect;

fn next(&mut self) -> Option<Self::Item> {
let value = self.container.field_at(self.index);
self.index += 1;
value
}

fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.container.field_len();
(size, Some(size))
}
}

impl<'a> ExactSizeIterator for VariantFieldIter<'a> {}

#[inline]
pub fn enum_partial_eq<E: Enum>(enum_a: &E, reflect_b: &dyn Reflect) -> Option<bool> {
// TODO: Uncomment and update once we figure out how we want to represent variants
Expand Down
2 changes: 0 additions & 2 deletions crates/bevy_reflect/src/enums/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
mod enum_trait;
mod variant_ref;
mod variants;

pub use enum_trait::*;
pub use variant_ref::*;
pub use variants::*;
235 changes: 0 additions & 235 deletions crates/bevy_reflect/src/enums/variant_ref.rs

This file was deleted.

31 changes: 31 additions & 0 deletions crates/bevy_reflect/src/enums/variants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@ use bevy_utils::HashMap;
use std::borrow::Cow;
use std::slice::Iter;

/// Describes the form of an enum variant.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum VariantType {
/// Struct enums take the form:
///
/// ```
/// enum MyEnum {
/// A {
/// foo: usize
/// }
/// }
/// ```
Struct,
/// Tuple enums take the form:
///
/// ```
/// enum MyEnum {
/// A(usize)
/// }
/// ```
Tuple,
/// Unit enums take the form:
///
/// ```
/// enum MyEnum {
/// A
/// }
/// ```
Unit,
}

/// A container for compile-time enum variant info.
#[derive(Clone, Debug)]
pub enum VariantInfo {
Expand Down
Loading

0 comments on commit 71d27ab

Please sign in to comment.