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

Global bindings.

parent 51173301
No related branches found
No related tags found
No related merge requests found
......@@ -1482,13 +1482,13 @@ checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e"
[[package]]
name = "flo_binding"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711a65cd60b91114a1cecbf6a9d533c3fde6e38532506cde25bc5f7bc87d2fa0"
version = "2.0.2"
source = "git+https://github.com/StarArawn/flo_binding.git?rev=609883068c43dc897da2b277e91320a41892643d#609883068c43dc897da2b277e91320a41892643d"
dependencies = [
"desync",
"flo_rope",
"futures",
"uuid",
]
[[package]]
......
use bevy::{
math::Vec2,
prelude::{App as BevyApp, AssetServer, Commands, Res, ResMut, World},
window::{WindowDescriptor, Windows},
PipelinedDefaultPlugins,
};
use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle};
use kayak_components::{Text, Window};
use kayak_core::{bind, Binding, Bound, Index, MutableBound};
use kayak_ui::components::App;
use kayak_ui::core::{rsx, widget};
#[derive(Clone, PartialEq)]
struct GlobalCount(pub u32);
#[widget]
fn Counter(context: &mut KayakContext) {
let global_count = {
if let Ok(world) = context.get_global_state::<World>() {
if let Some(global_count) = world.get_resource::<Binding<GlobalCount>>() {
global_count.clone()
} else {
return;
}
} else {
return;
}
};
context.bind(&global_count);
let global_count = global_count.get().0;
rsx! {
<>
<Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"Counter Example".to_string()}>
<Text size={32.0} content={format!("Current Count: {}", global_count).to_string()}>{}</Text>
</Window>
</>
}
}
fn startup(
mut commands: Commands,
windows: Res<Windows>,
mut font_mapping: ResMut<FontMapping>,
asset_server: Res<AssetServer>,
) {
commands.spawn_bundle(UICameraBundle::new());
font_mapping.add(asset_server.load("roboto.kayak_font"));
let window_size = if let Some(window) = windows.get_primary() {
Vec2::new(window.width(), window.height())
} else {
panic!("Couldn't find primary window!");
};
commands.insert_resource(bind(GlobalCount(0)));
let context = BevyContext::new(window_size.x, window_size.y, |styles, context| {
// Hack to trick the proc macro for right now..
let parent_id: Option<Index> = None;
rsx! {
<App styles={Some(styles.clone())}>
<Counter />
</App>
}
});
commands.insert_resource(context);
}
fn count_up(global_count: Res<Binding<GlobalCount>>) {
global_count.set(GlobalCount(global_count.get().0 + 1));
}
fn main() {
BevyApp::new()
.insert_resource(WindowDescriptor {
width: 1270.0,
height: 720.0,
title: String::from("UI Example"),
..Default::default()
})
.add_plugins(PipelinedDefaultPlugins)
.add_plugin(BevyKayakUIPlugin)
.add_startup_system(startup)
.add_system(count_up)
.run();
}
......@@ -10,7 +10,7 @@ as-any = "0.2"
dashmap = "4.0"
diff-struct = "0.3"
derivative = "2.2"
flo_binding = "2.0.1"
flo_binding = { git = "https://github.com/StarArawn/flo_binding.git", rev = "609883068c43dc897da2b277e91320a41892643d" }
fontdue = "0.6"
kayak_render_macros = { path = "../kayak_render_macros" }
morphorm = { git = "https://github.com/geom3trik/morphorm" }
......
......@@ -5,6 +5,7 @@ use crate::{node::NodeIndex, widget_manager::WidgetManager, Event, EventType, In
pub struct KayakContext {
component_states: HashMap<crate::Index, resources::Resources>,
global_bindings: HashMap<crate::Index, Vec<flo_binding::Uuid>>,
// component_state_lifetimes: DashMap<crate::Index, Vec<Box<dyn crate::Releasable>>>,
current_id: Index,
pub widget_manager: WidgetManager,
......@@ -25,6 +26,7 @@ impl KayakContext {
pub fn new() -> Self {
Self {
component_states: HashMap::new(),
global_bindings: HashMap::new(),
// component_state_lifetimes: DashMap::new(),
current_id: crate::Index::default(),
widget_manager: WidgetManager::new(),
......@@ -34,6 +36,46 @@ impl KayakContext {
}
}
/// Binds some global state to the current widget.
pub fn bind<T: Clone + PartialEq + Send + 'static>(
&mut self,
global_state: &crate::Binding<T>,
) {
if !self.global_bindings.contains_key(&self.current_id) {
self.global_bindings.insert(self.current_id, vec![]);
}
let global_binding_ids = self.global_bindings.get_mut(&self.current_id).unwrap();
if !global_binding_ids.contains(&global_state.id) {
let cloned_id = self.current_id;
let dirty_nodes = self.widget_manager.dirty_nodes.clone();
let mut lifetime = global_state.when_changed(crate::notify(move || {
if let Ok(mut dirty_nodes) = dirty_nodes.lock() {
dirty_nodes.insert(cloned_id);
}
}));
// TODO: Figure out how to store this so we can drop the lifetime on unbind.
lifetime.keep_alive();
global_binding_ids.push(global_state.id);
}
}
pub fn unbind<T: Clone + PartialEq + Send + 'static>(
&mut self,
global_state: &crate::Binding<T>,
) {
if self.global_bindings.contains_key(&self.current_id) {
let global_binding_ids = self.global_bindings.get_mut(&self.current_id).unwrap();
if let Some(index) = global_binding_ids
.iter()
.position(|id| *id == global_state.id)
{
global_binding_ids.remove(index);
}
}
}
pub fn set_current_id(&mut self, id: crate::Index) {
self.current_id = id;
}
......
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