Open keis opened 2 months ago
For reference my hacky solution right now looks like this
Cond::new(inner.is_some(), Unwrap(inner), ())
And the create of that Unwrap wrapper of Option looks like
fn create(&self, cx: &mut Cx) -> Self ::View {
self.0.as_ref().unwrap().create(cx)
}
I've run into this issue as well, and have resorted to similar ugly workarounds.
The basic problem is that normally, view states (that is, the associated type View::State
) don't have runtime type identification, so dynamically changing the view type (in this case from Some<View>
to None
) means that the State
type no longer corresponds to the view.
The cleanest solution, for now, is to wrap the optional view in Dynamic
. What Dynamic
does is wrap the State
in a boxed Any
. It also keeps around a copy of the previously-rendered view. When the view is rebuilt, it does a type check to determine if the stored state still matches the View::State
type. If it doesn't, then the we raze and rebuild the view.
The downside is that this has an extra cost of boxing and type checking. For Quill, because the view hierarchy is re-created every update, it's designed to be cheap - it's just filling in slots in a giant tuple. For bevy_reactor
, OTOH, I took a different approach because the view hierarchy is only built once, so there's less pressure to try and optimize the building of views.
Being able to use
Option<View>
as a view is very convenient but does not allow for the state Some/None to change. Being able to dynamically change this would be really useful.I've been able to emulate something like this by stitching
Cond
together with a helperUnwrap
ViewTemplate. So looks pretty doable to me but I've yet to fully wrap my head around the state tracking in quill works.