Skip to content

Commit

Permalink
feat(core): 🎸 support only dirty paint phase
Browse files Browse the repository at this point in the history
  • Loading branch information
M-Adoo committed Jan 8, 2025
1 parent 830c296 commit c212ad8
Show file tree
Hide file tree
Showing 26 changed files with 131 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he

### Features

- **core**: The `Render::dirty_phase` method has been added to allow widgets to mark only the paint phase as dirty when it is modified. (#pr @M-Adoo)
- **macros**: Added the `part_reader!` macro to generate a partial reader from a reference of a reader. (#688 @M-Adoo)
- **macros**: The `simple_declare` now supports the `stateless` meta attribute, `#[simple_declare(stateless)]`. (#pr @M-Adoo)

Expand Down
4 changes: 2 additions & 2 deletions core/src/builtin_widgets/align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ impl Declare for VAlignWidget {
fn declarer() -> Self::Builder { FatObj::new(()) }
}

impl_compose_child_for_wrap_render!(HAlignWidget);
impl_compose_child_for_wrap_render!(VAlignWidget);
impl_compose_child_for_wrap_render!(HAlignWidget, DirtyPhase::Layout);
impl_compose_child_for_wrap_render!(VAlignWidget, DirtyPhase::Layout);

impl WrapRender for HAlignWidget {
fn perform_layout(&self, mut clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl Declare for RelativeAnchor {
fn declarer() -> Self::Builder { FatObj::new(()) }
}

impl_compose_child_for_wrap_render!(RelativeAnchor);
impl_compose_child_for_wrap_render!(RelativeAnchor, DirtyPhase::Layout);

impl WrapRender for RelativeAnchor {
fn perform_layout(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/box_decoration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl BorderSide {
pub fn new(width: f32, color: Brush) -> Self { Self { width, color } }
}

impl_compose_child_for_wrap_render!(BoxDecoration);
impl_compose_child_for_wrap_render!(BoxDecoration, DirtyPhase::Layout);

impl WrapRender for BoxDecoration {
fn perform_layout(&self, mut clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
Expand Down
4 changes: 2 additions & 2 deletions core/src/builtin_widgets/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,9 @@ fn class_update(node: &ClassNode, orig: &ClassNode, class: &Class, wnd_id: Windo

node.dyn_info_mut().gen_range = GenRange::Single(new_id);
let marker = tree.dirty_marker();
marker.mark(new_id);
marker.mark(new_id, DirtyPhase::Layout);
if new_id != orig_id && new_id.ancestor_of(orig_id, tree) {
marker.mark(orig_id);
marker.mark(orig_id, DirtyPhase::Layout);
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/constrained_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl Declare for ConstrainedBox {
fn declarer() -> Self::Builder { FatObj::new(()) }
}

impl_compose_child_for_wrap_render!(ConstrainedBox);
impl_compose_child_for_wrap_render!(ConstrainedBox, DirtyPhase::Layout);

impl WrapRender for ConstrainedBox {
fn perform_layout(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/foreground.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Declare for Foreground {
fn declarer() -> Self::Builder { FatObj::new(()) }
}

impl_compose_child_for_wrap_render!(Foreground);
impl_compose_child_for_wrap_render!(Foreground, DirtyPhase::Paint);

impl WrapRender for Foreground {
fn perform_layout(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/global_anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ impl<'c> ComposeChild<'c> for GlobalAnchor {
}
}
.into_widget()
.dirty_on(modifies)
.dirty_on(modifies, DirtyPhase::Layout)
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/ignore_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub struct IgnorePointer {
pub ignore: bool,
}

impl_compose_child_for_wrap_render!(IgnorePointer);
impl_compose_child_for_wrap_render!(IgnorePointer, DirtyPhase::Paint);

impl WrapRender for IgnorePointer {
#[inline]
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/keep_alive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl<'c> ComposeChild<'c> for KeepAlive {
{ this.silent().wid = Some($w.track_id()); }
w
.into_widget()
.dirty_on(this.raw_modifies())
.dirty_on(this.raw_modifies(), DirtyPhase::Layout)
.try_unwrap_state_and_attach(this)

}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/opacity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl Default for Opacity {
fn default() -> Self { Self { opacity: 1.0 } }
}

impl_compose_child_for_wrap_render!(Opacity);
impl_compose_child_for_wrap_render!(Opacity, DirtyPhase::Paint);

impl WrapRender for Opacity {
fn perform_layout(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
Expand Down
12 changes: 5 additions & 7 deletions core/src/builtin_widgets/smooth_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ macro_rules! smooth_size_widget_impl {
}
}

impl_compose_child!($name, true);
impl_compose_child!($name, DirtyPhase::Layout);
};
}

Expand Down Expand Up @@ -264,12 +264,12 @@ macro_rules! smooth_pos_widget_impl {
}
}

impl_compose_child!($name, false);
impl_compose_child!($name, DirtyPhase::Paint);
};
}

macro_rules! impl_compose_child {
($name:ty, $dirty_self:literal) => {
($name:ty, $dirty:expr) => {
impl<'c> ComposeChild<'c> for $name {
type Child = Widget<'c>;

Expand Down Expand Up @@ -297,9 +297,7 @@ macro_rules! impl_compose_child {
if marker.is_dirty(id) {
inner.set_force_layout(true)
}
if $dirty_self {
marker.mark(id);
}
marker.mark(id, $dirty);
})
})
.unsubscribe_when_dropped();
Expand All @@ -308,7 +306,7 @@ macro_rules! impl_compose_child {
.into_widget()
.attach_anonymous_data(h);

WrapRender::combine_child(this, child)
WrapRender::combine_child(this, child, $dirty)
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/transform_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl Declare for TransformWidget {
fn declarer() -> Self::Builder { FatObj::new(()) }
}

impl_compose_child_for_wrap_render!(TransformWidget);
impl_compose_child_for_wrap_render!(TransformWidget, DirtyPhase::Paint);

impl WrapRender for TransformWidget {
#[inline]
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct VisibilityRender {
display: bool,
}

impl_compose_child_for_wrap_render!(VisibilityRender);
impl_compose_child_for_wrap_render!(VisibilityRender, DirtyPhase::Layout);

impl WrapRender for VisibilityRender {
#[inline]
Expand Down
2 changes: 1 addition & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub mod prelude {
ticker::{Duration, Instant},
widget::*,
widget_children::*,
widget_tree::{BoxClamp, LayoutInfo, TrackId, WidgetId},
widget_tree::{BoxClamp, DirtyPhase, LayoutInfo, TrackId, WidgetId},
window::Window,
};
pub use crate::{timer, *};
Expand Down
4 changes: 2 additions & 2 deletions core/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ impl Overlay {
let tree = wnd.tree_mut();
let root = tree.root();
wid.dispose_subtree(tree);
tree.dirty_marker().mark(root);
tree.dirty_marker().mark(root, DirtyPhase::Layout);
});
}
}
Expand Down Expand Up @@ -239,7 +239,7 @@ impl Overlay {
let tree = wnd.tree_mut();
tree.root().append(wid, tree);
wid.on_mounted_subtree(tree);
tree.dirty_marker().mark(wid);
tree.dirty_marker().mark(wid, DirtyPhase::Layout);

self.0.borrow_mut().showing = Some(ShowingInfo { generator: gen.into(), wnd_id: wnd.id() });

Expand Down
6 changes: 3 additions & 3 deletions core/src/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub(crate) trait InnerPipe: Pipe + Sized {
old.dispose_subtree(tree);
new.on_mounted_subtree(tree);

tree.dirty_marker().mark(new);
tree.dirty_marker().mark(new, DirtyPhase::Layout);

if without_ctx {
BuildCtx::clear();
Expand Down Expand Up @@ -201,7 +201,7 @@ pub(crate) trait InnerPipe: Pipe + Sized {
old.iter().for_each(|id| id.dispose_subtree(tree));
new.iter().for_each(|w| {
w.on_mounted_subtree(tree);
tree.dirty_marker().mark(*w);
tree.dirty_marker().mark(*w, DirtyPhase::Layout);
});

if without_ctx {
Expand Down Expand Up @@ -307,7 +307,7 @@ pub(crate) trait InnerPipe: Pipe + Sized {
}
}

tree.dirty_marker().mark(p);
tree.dirty_marker().mark(p, DirtyPhase::Layout);

if without_ctx {
BuildCtx::clear();
Expand Down
2 changes: 1 addition & 1 deletion core/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ where
let modifies = s.raw_modifies();
ReaderRender(s.clone_reader())
.into_widget()
.dirty_on(modifies)
.dirty_on(modifies, s.read().dirty_phase())
}
},
}
Expand Down
11 changes: 9 additions & 2 deletions core/src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ pub trait Render: 'static {
HitTest { hit, can_hit_child: hit || !self.only_sized_by_parent() }
}

/// By default, this function returns a `Layout` phase to indicate that the
/// widget should be marked as dirty when modified. When the layout phase is
/// marked as dirty, the paint phase will also be affected.
fn dirty_phase(&self) -> DirtyPhase { DirtyPhase::Layout }

/// Return a transform to map the coordinate from its parent to this widget.
fn get_transform(&self) -> Option<Transform> { None }
}
Expand Down Expand Up @@ -174,7 +179,9 @@ impl<'w> Widget<'w> {
/// # Panic
/// This method only works within a build process; otherwise, it will
/// result in a panic.
pub fn dirty_on(self, upstream: CloneableBoxOp<'static, ModifyScope, Infallible>) -> Self {
pub fn dirty_on(
self, upstream: CloneableBoxOp<'static, ModifyScope, Infallible>, dirty: DirtyPhase,
) -> Self {
let track = TrackWidgetId::default();
let id = track.track_id();

Expand All @@ -184,7 +191,7 @@ impl<'w> Widget<'w> {
.filter(|b| b.contains(ModifyScope::FRAMEWORK))
.subscribe(move |_| {
if let Some(id) = id.get() {
marker.mark(id);
marker.mark(id, dirty);
}
})
.unsubscribe_when_dropped();
Expand Down
Loading

0 comments on commit c212ad8

Please sign in to comment.