-
Notifications
You must be signed in to change notification settings - Fork 295
Change Widget::update to mutate the Widget::State rather than return a new one. Move input capturing methods from Widget trait to UiCell. #595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…a new one. Move input capturing from Widget trait to UiCell. Closes PistonDevelopers#554.
let state_mut_ptr: *mut State<W::State> = &mut state; | ||
widget.update(UpdateArgs { | ||
idx: idx, | ||
state: unsafe { ::std::mem::transmute(state_mut_ptr) }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really shouldn't be required, however I couldn't find any other way to appease the borrow checker. Perhaps there is something I'm missing? Would be nice if someone could review and see if they can get it working without the unsafe. @bvssvni ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reduced it http://is.gd/Xu6jc0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the solution: http://is.gd/LEoLyJ
You need to add another lifetime UpdateArgs<'a, 'b: 'a, W, C: 'a>
and pass it in to pub state: &'a mut State<'b, W::State>
. Notice that the second lifetime 'b
inherits the first 'a
such that 'b
always outlive 'a
.
This error happened because UpdateArgs
moved, and the compiler only has 'a
to reason about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah, great stuff @bvssvni ! I tried multiple lifetimes but didn't consider bounding the second lifetime by the first, though it does make a lot of sense :) thanks! I'll implement the change now
All passing unsafe-less 😸 going to merge! Published as v0.21.0. |
Change Widget::update to mutate the Widget::State rather than return a new one. Move input capturing methods from Widget trait to UiCell.
This change addresses the problem highlighted in #554 where large widgets would be required to allocate an entire new
Widget::State
even for the slightest of changes. This is because the only way of updating the state was to return an entirely new state from theWidget::update
method.This PR changes the
Widget::update
method so that it no longer returns anOption<Widget::State>
but instead provides a way of mutating the state via theState
wrapper which is given via theUpdateArgs
. All fields not relating to the unique widget state have been moved out of theState
type and into aCommonState
type. This allows us to use theState
type purely as a "cell"-like wrapper around theWidgetState
.State::view
provides immutable access to theWidget::State
.State::update
allows for mutation of theWidget::State
. When called, it sets ahas_updated
flag, allowing us to check whether or not theWidget::State
was updated at all following the call ofWidget::update
and in turn allowing us to know whether or not we need to produce a newElement
for theWidget
.This change also required moving the input capturing methods from the
Widget
trait to theUiCell
, to be called within theWidget::update
if necessary.