 bd008589f3
			
		
	
	
		bd008589f3
		
	
	
	
	
		
			
			> In draft until #4761 is merged. See the relevant commits [here](a85fe94a18).
---
# Objective
Update enums across Bevy to use the new enum reflection and get rid of `#[reflect_value(...)]` usages.
## Solution
Find and replace all[^1] instances of `#[reflect_value(...)]` on enum types.
---
## Changelog
- Updated all[^1] reflected enums to implement `Enum` (i.e. they are no longer `ReflectRef::Value`)
## Migration Guide
Bevy-defined enums have been updated to implement `Enum` and are not considered value types (`ReflectRef::Value`) anymore. This means that their serialized representations will need to be updated. For example, given the Bevy enum:
```rust
pub enum ScalingMode {
  None,
  WindowSize,
  Auto { min_width: f32, min_height: f32 },
  FixedVertical(f32),
  FixedHorizontal(f32),
}
```
You will need to update the serialized versions accordingly.
```js
// OLD FORMAT
{
  "type": "bevy_render:📷:projection::ScalingMode",
  "value": FixedHorizontal(720),
},
// NEW FORMAT
{
  "type": "bevy_render:📷:projection::ScalingMode",
  "enum": {
    "variant": "FixedHorizontal",
    "tuple": [
      {
        "type": "f32",
        "value": 720,
      },
    ],
  },
},
```
This may also have other smaller implications (such as `Debug` representation), but serialization is probably the most prominent.
[^1]: All enums except `HandleId` as neither `Uuid` nor `AssetPathId` implement the reflection traits
		
	
			
		
			
				
	
	
		
			252 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			252 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use bevy_asset::Handle;
 | |
| use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
 | |
| use bevy_reflect::{prelude::*, FromReflect};
 | |
| use bevy_render::color::Color;
 | |
| use serde::{Deserialize, Serialize};
 | |
| 
 | |
| use crate::Font;
 | |
| 
 | |
| #[derive(Component, Debug, Default, Clone, Reflect)]
 | |
| #[reflect(Component, Default)]
 | |
| pub struct Text {
 | |
|     pub sections: Vec<TextSection>,
 | |
|     pub alignment: TextAlignment,
 | |
| }
 | |
| 
 | |
| impl Text {
 | |
|     /// Constructs a [`Text`] with a single section.
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_asset::Handle;
 | |
|     /// # use bevy_render::color::Color;
 | |
|     /// # use bevy_text::{Font, Text, TextAlignment, TextStyle, HorizontalAlign, VerticalAlign};
 | |
|     /// #
 | |
|     /// # let font_handle: Handle<Font> = Default::default();
 | |
|     /// #
 | |
|     /// // Basic usage.
 | |
|     /// let hello_world = Text::from_section(
 | |
|     ///     // Accepts a String or any type that converts into a String, such as &str.
 | |
|     ///     "hello world!",
 | |
|     ///     TextStyle {
 | |
|     ///         font: font_handle.clone(),
 | |
|     ///         font_size: 60.0,
 | |
|     ///         color: Color::WHITE,
 | |
|     ///     },
 | |
|     /// );
 | |
|     ///
 | |
|     /// let hello_bevy = Text::from_section(
 | |
|     ///     "hello bevy!",
 | |
|     ///     TextStyle {
 | |
|     ///         font: font_handle,
 | |
|     ///         font_size: 60.0,
 | |
|     ///         color: Color::WHITE,
 | |
|     ///     },
 | |
|     /// ) // You can still add an alignment.
 | |
|     /// .with_alignment(TextAlignment::CENTER);
 | |
|     /// ```
 | |
|     pub fn from_section(value: impl Into<String>, style: TextStyle) -> Self {
 | |
|         Self {
 | |
|             sections: vec![TextSection::new(value, style)],
 | |
|             alignment: Default::default(),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Constructs a [`Text`] from a list of sections.
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_asset::Handle;
 | |
|     /// # use bevy_render::color::Color;
 | |
|     /// # use bevy_text::{Font, Text, TextStyle, TextSection};
 | |
|     /// #
 | |
|     /// # let font_handle: Handle<Font> = Default::default();
 | |
|     /// #
 | |
|     /// let hello_world = Text::from_sections([
 | |
|     ///     TextSection::new(
 | |
|     ///         "Hello, ",
 | |
|     ///         TextStyle {
 | |
|     ///             font: font_handle.clone(),
 | |
|     ///             font_size: 60.0,
 | |
|     ///             color: Color::BLUE,
 | |
|     ///         },
 | |
|     ///     ),
 | |
|     ///     TextSection::new(
 | |
|     ///         "World!",
 | |
|     ///         TextStyle {
 | |
|     ///             font: font_handle,
 | |
|     ///             font_size: 60.0,
 | |
|     ///             color: Color::RED,
 | |
|     ///         },
 | |
|     ///     ),
 | |
|     /// ]);
 | |
|     /// ```
 | |
|     pub fn from_sections(sections: impl IntoIterator<Item = TextSection>) -> Self {
 | |
|         Self {
 | |
|             sections: sections.into_iter().collect(),
 | |
|             alignment: Default::default(),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Returns this [`Text`] with a new [`TextAlignment`].
 | |
|     pub const fn with_alignment(mut self, alignment: TextAlignment) -> Self {
 | |
|         self.alignment = alignment;
 | |
|         self
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[derive(Debug, Default, Clone, FromReflect, Reflect)]
 | |
| pub struct TextSection {
 | |
|     pub value: String,
 | |
|     pub style: TextStyle,
 | |
| }
 | |
| 
 | |
| impl TextSection {
 | |
|     /// Create a new [`TextSection`].
 | |
|     pub fn new(value: impl Into<String>, style: TextStyle) -> Self {
 | |
|         Self {
 | |
|             value: value.into(),
 | |
|             style,
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Create an empty [`TextSection`] from a style. Useful when the value will be set dynamically.
 | |
|     pub const fn from_style(style: TextStyle) -> Self {
 | |
|         Self {
 | |
|             value: String::new(),
 | |
|             style,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[derive(Debug, Clone, Copy, Reflect)]
 | |
| pub struct TextAlignment {
 | |
|     pub vertical: VerticalAlign,
 | |
|     pub horizontal: HorizontalAlign,
 | |
| }
 | |
| 
 | |
| impl TextAlignment {
 | |
|     /// A [`TextAlignment`] set to the top-left.
 | |
|     pub const TOP_LEFT: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Top,
 | |
|         horizontal: HorizontalAlign::Left,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to the top-center.
 | |
|     pub const TOP_CENTER: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Top,
 | |
|         horizontal: HorizontalAlign::Center,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to the top-right.
 | |
|     pub const TOP_RIGHT: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Top,
 | |
|         horizontal: HorizontalAlign::Right,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to center the center-left.
 | |
|     pub const CENTER_LEFT: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Center,
 | |
|         horizontal: HorizontalAlign::Left,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to center on both axes.
 | |
|     pub const CENTER: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Center,
 | |
|         horizontal: HorizontalAlign::Center,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to the center-right.
 | |
|     pub const CENTER_RIGHT: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Center,
 | |
|         horizontal: HorizontalAlign::Right,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to the bottom-left.
 | |
|     pub const BOTTOM_LEFT: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Bottom,
 | |
|         horizontal: HorizontalAlign::Left,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to the bottom-center.
 | |
|     pub const BOTTOM_CENTER: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Bottom,
 | |
|         horizontal: HorizontalAlign::Center,
 | |
|     };
 | |
| 
 | |
|     /// A [`TextAlignment`] set to the bottom-right.
 | |
|     pub const BOTTOM_RIGHT: Self = TextAlignment {
 | |
|         vertical: VerticalAlign::Bottom,
 | |
|         horizontal: HorizontalAlign::Right,
 | |
|     };
 | |
| }
 | |
| 
 | |
| impl Default for TextAlignment {
 | |
|     fn default() -> Self {
 | |
|         TextAlignment::TOP_LEFT
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Describes horizontal alignment preference for positioning & bounds.
 | |
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect, Serialize, Deserialize)]
 | |
| #[reflect(Serialize, Deserialize)]
 | |
| pub enum HorizontalAlign {
 | |
|     /// Leftmost character is immediately to the right of the render position.<br/>
 | |
|     /// Bounds start from the render position and advance rightwards.
 | |
|     Left,
 | |
|     /// Leftmost & rightmost characters are equidistant to the render position.<br/>
 | |
|     /// Bounds start from the render position and advance equally left & right.
 | |
|     Center,
 | |
|     /// Rightmost character is immediately to the left of the render position.<br/>
 | |
|     /// Bounds start from the render position and advance leftwards.
 | |
|     Right,
 | |
| }
 | |
| 
 | |
| impl From<HorizontalAlign> for glyph_brush_layout::HorizontalAlign {
 | |
|     fn from(val: HorizontalAlign) -> Self {
 | |
|         match val {
 | |
|             HorizontalAlign::Left => glyph_brush_layout::HorizontalAlign::Left,
 | |
|             HorizontalAlign::Center => glyph_brush_layout::HorizontalAlign::Center,
 | |
|             HorizontalAlign::Right => glyph_brush_layout::HorizontalAlign::Right,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Describes vertical alignment preference for positioning & bounds. Currently a placeholder
 | |
| /// for future functionality.
 | |
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect, Serialize, Deserialize)]
 | |
| #[reflect(Serialize, Deserialize)]
 | |
| pub enum VerticalAlign {
 | |
|     /// Characters/bounds start underneath the render position and progress downwards.
 | |
|     Top,
 | |
|     /// Characters/bounds center at the render position and progress outward equally.
 | |
|     Center,
 | |
|     /// Characters/bounds start above the render position and progress upward.
 | |
|     Bottom,
 | |
| }
 | |
| 
 | |
| impl From<VerticalAlign> for glyph_brush_layout::VerticalAlign {
 | |
|     fn from(val: VerticalAlign) -> Self {
 | |
|         match val {
 | |
|             VerticalAlign::Top => glyph_brush_layout::VerticalAlign::Top,
 | |
|             VerticalAlign::Center => glyph_brush_layout::VerticalAlign::Center,
 | |
|             VerticalAlign::Bottom => glyph_brush_layout::VerticalAlign::Bottom,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[derive(Clone, Debug, Reflect, FromReflect)]
 | |
| pub struct TextStyle {
 | |
|     pub font: Handle<Font>,
 | |
|     pub font_size: f32,
 | |
|     pub color: Color,
 | |
| }
 | |
| 
 | |
| impl Default for TextStyle {
 | |
|     fn default() -> Self {
 | |
|         Self {
 | |
|             font: Default::default(),
 | |
|             font_size: 12.0,
 | |
|             color: Color::WHITE,
 | |
|         }
 | |
|     }
 | |
| }
 |