-
Notifications
You must be signed in to change notification settings - Fork 297
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
Change Widget::update
to return a function for mutating the current State rather than produce a whole new State?
#554
Comments
What about calling a closure with a closure? Perhaps we could get rid of the Example: https://github.com/PistonDevelopers/graphics/blob/master/src/graphics.rs#L17 |
I was originally thinking along these lines too, however the Perhaps instead of being passed in via the I think this might look something like: fn update<'a, 'b, C>(self, args: UpdateArgs<'a, 'b, Self, C>, state: &mut StateCell<Self::State>);
where C: CharacterCache; Maybe the pub struct StateCell<T> {
state: T,
has_updated: bool,
}
impl<T> StateCell<T> {
fn view(&self) -> &T { &self.state }
fn update(&mut self, f: &mut FnMut(&mut T)) {
self.has_updated = true;
f(&mut self.state);
}
} |
Something like abstract return types would make it easy to return a function for mutating the State. There's some related discussion going on here atm. It might make the signature look something like: fn update<C>(self, args: UpdateArgs<Self, C>) -> Option<impl FnMut(&mut Self::State)>; or fn update<C>(self, args: UpdateArgs<Self, C>)<F> -> F where
F: FnMut(&mut Self::State); IMO This would be the clearest option, as the user wouldn't have to investigate the |
Another possible solution which might keep the This would also take the burden of choosing whether or not to return a new update off of the The downside is that this would increase memory usage and would likely require allocating (depending on the I think I'd still prefer to try a more performant option like returning an optional mutation closure once something like abstract return types lands, but will keep this in mind if it gets too complex. Edit: facepalm I just realised that this basically re-introduces the whole problem of needing to allocate the whole state each time there's some change, which is the very thing this issue was trying to address in the first place 😵 scrap this! |
Motivation
Currently, the signature for
Widget::update
is:The idea is that you only have to return a new
State
if something has changed between updates. This works quite efficiently for small widgets, however can be quite expensive for larger widgets.A possible solution is to instead return an
Option<Box<FnMut(&mut Self::State)>>
. With this change, theWidget::update
signature might look something like this:This way, instead of returning an entirely new state, we return a function that can mutate the state that already exists, reducing large allocations etc for larger widgets.
Concerns
It would be nice if we didn't have to
Box
the function that we're returning, however I'm unsure if it's possible to make an API that doesn't require it (I think we'd need HKT or something).Any suggestions or alternatives for handling this problem in a nicer way are welcome!
The text was updated successfully, but these errors were encountered: