Upgrade inspector-egui and add first pen_up

Unfortunately `pen_up` does not seem to work even though it compiles
This commit is contained in:
Dietrich 2023-01-11 10:20:15 +01:00
parent 75771e8556
commit 8c5c9b4ec6
12 changed files with 234 additions and 50 deletions

View File

@ -10,6 +10,6 @@ license = "MIT OR Apache-2.0"
bevy = { version = "0.9" } bevy = { version = "0.9" }
bevy_prototype_lyon = {version="0.7"} bevy_prototype_lyon = {version="0.7"}
bevy-inspector-egui = "0.14" bevy-inspector-egui = "0.16"
num-traits = "0.2" num-traits = "0.2"
bevy_tweening = {version="0.6"} bevy_tweening = {version="0.6"}

View File

@ -7,6 +7,10 @@ use crate::{
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct TurtlePlan { pub struct TurtlePlan {
/**
* A turtle Plan contains the segments of a turtle drawing.
* The segments in turn contain the commands to draw the graph.
*/
commands: Vec<TurtleSegment>, commands: Vec<TurtleSegment>,
} }
@ -119,3 +123,133 @@ pub trait CurvedMovement: WithCommands {
} }
impl CurvedMovement for TurtlePlan {} impl CurvedMovement for TurtlePlan {}
pub trait StopLine<T>
where
T: WithCommands,
{
fn pen_up(self) -> InvisibleLinesPlan<T>;
}
impl StopLine<TurtlePlan> for TurtlePlan {
fn pen_up(self) -> InvisibleLinesPlan<TurtlePlan> {
{
InvisibleLinesPlan {
before: self,
commands: vec![],
}
}
}
}
pub trait StartLine<T> {
fn pen_down(self) -> T;
}
impl<T> StartLine<T> for InvisibleLinesPlan<T>
where
T: WithCommands,
{
fn pen_down(mut self) -> T {
self.before.get_mut_commands().append(&mut self.commands);
self.before
}
}
pub struct InvisibleLinesPlan<T: WithCommands> {
before: T,
commands: Vec<TurtleSegment>,
}
impl<T> WithCommands for InvisibleLinesPlan<T>
where
T: WithCommands,
{
fn get_mut_commands(&mut self) -> &mut Vec<TurtleSegment> {
&mut self.commands
}
fn get_commands(self) -> Vec<TurtleSegment> {
self.commands
}
}
impl<T> InvisibleLinesPlan<T>
where
T: WithCommands,
{
pub fn new(before: T) -> Self {
InvisibleLinesPlan {
before,
commands: vec![],
}
}
}
impl Turnable for InvisibleLinesPlan<TurtlePlan> {}
impl<T> DirectionalMovement for InvisibleLinesPlan<T>
where
T: WithCommands,
{
fn forward<IntoDistance>(&mut self, length: IntoDistance) -> &mut Self
where
Length: From<IntoDistance>,
{
let length: Length = length.into();
self.get_mut_commands()
.push(TurtleSegment::Single(DrawElement::Move(
crate::commands::MoveCommand::Forward(length),
)));
self
}
fn backward<IntoDistance>(&mut self, length: IntoDistance) -> &mut Self
where
Length: From<IntoDistance>,
{
let length: Length = length.into();
self.get_mut_commands()
.push(TurtleSegment::Single(DrawElement::Move(
crate::commands::MoveCommand::Backward(length),
)));
self
}
}
impl<T> CurvedMovement for InvisibleLinesPlan<T>
where
T: WithCommands,
{
fn circle<IntoAngle, IntoDistance>(
&mut self,
radius: IntoDistance,
extend: IntoAngle,
) -> &mut Self
where
Angle<Precision>: From<IntoAngle>,
Length: From<IntoDistance>,
{
let angle: Angle<Precision> = extend.into();
let radius: Length = radius.into();
self.get_mut_commands()
.push(TurtleSegment::Single(DrawElement::Move(
MoveCommand::Circle { radius, angle },
)));
self
}
fn circle_right<IntoAngle, IntoDistance: Neg + Neg<Output = IntoDistance>>(
&mut self,
radius: IntoDistance,
extend: IntoAngle,
) -> &mut Self
where
Angle<Precision>: From<IntoAngle>,
Length: From<IntoDistance>,
{
self.circle(-radius, extend);
println!("Warning: circle with right arc not working yet...");
self
}
}

View File

@ -1,5 +1,7 @@
use bevy::prelude::Component; use bevy::{
use bevy_inspector_egui::Inspectable; prelude::Component,
reflect::{FromReflect, Reflect},
};
use crate::{ use crate::{
builders::WithCommands, builders::WithCommands,
@ -17,7 +19,7 @@ use crate::{
* All the possibilities to draw something with turtle. All the commands can get the position, heading, * All the possibilities to draw something with turtle. All the commands can get the position, heading,
* color and fill_color from the turtles state. * color and fill_color from the turtles state.
*/ */
#[derive(Component, Inspectable, Debug)] #[derive(Component, Reflect, FromReflect, Debug, Clone)]
pub enum MoveCommand { pub enum MoveCommand {
Forward(Length), Forward(Length),
Backward(Length), Backward(Length),
@ -35,7 +37,7 @@ impl Default for MoveCommand {
} }
/// Different ways to drop breadcrumbs on the way like a dot or a stamp of the turtles shape. /// Different ways to drop breadcrumbs on the way like a dot or a stamp of the turtles shape.
#[derive(Component, Inspectable, Default, Debug)] #[derive(Component, Reflect, FromReflect, Default, Debug, Clone)]
pub enum Breadcrumb { pub enum Breadcrumb {
Dot, Dot,
#[default] #[default]
@ -43,7 +45,7 @@ pub enum Breadcrumb {
} }
/// Different ways that change the orientation of the turtle. /// Different ways that change the orientation of the turtle.
#[derive(Component, Inspectable, Debug)] #[derive(Component, Reflect, FromReflect, Debug, Clone)]
pub enum OrientationCommand { pub enum OrientationCommand {
Left(Angle<Precision>), Left(Angle<Precision>),
Right(Angle<Precision>), Right(Angle<Precision>),
@ -58,7 +60,7 @@ impl Default for OrientationCommand {
} }
/// A combination of all commands that can be used while drawing. /// A combination of all commands that can be used while drawing.
#[derive(Component, Inspectable, Debug)] #[derive(Component, Reflect, FromReflect, Debug, Clone)]
pub enum DrawElement { pub enum DrawElement {
Draw(MoveCommand), Draw(MoveCommand),
Move(MoveCommand), Move(MoveCommand),
@ -102,7 +104,7 @@ impl ToAnimationSegment for DrawElement {
} }
} }
#[derive(Component, Inspectable, Debug)] #[derive(Component, Reflect, FromReflect, Debug, Clone)]
pub enum TurtleSegment { pub enum TurtleSegment {
Single(DrawElement), Single(DrawElement),
Outline(Vec<DrawElement>), Outline(Vec<DrawElement>),
@ -126,7 +128,7 @@ impl ToAnimationSegment for TurtleSegment {
} }
} }
} }
#[derive(Component, Inspectable, Debug)] #[derive(Component, Reflect, Debug)]
pub struct TurtleCommands { pub struct TurtleCommands {
animation_state: usize, animation_state: usize,
commands: Vec<TurtleSegment>, commands: Vec<TurtleSegment>,

View File

@ -1,12 +1,12 @@
use bevy::prelude::Plugin; use bevy::prelude::Plugin;
use bevy_inspector_egui::WorldInspectorPlugin; use bevy_inspector_egui::quick::WorldInspectorPlugin;
pub struct DebugPlugin; pub struct DebugPlugin;
impl Plugin for DebugPlugin { impl Plugin for DebugPlugin {
fn build(&self, app: &mut bevy::prelude::App) { fn build(&self, app: &mut bevy::prelude::App) {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
app.add_plugin(WorldInspectorPlugin::new()); app.add_plugin(WorldInspectorPlugin);
} }
} }
} }

View File

@ -1,4 +1,4 @@
use bevy_inspector_egui::Inspectable; use bevy::reflect::{FromReflect, Reflect};
pub use self::line_segments::{TurtleDrawCircle, TurtleDrawLine}; pub use self::line_segments::{TurtleDrawCircle, TurtleDrawLine};
@ -6,7 +6,7 @@ pub mod animation;
mod line_segments; mod line_segments;
pub(crate) mod run_step; pub(crate) mod run_step;
#[derive(Inspectable, Default, Debug)] #[derive(Reflect, FromReflect, Default, Debug)]
pub enum TurtleGraphElement { pub enum TurtleGraphElement {
TurtleLine(TurtleDrawLine), TurtleLine(TurtleDrawLine),
TurtleCircle(TurtleDrawCircle), TurtleCircle(TurtleDrawCircle),

View File

@ -1,5 +1,7 @@
use bevy::prelude::{Bundle, Color, Component, Name, Transform, Vec2}; use bevy::{
use bevy_inspector_egui::Inspectable; prelude::{Bundle, Color, Component, Name, Transform, Vec2},
reflect::{FromReflect, Reflect},
};
use bevy_prototype_lyon::{ use bevy_prototype_lyon::{
entity::ShapeBundle, entity::ShapeBundle,
prelude::{DrawMode, FillMode, GeometryBuilder, PathBuilder, StrokeMode}, prelude::{DrawMode, FillMode, GeometryBuilder, PathBuilder, StrokeMode},
@ -8,9 +10,9 @@ use bevy_prototype_lyon::{
use crate::general::{angle::Angle, Precision}; use crate::general::{angle::Angle, Precision};
#[derive(Bundle, Inspectable, Default)] #[derive(Bundle, Reflect, FromReflect, Default)]
pub struct TurtleDrawLine { pub struct TurtleDrawLine {
#[inspectable(ignore)] #[reflect(ignore)]
line: ShapeBundle, line: ShapeBundle,
name: Name, name: Name,
marker: LineMarker, marker: LineMarker,
@ -25,7 +27,7 @@ impl std::fmt::Debug for TurtleDrawLine {
} }
} }
#[derive(Component, Default, Inspectable, Debug)] #[derive(Component, Default, Reflect, FromReflect, Debug, Clone, Copy)]
struct LineMarker; struct LineMarker;
impl TurtleDrawLine { impl TurtleDrawLine {
@ -45,10 +47,10 @@ impl TurtleDrawLine {
} }
} }
#[derive(Bundle, Inspectable, Default)] #[derive(Bundle, Reflect, FromReflect, Default)]
pub struct TurtleDrawCircle { pub struct TurtleDrawCircle {
#[inspectable(ignore)] #[reflect(ignore)]
line: ShapeBundle, line: ShapeBundle,
name: Name, name: Name,
marker: CircleMarker, marker: CircleMarker,
@ -63,7 +65,7 @@ impl std::fmt::Debug for TurtleDrawCircle {
} }
} }
#[derive(Component, Default, Inspectable, Debug)] #[derive(Component, Default, Reflect, FromReflect, Debug, Clone)]
struct CircleMarker; struct CircleMarker;
impl TurtleDrawCircle { impl TurtleDrawCircle {

View File

@ -1,29 +1,30 @@
use bevy_inspector_egui::Inspectable;
use std::{ use std::{
f32::consts::PI, f32::consts::PI,
ops::{Add, Div, Mul, Neg, Rem, Sub}, ops::{Add, Div, Mul, Neg, Rem, Sub},
}; };
use bevy::reflect::{FromReflect, Reflect};
use super::Precision; use super::Precision;
#[derive(Inspectable, Copy, Clone, Debug, PartialEq, Eq)] #[derive(Reflect, FromReflect, Copy, Clone, Debug, PartialEq, Eq)]
pub enum AngleUnit<T: Default> { pub enum AngleUnit<T: Default + Send + Sync + Reflect + Copy + FromReflect> {
Degrees(T), Degrees(T),
Radians(T), Radians(T),
} }
impl<T: Default> Default for AngleUnit<T> { impl<T: Default + Send + Sync + Reflect + Copy + FromReflect> Default for AngleUnit<T> {
fn default() -> Self { fn default() -> Self {
Self::Degrees(Default::default()) Self::Degrees(Default::default())
} }
} }
#[derive(Inspectable, Copy, Default, Clone, Debug, PartialEq, Eq)] #[derive(Reflect, FromReflect, Copy, Default, Clone, Debug, PartialEq, Eq)]
pub struct Angle<T: Default> { pub struct Angle<T: Default + Send + Sync + Reflect + Copy + FromReflect> {
value: AngleUnit<T>, value: AngleUnit<T>,
} }
impl<T: From<i16> + Default> From<i16> for Angle<T> { impl<T: From<i16> + Default + Send + Sync + Reflect + Copy + FromReflect> From<i16> for Angle<T> {
fn from(i: i16) -> Self { fn from(i: i16) -> Self {
Self { Self {
value: AngleUnit::Degrees(T::from(i)), value: AngleUnit::Degrees(T::from(i)),
@ -31,7 +32,9 @@ impl<T: From<i16> + Default> From<i16> for Angle<T> {
} }
} }
impl<T: Default + Clone + Rem<T, Output = T>> Rem<T> for Angle<T> { impl<T: Default + Send + Sync + Reflect + Clone + Copy + FromReflect + Rem<T, Output = T>> Rem<T>
for Angle<T>
{
type Output = Self; type Output = Self;
fn rem(self, rhs: T) -> Self::Output { fn rem(self, rhs: T) -> Self::Output {
@ -42,7 +45,9 @@ impl<T: Default + Clone + Rem<T, Output = T>> Rem<T> for Angle<T> {
} }
} }
impl<T: Default + Clone + Mul<T, Output = T>> Mul<T> for Angle<T> { impl<T: Default + Clone + Send + Sync + Reflect + Copy + FromReflect + Mul<T, Output = T>> Mul<T>
for Angle<T>
{
type Output = Self; type Output = Self;
fn mul(self, rhs: T) -> Self::Output { fn mul(self, rhs: T) -> Self::Output {
@ -65,7 +70,9 @@ impl Angle<Precision> {
} }
} }
} }
impl<T: Default + Clone + Div<T, Output = T>> Div<T> for Angle<T> { impl<T: Default + Clone + Send + Sync + Reflect + Copy + FromReflect + Div<T, Output = T>> Div<T>
for Angle<T>
{
type Output = Self; type Output = Self;
fn div(self, rhs: T) -> Self::Output { fn div(self, rhs: T) -> Self::Output {
@ -76,7 +83,10 @@ impl<T: Default + Clone + Div<T, Output = T>> Div<T> for Angle<T> {
} }
} }
impl<T: Default + Clone + std::ops::Neg<Output = T>> Neg for Angle<T> { impl<
T: Default + Clone + Send + Sync + Reflect + Copy + FromReflect + std::ops::Neg<Output = T>,
> Neg for Angle<T>
{
type Output = Self; type Output = Self;
fn neg(self) -> Self::Output { fn neg(self) -> Self::Output {
@ -87,7 +97,10 @@ impl<T: Default + Clone + std::ops::Neg<Output = T>> Neg for Angle<T> {
} }
} }
impl<T: Default + Clone + std::ops::Neg<Output = T>> Neg for &Angle<T> { impl<
T: Default + Clone + Send + Sync + Reflect + Copy + FromReflect + std::ops::Neg<Output = T>,
> Neg for &Angle<T>
{
type Output = Angle<T>; type Output = Angle<T>;
fn neg(self) -> Self::Output { fn neg(self) -> Self::Output {
@ -98,7 +111,7 @@ impl<T: Default + Clone + std::ops::Neg<Output = T>> Neg for &Angle<T> {
} }
} }
impl<T: Default + Clone> Angle<T> { impl<T: Default + Clone + Send + Sync + Reflect + Copy + FromReflect> Angle<T> {
pub fn degrees(value: T) -> Angle<T> { pub fn degrees(value: T) -> Angle<T> {
Self { Self {
value: AngleUnit::Degrees(value), value: AngleUnit::Degrees(value),
@ -117,7 +130,7 @@ impl<T: Default + Clone> Angle<T> {
} }
} }
impl<T: Default + num_traits::float::Float> Angle<T> { impl<T: Default + Send + Sync + Reflect + Copy + FromReflect + num_traits::float::Float> Angle<T> {
pub fn to_radians(self) -> Self { pub fn to_radians(self) -> Self {
match self.value { match self.value {
AngleUnit::Degrees(v) => Self { AngleUnit::Degrees(v) => Self {
@ -136,7 +149,17 @@ impl<T: Default + num_traits::float::Float> Angle<T> {
} }
} }
impl<T: Add<Output = T> + Default + num_traits::float::Float> Add for Angle<T> { impl<
T: Add<Output = T>
+ Send
+ Sync
+ Reflect
+ Copy
+ FromReflect
+ Default
+ num_traits::float::Float,
> Add for Angle<T>
{
type Output = Angle<T>; type Output = Angle<T>;
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
@ -157,7 +180,17 @@ impl<T: Add<Output = T> + Default + num_traits::float::Float> Add for Angle<T> {
} }
} }
impl<T: Sub<Output = T> + Default + num_traits::float::Float> Sub for Angle<T> { impl<
T: Sub<Output = T>
+ Default
+ Send
+ Sync
+ Reflect
+ Copy
+ FromReflect
+ num_traits::float::Float,
> Sub for Angle<T>
{
type Output = Angle<T>; type Output = Angle<T>;
fn sub(self, rhs: Self) -> Self::Output { fn sub(self, rhs: Self) -> Self::Output {

View File

@ -1,8 +1,8 @@
use bevy_inspector_egui::Inspectable; use bevy::reflect::{FromReflect, Reflect};
use super::Precision; use super::Precision;
#[derive(Inspectable, Default, Copy, Clone, Debug)] #[derive(Reflect, FromReflect, Default, Copy, Clone, Debug)]
pub struct Length(pub Precision); pub struct Length(pub Precision);
impl From<i16> for Length { impl From<i16> for Length {

View File

@ -1,7 +1,6 @@
use std::time::Duration; use std::time::Duration;
use bevy::{core_pipeline::clear_color::ClearColorConfig, prelude::*, window::close_on_esc}; use bevy::{core_pipeline::clear_color::ClearColorConfig, prelude::*, window::close_on_esc};
use bevy_inspector_egui::RegisterInspectable;
use bevy_prototype_lyon::prelude::{Path, ShapePlugin}; use bevy_prototype_lyon::prelude::{Path, ShapePlugin};
use bevy_tweening::{ use bevy_tweening::{
component_animator_system, lens::TransformScaleLens, Animator, EaseFunction, Tween, component_animator_system, lens::TransformScaleLens, Animator, EaseFunction, Tween,
@ -57,8 +56,8 @@ impl Plugin for TurtlePlugin {
.add_system(component_animator_system::<Path>) .add_system(component_animator_system::<Path>)
.add_system(close_on_esc) .add_system(close_on_esc)
.add_system(draw_lines) .add_system(draw_lines)
.register_inspectable::<TurtleColors>() .register_type::<TurtleColors>()
.register_inspectable::<TurtleCommands>(); .register_type::<TurtleCommands>();
} }
} }

View File

@ -1,12 +1,14 @@
mod turtle; mod turtle;
use bevy::prelude::{Color, Component}; use bevy::{
use bevy_inspector_egui::Inspectable; prelude::{Color, Component},
reflect::Reflect,
};
pub use turtle::turtle; pub use turtle::turtle;
#[derive(Clone, Component, Inspectable)] #[derive(Clone, Component, Reflect)]
pub struct TurtleShape; pub struct TurtleShape;
#[derive(Clone, Component, Inspectable, Default, Debug)] #[derive(Clone, Component, Reflect, Default, Debug)]
pub struct TurtleColors { pub struct TurtleColors {
color: Color, color: Color,
fill_color: Color, fill_color: Color,

View File

@ -1,7 +1,9 @@
use std::{cmp::max, time::Duration}; use std::{cmp::max, time::Duration};
use bevy::prelude::{Color, Component, Transform}; use bevy::{
use bevy_inspector_egui::Inspectable; prelude::{Component, Transform},
reflect::Reflect,
};
use crate::{ use crate::{
commands::TurtleSegment, commands::TurtleSegment,
@ -10,7 +12,7 @@ use crate::{
}; };
/// Describing the full state of a turtle. /// Describing the full state of a turtle.
#[derive(Component, Inspectable, Default, Debug)] #[derive(Component, Reflect, Default, Debug, Clone)]
pub struct TurtleState { pub struct TurtleState {
drawing: Vec<TurtleSegment>, drawing: Vec<TurtleSegment>,
position: Coordinate, position: Coordinate,

View File

@ -7,7 +7,10 @@ use bevy_prototype_lyon::{
}; };
use crate::{ use crate::{
builders::{CurvedMovement, DirectionalMovement, Turnable, TurtlePlan, WithCommands}, builders::{
CurvedMovement, DirectionalMovement, InvisibleLinesPlan, StopLine, Turnable, TurtlePlan,
WithCommands,
},
commands::{TurtleCommands, TurtleSegment}, commands::{TurtleCommands, TurtleSegment},
general::Speed, general::Speed,
shapes::{self, TurtleColors}, shapes::{self, TurtleColors},
@ -87,6 +90,13 @@ impl WithCommands for TurtleBundle {
self.commands.get_commands() self.commands.get_commands()
} }
} }
impl StopLine<TurtleBundle> for TurtleBundle {
fn pen_up(self) -> crate::builders::InvisibleLinesPlan<TurtleBundle> {
{
InvisibleLinesPlan::new(self)
}
}
}
impl DirectionalMovement for TurtleBundle {} impl DirectionalMovement for TurtleBundle {}
impl Turnable for TurtleBundle {} impl Turnable for TurtleBundle {}