Skip to content
Snippets Groups Projects
Commit acc9c7d5 authored by StarArawn's avatar StarArawn
Browse files

Working on getting global state working.

parent 75306334
No related branches found
No related tags found
No related merge requests found
assets/panel.png

1.19 KiB

...@@ -6,11 +6,11 @@ use kayak_core::{ ...@@ -6,11 +6,11 @@ use kayak_core::{
styles::{Style, StyleProp, Units}, styles::{Style, StyleProp, Units},
}; };
pub struct BevyContext { pub struct BevyContext<'a> {
pub kayak_context: Arc<RwLock<KayakContext>>, 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 { pub fn new<F: Fn(&mut Style, &mut KayakContext)>(width: f32, height: f32, f: F) -> Self {
let mut app_styles = Style { let mut app_styles = Style {
render_command: StyleProp::Value(RenderCommand::Window), render_command: StyleProp::Value(RenderCommand::Window),
...@@ -23,9 +23,6 @@ impl BevyContext { ...@@ -23,9 +23,6 @@ impl BevyContext {
if let Ok(mut kayak_context) = kayak_context.write() { if let Ok(mut kayak_context) = kayak_context.write() {
f(&mut app_styles, &mut kayak_context); f(&mut app_styles, &mut kayak_context);
kayak_context.render();
kayak_context.widget_manager.dirty(true); kayak_context.widget_manager.dirty(true);
} }
......
use bevy::{ use bevy::{
input::{mouse::MouseButtonInput, ElementState}, input::{mouse::MouseButtonInput, ElementState},
math::Vec2, math::Vec2,
prelude::{EventReader, MouseButton, Plugin, Res, ResMut}, prelude::{
EventReader, IntoExclusiveSystem, IntoSystem, MouseButton, Mut, Plugin, Res, ResMut, World,
},
render2::color::Color, render2::color::Color,
window::{CursorMoved, Windows}, window::{CursorMoved, Windows},
}; };
...@@ -12,7 +14,7 @@ mod render; ...@@ -12,7 +14,7 @@ mod render;
pub use bevy_context::BevyContext; pub use bevy_context::BevyContext;
pub use camera::*; pub use camera::*;
use kayak_core::InputEvent; use kayak_core::{context::GlobalState, InputEvent};
#[derive(Default)] #[derive(Default)]
pub struct BevyKayakUIPlugin; pub struct BevyKayakUIPlugin;
...@@ -21,7 +23,7 @@ impl Plugin for BevyKayakUIPlugin { ...@@ -21,7 +23,7 @@ impl Plugin for BevyKayakUIPlugin {
fn build(&self, app: &mut bevy::prelude::App) { fn build(&self, app: &mut bevy::prelude::App) {
app.add_plugin(render::BevyKayakUIRenderPlugin) app.add_plugin(render::BevyKayakUIRenderPlugin)
.add_plugin(camera::KayakUICameraPlugin) .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 { ...@@ -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) Color::rgba(color.r, color.g, color.b, color.a)
} }
pub fn update( pub struct WrappedWorld<'a> {
bevy_context: ResMut<BevyContext>, world: &'a mut World,
mut cursor_moved_events: EventReader<CursorMoved>, }
mut mouse_button_input_events: EventReader<MouseButtonInput>,
windows: Res<Windows>, impl<'a> GlobalState for WrappedWorld<'a> {}
) {
let window_size = if let Some(window) = windows.get_primary() { pub fn update(world: &mut World) {
Vec2::new(window.width(), window.height()) let window_size = {
} else { let windows = world.get_resource::<Windows>().unwrap();
panic!("Couldn't find primary window!"); 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() { 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(); let mut input_events = Vec::new();
for event in cursor_moved_events.iter() {
input_events.push(InputEvent::MouseMoved(( {
event.position.x as f32, let mut cursor_moved_events = world
window_size.y - event.position.y as f32, .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 { let mut mouse_button_input_events = world
MouseButton::Left => { .get_resource_mut::<EventReader<MouseButtonInput>>()
if event.state == ElementState::Pressed { .unwrap();
input_events.push(InputEvent::MouseLeftClick); 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); context.process_events(input_events);
} }
world.insert_resource(bevy_context);
} }
...@@ -14,7 +14,7 @@ use super::{font::KayakFont, font_mapping::FontMapping}; ...@@ -14,7 +14,7 @@ use super::{font::KayakFont, font_mapping::FontMapping};
pub fn extract_texts( pub fn extract_texts(
mut commands: Commands, mut commands: Commands,
context: Res<BevyContext>, context: Res<BevyContext<'static>>,
mut fonts: ResMut<Assets<KayakFont>>, mut fonts: ResMut<Assets<KayakFont>>,
font_mapping: Res<FontMapping>, font_mapping: Res<FontMapping>,
) { ) {
......
...@@ -10,7 +10,7 @@ use crate::{ ...@@ -10,7 +10,7 @@ use crate::{
to_bevy_color, BevyContext, 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() { let render_commands = if let Ok(context) = context.kayak_context.read() {
context.widget_manager.build_render_primitives() context.widget_manager.build_render_primitives()
} else { } else {
......
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}
</>
}
}
use std::collections::HashMap; use std::collections::HashMap;
use as_any::AsAny;
use resources::Ref; use resources::Ref;
use crate::{node::NodeIndex, widget_manager::WidgetManager, Event, EventType, Index, InputEvent}; 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>, component_states: HashMap<crate::Index, resources::Resources>,
current_id: crate::Index, current_id: crate::Index,
pub widget_manager: WidgetManager, pub widget_manager: WidgetManager,
last_mouse_position: (f32, f32), 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 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("KayakContext") f.debug_struct("KayakContext")
.field("current_id", &self.current_id) .field("current_id", &self.current_id)
...@@ -19,13 +23,14 @@ impl std::fmt::Debug for KayakContext { ...@@ -19,13 +23,14 @@ impl std::fmt::Debug for KayakContext {
} }
} }
impl KayakContext { impl<'a> KayakContext<'a> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
component_states: HashMap::new(), component_states: HashMap::new(),
current_id: crate::Index::default(), current_id: crate::Index::default(),
widget_manager: WidgetManager::new(), widget_manager: WidgetManager::new(),
last_mouse_position: (0.0, 0.0), last_mouse_position: (0.0, 0.0),
global_state: None,
} }
} }
...@@ -78,7 +83,9 @@ impl KayakContext { ...@@ -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(); let dirty_nodes = self.widget_manager.dirty_nodes.clone();
for node_index in dirty_nodes { for node_index in dirty_nodes {
if self if self
...@@ -97,6 +104,8 @@ impl KayakContext { ...@@ -97,6 +104,8 @@ impl KayakContext {
self.widget_manager.render(); self.widget_manager.render();
self.widget_manager.calculate_layout(); self.widget_manager.calculate_layout();
self.global_state = None;
} }
pub fn process_events(&mut self, input_events: Vec<InputEvent>) { pub fn process_events(&mut self, input_events: Vec<InputEvent>) {
......
...@@ -22,8 +22,15 @@ pub use input_event::*; ...@@ -22,8 +22,15 @@ pub use input_event::*;
pub use kayak_render_macros::{render, rsx, widget}; pub use kayak_render_macros::{render, rsx, widget};
pub use widget::Widget; pub use widget::Widget;
pub type Children = pub type Children = Option<
Option<Arc<dyn Fn(Option<crate::Index>, &mut crate::context::KayakContext) + Send + Sync>>; Arc<
dyn for<'global_state> Fn(
Option<crate::Index>,
&mut crate::context::KayakContext,
) + Send
+ Sync,
>,
>;
#[derive(Clone)] #[derive(Clone)]
pub struct OnEvent( pub struct OnEvent(
......
...@@ -9,6 +9,9 @@ pub enum RenderCommand { ...@@ -9,6 +9,9 @@ pub enum RenderCommand {
size: f32, size: f32,
font: u16, font: u16,
}, },
Image {
handle: u16,
},
} }
impl Default for RenderCommand { impl Default for RenderCommand {
......
...@@ -23,6 +23,9 @@ pub enum RenderPrimitive { ...@@ -23,6 +23,9 @@ pub enum RenderPrimitive {
content: String, content: String,
font: u16, font: u16,
}, },
Image {
handle: u16,
},
} }
impl RenderPrimitive { impl RenderPrimitive {
...@@ -68,6 +71,7 @@ impl From<&Style> for RenderPrimitive { ...@@ -68,6 +71,7 @@ impl From<&Style> for RenderPrimitive {
content, content,
font, font,
}, },
RenderCommand::Image { handle } => Self::Image { handle },
} }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment