Skip to content

Commit

Permalink
with value now returns whatever the closure returns
Browse files Browse the repository at this point in the history
  • Loading branch information
togglebyte committed Aug 31, 2024
1 parent 4c064a5 commit 4e431e5
Show file tree
Hide file tree
Showing 9 changed files with 374 additions and 413 deletions.
281 changes: 105 additions & 176 deletions anathema-runtime/src/events.rs

Large diffs are not rendered by default.

170 changes: 76 additions & 94 deletions anathema-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,20 @@ use anathema_widgets::components::{
use anathema_widgets::layout::text::StringStorage;
use anathema_widgets::layout::{layout_widget, position_widget, Constraints, LayoutCtx, LayoutFilter, Viewport};
use anathema_widgets::{
eval_blueprint, try_resolve_future_values, update_tree, AttributeStorage, Components, Elements, EvalContext,
Factory, FloatingWidgets, Scope, WidgetKind, WidgetTree,
eval_blueprint, try_resolve_future_values, update_tree, AttributeStorage, Components, EvalContext, Factory,
FloatingWidgets, Scope, WidgetKind, WidgetTree,
};
use events::EventHandler;
use events::{EventCtx, EventHandler};
use notify::{recommended_watcher, Event, RecommendedWatcher, RecursiveMode, Watcher};
use tree::Tree;

pub use crate::error::{Error, Result};

static REBUILD: AtomicBool = AtomicBool::new(false);

mod error;
mod events;
mod tree;

pub struct RuntimeBuilder<T> {
document: Document,
Expand Down Expand Up @@ -165,7 +167,6 @@ impl<T> RuntimeBuilder<T> {
future_values: FutureValues::empty(),

changes: Changes::empty(),
// tab_indices: TabIndices::new(),
component_registry: self.component_registry,
globals,
document: self.document,
Expand Down Expand Up @@ -307,13 +308,6 @@ where
return;
}

// use std::io::Write;
// let mut file = std::fs::OpenOptions::new()
// .append(true)
// .write(true)
// .open("/tmp/log.lol").unwrap();
// file.write(format!("{}\n", self.changes.len()).as_bytes()).unwrap();

let mut scope = Scope::new();
self.changes.drain().rev().for_each(|(sub, change)| {
sub.iter().for_each(|sub| {
Expand Down Expand Up @@ -347,37 +341,28 @@ where
attribute_storage: &mut AttributeStorage<'bp>,
assoc_events: &mut AssociatedEvents,
) -> Duration {
let context = UntypedContext {
emitter: &self.emitter,
viewport: self.viewport,
strings: &mut self.document.strings,
};

let mut event_ctx = EventCtx {
components: &mut self.components,
states,
attribute_storage,
assoc_events,
context,
};

while let Ok(msg) = self.message_receiver.try_recv() {
if let Some((widget_id, state_id)) = self
if let Some((widget_id, state_id)) = event_ctx
.components
.get_by_component_id(msg.recipient())
.map(|e| (e.widget_id, e.state_id))
{
tree.with_value_mut(widget_id, |path, widget, tree| {
let WidgetKind::Component(component) = widget else { return };
let state = states.get_mut(state_id);

let parent = component
.parent
.and_then(|parent| self.components.get_by_component_id(parent))
.map(|parent| parent.component_id.into());

let Some((node, values)) = tree.get_node_by_path(path) else { return };
let elements = Elements::new(node.children(), values, attribute_storage);

let context = UntypedContext {
emitter: &self.emitter,
viewport: self.viewport,
assoc_events,
state_id,
parent,
strings: &mut self.document.strings,
assoc_functions: component.assoc_functions,
};

component
.dyn_component
.any_message(msg.payload(), state, elements, context);
tree.with_component(widget_id, state_id, &mut event_ctx, |a, b| {
a.any_message(msg.payload(), b)
});
}

Expand Down Expand Up @@ -438,31 +423,27 @@ where
}
}

// Select the first widget
if let Some((widget_id, state_id)) = self.components.current() {
tree.with_value_mut(widget_id, |path, widget, tree| {
let WidgetKind::Component(component) = widget else { return };
let state = states.get_mut(state_id);

let parent = component
.parent
.and_then(|parent| self.components.get_by_component_id(parent))
.map(|parent| parent.component_id.into());

let Some((node, values)) = tree.get_node_by_path(path) else { return };
let elements = Elements::new(node.children(), values, &mut attribute_storage);
let context = UntypedContext {
emitter: &self.emitter,
viewport: self.viewport,
assoc_events: &mut assoc_events,
state_id,
parent,
strings: &mut self.document.strings,
assoc_functions: component.assoc_functions,
};
component.dyn_component.any_focus(state, elements, context);
});
}
// // Select the first widget
// if let Some((widget_id, state_id)) = self.components.current() {
// tree.with_value_mut(widget_id, |path, widget, tree| {
// let WidgetKind::Component(component) = widget else { return };
// let state = states.get_mut(state_id);

// let parent = component
// .parent
// .and_then(|parent| self.components.get_by_component_id(parent))
// .map(|parent| parent.component_id.into());

// let Some((node, values)) = tree.get_node_by_path(path) else { return };
// let elements = Elements::new(node.children(), values, &mut attribute_storage);

// let component_ctx = ComponentContext::new(state_id, component.parent, component.assoc_functions);

// component
// .dyn_component
// .any_focus(state, elements, context, component_ctx);
// });
// }

let mut dt = Instant::now();
loop {
Expand Down Expand Up @@ -557,24 +538,34 @@ where
// Clear the text buffer
self.string_storage.clear();

// Call the `tick` function on all components
self.tick_components(tree, states, attribute_storage, dt.elapsed(), assoc_events);

let context = UntypedContext {
emitter: &self.emitter,
viewport: self.viewport,
strings: &self.document.strings,
};

let mut event_ctx = EventCtx {
components: &mut self.components,
states,
attribute_storage,
assoc_events,
context,
};

self.event_handler.handle(
poll_duration,
fps_now,
sleep_micros,
&mut self.backend,
&mut self.viewport,
&self.emitter,
tree,
&mut self.components,
states,
attribute_storage,
&mut self.constraints,
assoc_events,
&self.document.strings,
&mut event_ctx,
)?;

// Call the `tick` function on all components
self.tick_components(tree, states, attribute_storage, dt.elapsed(), assoc_events);
*dt = Instant::now();

self.apply_futures(globals, tree, states, attribute_storage);
Expand Down Expand Up @@ -677,36 +668,27 @@ where
dt: Duration,
assoc_events: &mut AssociatedEvents,
) {
let context = UntypedContext {
emitter: &self.emitter,
viewport: self.viewport,
strings: &self.document.strings,
};

for i in 0..self.components.len() {
let (widget_id, state_id) = self
.components
.get(i)
.expect("the components can not change as a result of this step");

tree.with_value_mut(widget_id, |path, widget, tree| {
let WidgetKind::Component(component) = widget else { return };
let state = states.get_mut(state_id);

let parent = component
.parent
.and_then(|parent| self.components.get_by_component_id(parent))
.map(|parent| parent.component_id.into());

let Some((node, values)) = tree.get_node_by_path(path) else { return };
let elements = Elements::new(node.children(), values, attribute_storage);

let context = UntypedContext {
emitter: &self.emitter,
viewport: self.viewport,
assoc_events,
state_id,
parent,
strings: &mut self.document.strings,
assoc_functions: component.assoc_functions,
};

component.dyn_component.any_tick(state, elements, context, dt);
});
let mut event_ctx = EventCtx {
components: &mut self.components,
states,
attribute_storage,
assoc_events,
context,
};

tree.with_component(widget_id, state_id, &mut event_ctx, |a, b| a.any_tick(b, dt));
}
}
}
58 changes: 58 additions & 0 deletions anathema-runtime/src/tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use anathema_state::StateId;
use anathema_widgets::components::{AnyComponent, AnyEventCtx, ComponentContext};
use anathema_widgets::{Elements, WidgetId, WidgetKind, WidgetTree};

use crate::events::EventCtx;

pub(crate) trait Tree<'bp> {
fn with_component<F, V>(
&mut self,
widget_id: WidgetId,
state_id: StateId,
event_ctx: &mut EventCtx<'_, '_, 'bp>,
f: F,
) -> Option<V>
where
F: FnOnce(&mut dyn AnyComponent, AnyEventCtx<'_, '_, '_>) -> V;
}

impl<'bp> Tree<'bp> for WidgetTree<'bp> {
fn with_component<F, V>(
&mut self,
widget_id: WidgetId,
state_id: StateId,
event_ctx: &mut EventCtx<'_, '_, 'bp>,
f: F,
) -> Option<V>
where
F: FnOnce(&mut dyn AnyComponent, AnyEventCtx<'_, '_, '_>) -> V,
{
self.with_value_mut(widget_id, |path, widget, tree| {
let WidgetKind::Component(component) = widget else { return None };
if !component.dyn_component.accept_focus_any() {
return None;
}

let (node, values) = tree.get_node_by_path(path)?;
let elements = Elements::new(node.children(), values, event_ctx.attribute_storage);
let state = event_ctx.states.get_mut(state_id);

let component_ctx = ComponentContext::new(
state_id,
component.parent,
component.assoc_functions,
event_ctx.assoc_events,
);

let lol = AnyEventCtx {
state,
elements,
context: event_ctx.context,
component_ctx,
};

let value = f(&mut *component.dyn_component, lol);
Some(value)
})
}
}
20 changes: 10 additions & 10 deletions anathema-store/src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,25 +211,25 @@ impl<T> Tree<T> {

/// Perform a given operation (`F`) on a reference to a value in the tree
/// while still haveing mutable access to the rest of the tree.
pub fn with_value<F, R>(&mut self, value_id: ValueId, mut f: F) -> R
pub fn with_value<F, R>(&self, value_id: ValueId, mut f: F) -> Option<R>
where
F: FnMut(&[u16], &T, &mut Self) -> R,
F: FnMut(&[u16], &T, &Self) -> R,
{
let ticket = self.values.checkout(value_id);
let ret = f(&ticket.value.0, &ticket.value.1, self);
self.values.restore(ticket);
ret
let value = self.values.get(value_id)?;
let ret = f(&value.0, &value.1, self);
Some(ret)
}

/// Perform a given operation (`F`) on a mutable reference to a value in the tree
/// while still having mutable access to the rest of the tree.
pub fn with_value_mut<F>(&mut self, value_id: ValueId, f: F)
pub fn with_value_mut<F, V>(&mut self, value_id: ValueId, f: F) -> V
where
F: FnOnce(&[u16], &mut T, &mut Self),
F: FnOnce(&[u16], &mut T, &mut Self) -> V,
{
let mut ticket = self.values.checkout(value_id);
f(&ticket.value.0, &mut ticket.value.1, self);
let value = f(&ticket.value.0, &mut ticket.value.1, self);
self.values.restore(ticket);
value
}

/// Get mutable access to a node value along with the children
Expand Down Expand Up @@ -577,7 +577,7 @@ mod test {
let mut tree = Tree::empty();
let key = tree.insert(root_node()).commit_child(0).unwrap();
tree.insert(root_node()).commit_child(1);
tree.with_value(key, |_path, _value, tree| {
tree.with_value_mut(key, |_path, _value, tree| {
// The value is already checked out
assert!(tree.get_ref_by_id(key).is_none());
});
Expand Down
Loading

0 comments on commit 4e431e5

Please sign in to comment.