From acc9c7d5d05e85f8612946f4285324d3dfad4a13 Mon Sep 17 00:00:00 2001 From: StarArawn <toasterthegamer@gmail.com> Date: Sun, 5 Dec 2021 11:06:03 -0500 Subject: [PATCH] Working on getting global state working. --- assets/panel.png | Bin 0 -> 1215 bytes bevy_kayak_ui/src/bevy_context.rs | 9 +-- bevy_kayak_ui/src/lib.rs | 73 ++++++++++++------ .../src/render/unified/font/extract.rs | 2 +- .../src/render/unified/quad/extract.rs | 2 +- kayak_components/src/image.rs | 15 ++++ kayak_core/src/context.rs | 17 +++- kayak_core/src/lib.rs | 11 ++- kayak_core/src/render_command.rs | 3 + kayak_core/src/render_primitive.rs | 4 + 10 files changed, 97 insertions(+), 39 deletions(-) create mode 100644 assets/panel.png create mode 100644 kayak_components/src/image.rs diff --git a/assets/panel.png b/assets/panel.png new file mode 100644 index 0000000000000000000000000000000000000000..739934c54b3e2103ddc44c3283f03c9dc08ac4a5 GIT binary patch literal 1215 zcmV;w1VH<VP)<h;3K|Lk000e1NJLTq004jh004jp1^@s6!#-il00001b5ch_0Itp) z=>Px(c}YY;RCt{2ozHRVFc60~nOvzOGaNEBkQ)_IK`NkxbU+2+<^~Lh%%qAOC?M~U zNN-W(KNtg!e&09qCVqg$TKm&#g(dm!?e*o$K$6Yw(;mVB=&`TsZvmK@Evw4R%+|A+ znVGE)2irbB_bzN%RY&KV*-7X3DRVuW#j@A4nLRBQCzlt_^>&8WhT6Ta>m$2@t>HVy zsE5?<v3zs)_WJU**?ro+u1~H|_?rY@A4P!G;b7aJH;3}^{+@mPaXueh=9qlEzuV({ z-e_lzKDOt|yY)4PYfX=z7K`X>Gqd|}LI@G(l3w_&E5ehrCA{YU`hR`P^`8wQ3&J=> zaAT3$;O+3fzW;URK>Qb_l{z)NeW{a%I4e|i5Q1-U{`;;)>i9NB6M&f=g`6SAT$9v6 z=Qt@B0X)~f{w{kwQ2;(89{Q!>LcIa!R_>*_WJ|qOBut}m+6cX`FA@R%G9_I@A90VK z1j2Oi5!pw8Y!b+C0OgSz2AUoFdeklerb(|P5XvVf1Oy<?F9A$(%np~MH3A@p@@W*n zkQ*oP_s9wWr|XavKrUNE6lKyG0j7Ru56**Opg65v0Aas;S|b2qzkC`6fb%sV2N0mG zEB_?`T7G%7<#a><aiRduSq}iy$G3j(>(M5K!u0S{-F?@dofOKP!1Bnge=xhy!Vs7? zowI^L69iB=T|eiO1Qt#%^j~ac5d1w5fH({T1xWJ%hJj+RG6>A9V`UJd03G-#SR8Ty zh#&xQ$N>Z)2M~uG03rxL90VW^NuVIDw}V*^s0CesI1B>?VHgMz_6QOuI|^WdXqkkD z-T6~65uj{3a{%@SERQCCvR%9&o!iCJ`pcs!uY1V7ND`<+V+6S6Gw<Mf@I#O|o!i9G z9h40_g$i-<BV%a&<wFi24gwH|okGPS0*HeE#6bY!AOLX?fH>?HE(p7Yi^E2d5J3Rq zAOLY#8YT!!!yv*aK#1NegP?4(T>ue42O@wtL;!J!0ODjL0E<I)=v*8M<<Yr395g`y z;vfJ4(x-=e5P&!cK!CPApAdiubODeB0f@u2Z~@Z(pK0M@r2T*E%^<dgDIabJi^J_; zakw2U4!46Lf&j!p079I+Q6!WP0uToQh=Tyci2_(w)h+FSE8>04R<YvH1&G7F072Lx z1R@APoMPt#FtOzrUmv~a1Nf7sUZJUd>Z6&Q@50~SIY3&8Qxbu{sJ5j~>V&%KTo=&P z1%!%jE99D_4sWw*N`k!=x%%lfDKyuzZe5{WT~ZqArXbj<;C<QJ1^9Jj>6)@zKTy&~ zp<r9izP7b+rPJg)|DGp4J$!XI*w(#~R;G9U6k1l!4ppane4V5XHvHfFI!1u)^K<-g zQ_G(UP4<KcF*SRyP5Sirv_68b&CKrJUSGa8yH8tI)zKSJF2UFPy8hn<tY<S@xi?ma zLrfOZ<M?@ZeD1XJ@SVQwQ_F3#d#G(=l;_L1bbW<mZ)<AzvZ}t1f69pw0QA_`wLNTh dpR5cP<{v6bh=U}asq6p%002ovPDHLkV1n3OFF*hQ literal 0 HcmV?d00001 diff --git a/bevy_kayak_ui/src/bevy_context.rs b/bevy_kayak_ui/src/bevy_context.rs index 0c2c974..6708d8e 100644 --- a/bevy_kayak_ui/src/bevy_context.rs +++ b/bevy_kayak_ui/src/bevy_context.rs @@ -6,11 +6,11 @@ use kayak_core::{ styles::{Style, StyleProp, Units}, }; -pub struct BevyContext { - pub kayak_context: Arc<RwLock<KayakContext>>, +pub struct BevyContext<'a> { + pub kayak_context: Arc<RwLock<KayakContext<'a>>>, } -impl BevyContext { +impl<'a> BevyContext<'a> { pub fn new<F: Fn(&mut Style, &mut KayakContext)>(width: f32, height: f32, f: F) -> Self { let mut app_styles = Style { render_command: StyleProp::Value(RenderCommand::Window), @@ -23,9 +23,6 @@ impl BevyContext { if let Ok(mut kayak_context) = kayak_context.write() { f(&mut app_styles, &mut kayak_context); - - kayak_context.render(); - kayak_context.widget_manager.dirty(true); } diff --git a/bevy_kayak_ui/src/lib.rs b/bevy_kayak_ui/src/lib.rs index fee1bbc..ced7953 100644 --- a/bevy_kayak_ui/src/lib.rs +++ b/bevy_kayak_ui/src/lib.rs @@ -1,7 +1,9 @@ use bevy::{ input::{mouse::MouseButtonInput, ElementState}, math::Vec2, - prelude::{EventReader, MouseButton, Plugin, Res, ResMut}, + prelude::{ + EventReader, IntoExclusiveSystem, IntoSystem, MouseButton, Mut, Plugin, Res, ResMut, World, + }, render2::color::Color, window::{CursorMoved, Windows}, }; @@ -12,7 +14,7 @@ mod render; pub use bevy_context::BevyContext; pub use camera::*; -use kayak_core::InputEvent; +use kayak_core::{context::GlobalState, InputEvent}; #[derive(Default)] pub struct BevyKayakUIPlugin; @@ -21,7 +23,7 @@ impl Plugin for BevyKayakUIPlugin { fn build(&self, app: &mut bevy::prelude::App) { app.add_plugin(render::BevyKayakUIRenderPlugin) .add_plugin(camera::KayakUICameraPlugin) - .add_system(update); + .add_system(update.exclusive_system()); } } @@ -29,40 +31,61 @@ pub(crate) fn to_bevy_color(color: &kayak_core::color::Color) -> Color { Color::rgba(color.r, color.g, color.b, color.a) } -pub fn update( - bevy_context: ResMut<BevyContext>, - mut cursor_moved_events: EventReader<CursorMoved>, - mut mouse_button_input_events: EventReader<MouseButtonInput>, - windows: Res<Windows>, -) { - let window_size = if let Some(window) = windows.get_primary() { - Vec2::new(window.width(), window.height()) - } else { - panic!("Couldn't find primary window!"); +pub struct WrappedWorld<'a> { + world: &'a mut World, +} + +impl<'a> GlobalState for WrappedWorld<'a> {} + +pub fn update(world: &mut World) { + let window_size = { + let windows = world.get_resource::<Windows>().unwrap(); + if let Some(window) = windows.get_primary() { + Vec2::new(window.width(), window.height()) + } else { + panic!("Couldn't find primary window!"); + } }; + let bevy_context = world.remove_resource::<BevyContext<'static>>().unwrap(); if let Ok(mut context) = bevy_context.kayak_context.write() { - context.render(); + let mut wrapped_world = WrappedWorld { world }; + context.render(&mut wrapped_world); + } + if let Ok(mut context) = bevy_context.kayak_context.write() { let mut input_events = Vec::new(); - for event in cursor_moved_events.iter() { - input_events.push(InputEvent::MouseMoved(( - event.position.x as f32, - window_size.y - event.position.y as f32, - ))); + + { + let mut cursor_moved_events = world + .get_resource_mut::<EventReader<CursorMoved>>() + .unwrap(); + for event in cursor_moved_events.iter() { + input_events.push(InputEvent::MouseMoved(( + event.position.x as f32, + window_size.y - event.position.y as f32, + ))); + } } - for event in mouse_button_input_events.iter() { - match event.button { - MouseButton::Left => { - if event.state == ElementState::Pressed { - input_events.push(InputEvent::MouseLeftClick); + { + let mut mouse_button_input_events = world + .get_resource_mut::<EventReader<MouseButtonInput>>() + .unwrap(); + for event in mouse_button_input_events.iter() { + match event.button { + MouseButton::Left => { + if event.state == ElementState::Pressed { + input_events.push(InputEvent::MouseLeftClick); + } } + _ => {} } - _ => {} } } context.process_events(input_events); } + + world.insert_resource(bevy_context); } diff --git a/bevy_kayak_ui/src/render/unified/font/extract.rs b/bevy_kayak_ui/src/render/unified/font/extract.rs index ce8844d..585f124 100644 --- a/bevy_kayak_ui/src/render/unified/font/extract.rs +++ b/bevy_kayak_ui/src/render/unified/font/extract.rs @@ -14,7 +14,7 @@ use super::{font::KayakFont, font_mapping::FontMapping}; pub fn extract_texts( mut commands: Commands, - context: Res<BevyContext>, + context: Res<BevyContext<'static>>, mut fonts: ResMut<Assets<KayakFont>>, font_mapping: Res<FontMapping>, ) { diff --git a/bevy_kayak_ui/src/render/unified/quad/extract.rs b/bevy_kayak_ui/src/render/unified/quad/extract.rs index 20a4c8e..1290ae5 100644 --- a/bevy_kayak_ui/src/render/unified/quad/extract.rs +++ b/bevy_kayak_ui/src/render/unified/quad/extract.rs @@ -10,7 +10,7 @@ use crate::{ to_bevy_color, BevyContext, }; -pub fn extract_quads(mut commands: Commands, context: Res<BevyContext>) { +pub fn extract_quads(mut commands: Commands, context: Res<BevyContext<'static>>) { let render_commands = if let Ok(context) = context.kayak_context.read() { context.widget_manager.build_render_primitives() } else { diff --git a/kayak_components/src/image.rs b/kayak_components/src/image.rs new file mode 100644 index 0000000..f67f293 --- /dev/null +++ b/kayak_components/src/image.rs @@ -0,0 +1,15 @@ +use kayak_core::{component, rsx, Render, Update}; + +#[component] +pub fn Image<Children: Render + Update + Clone>(handle: u16, children: Children) { + *styles = Some(Style { + render_command: StyleProp::Value(RenderCommand::Image { handle }), + ..styles.clone().unwrap_or_default() + }); + + rsx! { + <> + {children} + </> + } +} diff --git a/kayak_core/src/context.rs b/kayak_core/src/context.rs index b18aa0e..bcd89da 100644 --- a/kayak_core/src/context.rs +++ b/kayak_core/src/context.rs @@ -1,17 +1,21 @@ use std::collections::HashMap; +use as_any::AsAny; use resources::Ref; use crate::{node::NodeIndex, widget_manager::WidgetManager, Event, EventType, Index, InputEvent}; -pub struct KayakContext { +pub trait GlobalState: Send + Sync {} + +pub struct KayakContext<'a> { component_states: HashMap<crate::Index, resources::Resources>, current_id: crate::Index, pub widget_manager: WidgetManager, last_mouse_position: (f32, f32), + global_state: Option<&'a mut dyn GlobalState>, } -impl std::fmt::Debug for KayakContext { +impl<'a> std::fmt::Debug for KayakContext<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("KayakContext") .field("current_id", &self.current_id) @@ -19,13 +23,14 @@ impl std::fmt::Debug for KayakContext { } } -impl KayakContext { +impl<'a> KayakContext<'a> { pub fn new() -> Self { Self { component_states: HashMap::new(), current_id: crate::Index::default(), widget_manager: WidgetManager::new(), last_mouse_position: (0.0, 0.0), + global_state: None, } } @@ -78,7 +83,9 @@ impl KayakContext { } } - pub fn render(&mut self) { + pub fn render(&mut self, global_state: &'a mut dyn GlobalState) { + self.global_state = Some(global_state); + let dirty_nodes = self.widget_manager.dirty_nodes.clone(); for node_index in dirty_nodes { if self @@ -97,6 +104,8 @@ impl KayakContext { self.widget_manager.render(); self.widget_manager.calculate_layout(); + + self.global_state = None; } pub fn process_events(&mut self, input_events: Vec<InputEvent>) { diff --git a/kayak_core/src/lib.rs b/kayak_core/src/lib.rs index 47009cc..268b555 100644 --- a/kayak_core/src/lib.rs +++ b/kayak_core/src/lib.rs @@ -22,8 +22,15 @@ pub use input_event::*; pub use kayak_render_macros::{render, rsx, widget}; pub use widget::Widget; -pub type Children = - Option<Arc<dyn Fn(Option<crate::Index>, &mut crate::context::KayakContext) + Send + Sync>>; +pub type Children = Option< + Arc< + dyn for<'global_state> Fn( + Option<crate::Index>, + &mut crate::context::KayakContext, + ) + Send + + Sync, + >, +>; #[derive(Clone)] pub struct OnEvent( diff --git a/kayak_core/src/render_command.rs b/kayak_core/src/render_command.rs index 31f034e..cb6839f 100644 --- a/kayak_core/src/render_command.rs +++ b/kayak_core/src/render_command.rs @@ -9,6 +9,9 @@ pub enum RenderCommand { size: f32, font: u16, }, + Image { + handle: u16, + }, } impl Default for RenderCommand { diff --git a/kayak_core/src/render_primitive.rs b/kayak_core/src/render_primitive.rs index 3208f6c..433c216 100644 --- a/kayak_core/src/render_primitive.rs +++ b/kayak_core/src/render_primitive.rs @@ -23,6 +23,9 @@ pub enum RenderPrimitive { content: String, font: u16, }, + Image { + handle: u16, + }, } impl RenderPrimitive { @@ -68,6 +71,7 @@ impl From<&Style> for RenderPrimitive { content, font, }, + RenderCommand::Image { handle } => Self::Image { handle }, } } } -- GitLab