NAME
Clay::UI::Revision - process-wide counter that grows whenever a Clay::UI frame would look different
SYNOPSIS
use v5.22;
use warnings;
use Object::Pad;
use Clay::UI;
use Clay::UI::Box;
use Clay::UI::Revision qw(current_revision);
class My::Panel :strict(params) :does(Clay::UI::Box) {}
my $root = My::Panel->new(id => 'root', background_color => [40, 50, 60, 255]);
my $ui = Clay::UI->new(width => 800, height => 600, root => $root);
my $drawn; # the revision of the frame on screen
for my $frame (1 .. 3) {
# render runs every frame: input reaches the widgets only through it.
my $commands = $ui->render(pointer_state => { x => 10, y => 10, down => 0 });
next if defined $drawn && $drawn == $ui->laid_out_revision;
$drawn = $ui->laid_out_revision;
say "frame $frame: drawing ", scalar @$commands, ' commands';
}
$root->background_color([0, 0, 0, 255]); # a change ...
say 'stale' if current_revision() != $drawn; # ... makes the drawn frame stale
DESCRIPTION
The revision is a non-negative integer that grows whenever something that a frame lays out or draws has changed. A renderer remembers the revision of the frame it drew and skips drawing while the revision is still the same. It still calls "render" in Clay::UI every frame: pointer and scroll input reach the widgets only through render, and the changes they cause (hover states, scrolling) bump the revision there. "laid_out_revision" in Clay::UI tells which revision a frame shows.
These bump the revision:
every widget setter that changes what a frame lays out or draws: attributes (
layout,background_color,text, ...), the children of a widget, user states (add_stateand friends),disabled;the
width,heightandmeasure_textwriters of a Clay::UI;a change of the hovered, armed, pressed or focused widgets in a Clay::UI::Interaction, because they drive the derived
hovered,pressedandfocusedstates;a scroll container moving inside
render(wheel input, drag scrolling or the momentum after drag scrolling), "scroll_to" in Clay::UI and "set_scroll_position" in Clay::XS;mark_changed("mark_changed" in Clay::UI::Role::Core::Element), which widget classes that keep state of their own call from their setters, andrequest_prepare(Clay::UI::Role::Core::Preparable).every frame in which Clay runs a transition handler ("transition" in Clay::XS::Structs), that is, animates an element: its render commands differ from the frame before, and the frame after the last step shows the final state. The counting happens in Clay::XS, so the revision moves during
render, after "laid_out_revision" in Clay::UI was recorded; the next frame then shows a new revision.
Reading an attribute never bumps the revision; neither does writing can_focus, which changes nothing drawn (unless it takes the focus away).
There is one revision for the whole process, shared by every Clay::UI: a change in any of them makes every renderer draw again. Only equality is meaningful. The value starts at 0 and only grows, but how far it grows per change is unspecified (one write may bump it more than once).
FUNCTIONS
Nothing is exported by default; import the functions by name.
current_revision
my $revision = current_revision();
Returns the current revision.
bump_revision
my $revision = bump_revision();
Increments the revision and returns the new value. Widget code calls it from setters that change what a frame shows; most widget classes call $widget->mark_changed instead, which does the same.