Skip to content

Commit

Permalink
Add AdaptState view
Browse files Browse the repository at this point in the history
Co-authored-by: Philipp Mildenberger <philipp@mildenberger.me>
  • Loading branch information
jplatte and Philipp-M authored Jul 17, 2023
1 parent 0c61390 commit 2b86d1d
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 2 deletions.
72 changes: 72 additions & 0 deletions crates/xilem_core/src/view/adapt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,75 @@ macro_rules! generate_adapt_view {
}
};
}

#[macro_export]
macro_rules! generate_adapt_state_view {
($viewtrait:ident, $cx:ty, $changeflags:ty) => {
/// A view that wraps a child view and modifies the state that callbacks have access to.
pub struct AdaptState<
ParentT,
ChildT,
V,
F: Fn(&mut ParentT) -> &mut ChildT = fn(&mut ParentT) -> &mut ChildT,
> {
f: F,
child: V,
phantom: std::marker::PhantomData<fn() -> (ParentT, ChildT)>,
}

impl<ParentT, ChildT, V, F: Fn(&mut ParentT) -> &mut ChildT + Send>
AdaptState<ParentT, ChildT, V, F>
{
pub fn new(f: F, child: V) -> Self {
Self {
f,
child,
phantom: Default::default(),
}
}
}

impl<
ParentT,
ChildT,
A,
V: $viewtrait<ChildT, A>,
F: Fn(&mut ParentT) -> &mut ChildT + Send,
> $viewtrait<ParentT, A> for AdaptState<ParentT, ChildT, V, F>
{
type State = V::State;
type Element = V::Element;

fn build(&self, cx: &mut $cx) -> ($crate::Id, Self::State, Self::Element) {
self.child.build(cx)
}

fn rebuild(
&self,
cx: &mut $cx,
prev: &Self,
id: &mut $crate::Id,
state: &mut Self::State,
element: &mut Self::Element,
) -> $changeflags {
self.child.rebuild(cx, &prev.child, id, state, element)
}

fn message(
&self,
id_path: &[$crate::Id],
state: &mut Self::State,
message: Box<dyn std::any::Any>,
app_state: &mut ParentT,
) -> $crate::MessageResult<A> {
self.child
.message(id_path, state, message, (self.f)(app_state))
}
}

impl<ParentT, ChildT, V, F: Fn(&mut ParentT) -> &mut ChildT> ViewMarker
for AdaptState<ParentT, ChildT, V, F>
{
}
};
}
4 changes: 3 additions & 1 deletion crates/xilem_html/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ pub use element::{element, Element, ElementState};
#[cfg(feature = "typed")]
pub use event::events;
pub use event::{on_event, Action, Event, OnEvent, OnEventState, OptionalAction};
pub use view::{Adapt, AdaptThunk, AnyView, Either, Pod, View, ViewMarker, ViewSequence};
pub use view::{
Adapt, AdaptState, AdaptThunk, AnyView, Either, Pod, View, ViewMarker, ViewSequence,
};
#[cfg(feature = "typed")]
pub use view_ext::ViewExt;

Expand Down
1 change: 1 addition & 0 deletions crates/xilem_html/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ xilem_core::generate_viewsequence_trait! {ViewSequence, View, ViewMarker, DomNod
xilem_core::generate_anyview_trait! {AnyView, View, ViewMarker, Cx, ChangeFlags, AnyNode, BoxedView;}
xilem_core::generate_memoize_view! {Memoize, MemoizeState, View, ViewMarker, Cx, ChangeFlags, s, memoize}
xilem_core::generate_adapt_view! {View, Cx, ChangeFlags}
xilem_core::generate_adapt_state_view! {View, Cx, ChangeFlags}

/// This view container can switch between two views.
///
Expand Down
2 changes: 1 addition & 1 deletion src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ pub use xilem_core::{Id, IdPath, VecSplice};
pub use button::button;
pub use linear_layout::{h_stack, v_stack, LinearLayout};
pub use list::{list, List};
pub use view::{Adapt, Cx, Memoize, View, ViewMarker, ViewSequence};
pub use view::{Adapt, AdaptState, Cx, Memoize, View, ViewMarker, ViewSequence};
1 change: 1 addition & 0 deletions src/view/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ xilem_core::generate_viewsequence_trait! {ViewSequence, View, ViewMarker, Widget
xilem_core::generate_anyview_trait! {AnyView, View, ViewMarker, Cx, ChangeFlags, AnyWidget, BoxedView; + Send}
xilem_core::generate_memoize_view! {Memoize, MemoizeState, View, ViewMarker, Cx, ChangeFlags, s, memoize}
xilem_core::generate_adapt_view! {View, Cx, ChangeFlags}
xilem_core::generate_adapt_state_view! {View, Cx, ChangeFlags}

#[derive(Clone)]
pub struct Cx {
Expand Down

0 comments on commit 2b86d1d

Please sign in to comment.