11use std:: { pin:: Pin , task:: Poll } ;
22
3+ use frender_common:: reactive_value:: AsOptionMut ;
34use frender_dom:: { render:: RenderContext , ui_handle:: UiHandle , StateUnmount } ;
45
56use crate :: RenderHtml ;
67
7- pub trait HtmlRenderContext : RenderContext < Renderer = Self :: HtmlRenderer > {
8- type HtmlRenderer : RenderHtml + ?Sized ;
9- }
10-
11- impl < Ctx : ?Sized + RenderContext > HtmlRenderContext for Ctx
12- where
13- Ctx :: Renderer : RenderHtml ,
14- {
15- type HtmlRenderer = Ctx :: Renderer ;
16- }
17-
18- // pub trait StatePollRender<U: ?Sized, R: ?Sized> {
19- // fn state_poll_render(self: Pin<&mut Self>, ui_handle: &mut U, renderer: &mut R) -> Poll<()>;
20- // }
21-
22- // + StatePollRender<Self, R>
23- /// A synonymous trait for [`StatePollRender`] with ui handle as Self.
24-
25- // impl<UH: ?Sized, S: ?Sized + StatePollRender<Self, R>, R: ?Sized> UiHandlePollRender<S, R> for UH {
26- // #[inline(always)]
27- // fn ui_handle_poll_render(&mut self, state: &mut S, renderer: &mut R) -> Poll<()> {
28- // state.state_poll_render(self, renderer)
29- // }
30- // }
8+ pub trait HtmlRenderContext : RenderContext < Renderer : RenderHtml > { }
9+ impl < Ctx : ?Sized + RenderContext < Renderer : RenderHtml > > HtmlRenderContext for Ctx { }
3110
3211pub trait PinnedRenderStateKind {
3312 /// Ui handles that are renderer-specific and **NOT** pinned in pinned environment.
3413 type PinnedUiHandle < R : RenderHtml + ?Sized > : UiHandle < R > ;
3514
36- // TODO: should `*NonReactiveState` and `*ReactiveState` be merged as one `*State`?
37- /// Renderer-specific non-reactive state in pinned environment.
38- type PinnedNonReactiveState < R : RenderHtml + ?Sized > : Default ;
39- /// Renderer-agnostic reactive state in pinned environment.
15+ /// State in pinned environment.
4016 ///
4117 /// [`Default`] is required so that the state can be constructed and then pinned before [`CsrElement::pinned_render_init`].
4218 /// Note that [`UnpinnedRenderStateKind::UnpinnedReactiveState`] requires `Default` for a different reason.
43- type PinnedReactiveState : StateUnmount + Default ;
19+ type PinnedState < R : RenderHtml + ?Sized > : StateUnmount ;
20+ type PinnedStateDefault < R : RenderHtml + ?Sized > : Default + AsOptionMut < Self :: PinnedState < R > > + StateUnmount ;
4421}
4522
4623pub trait PinnedRenderStateKindPollRender : PinnedRenderStateKind {
4724 fn pinned_poll_render < R : RenderHtml + ?Sized > (
4825 //
4926 renderer : & mut R ,
50- states : PinnedMutRenderStatesOfKind < Self , R > ,
27+ state : Pin < & mut Self :: PinnedState < R > > ,
28+ ui_handle : & mut Self :: PinnedUiHandle < R > ,
5129 cx : & mut std:: task:: Context < ' _ > ,
5230 ) -> Poll < ( ) > ;
5331}
5432
5533pub trait UnpinnedRenderStateKind {
5634 /// Ui handles that are renderer-specific and not pinned in unpinned environment.
5735 type UnpinnedUiHandle < R : RenderHtml + ?Sized > : UiHandle < R > ;
58- /// Renderer-specific non-reactive state in unpinned environment.
59- type UnpinnedNonReactiveState < R : RenderHtml + ?Sized > ;
60- /// Renderer-agnostic reactive state in unpinned environment.
36+
37+ /// State in unpinned environment.
6138 ///
62- /// [`Unpin`] is required so that [`StateUnmount`] can be used
39+ /// [`Unpin`] is required so that [`StateUnmount`] can be used without defining another unpinned variant
6340 /// (caller can safely create a `Pin<&mut _>` from unpinned places
6441 /// and then call [`StateUnmount::state_unmount`]).
65- ///
66- /// Another solution is to split trait [`StateUnmount`] into pinned and unpinned variants,
67- /// then we don't need the `Unpin` bound.
68- type UnpinnedReactiveState : StateUnmount + Default + Unpin ;
42+ type UnpinnedState < R : RenderHtml + ?Sized > : StateUnmount + Unpin ;
6943
70- #[ cfg( todo) ]
7144 /// [`Default`] is required so that [`RenderStateKind`](CsrElement::RenderStateKind) of `Option<impl CsrElement>`
7245 /// don't need to wrap `UnpinnedReactiveState` with `Option`.
46+ /// This optimizes `impl CsrElement for Option<impl CsrElement<RenderStateKind: UnpinnedRenderStateKind<UnpinnedState<_>: Default>>>`.
7347 /// Note that [`PinnedRenderStateKind::PinnedReactiveState`] requires `Default` for a different reason.
74- type UnpinnedReactiveStateDefault : StateUnmount + Default + Unpin ;
48+ type UnpinnedStateDefault < R : RenderHtml + ? Sized > : Default + AsOptionMut < Self :: UnpinnedState < R > > + StateUnmount + Unpin ;
7549}
7650
7751pub trait UnpinnedRenderStateKindPollRender : UnpinnedRenderStateKind {
7852 fn unpinned_poll_render < R : RenderHtml + ?Sized > (
7953 //
8054 renderer : & mut R ,
81- states : UnpinnedMutRenderStatesOfKind < Self , R > ,
55+ state : & mut Self :: UnpinnedState < R > ,
56+ ui_handle : & mut Self :: UnpinnedUiHandle < R > ,
8257 cx : & mut std:: task:: Context < ' _ > ,
8358 ) -> Poll < ( ) > ;
8459}
@@ -87,74 +62,67 @@ pub trait UnpinnedRenderStateKindPollRender: UnpinnedRenderStateKind {
8762pub trait RenderStateKind : UnpinnedRenderStateKindPollRender + PinnedRenderStateKindPollRender { }
8863impl < K : ?Sized + UnpinnedRenderStateKindPollRender + PinnedRenderStateKindPollRender > RenderStateKind for K { }
8964
90- pub type PinnedMutRenderStatesOfKind < ' a , Kind , Renderer > = RenderStates <
91- //
92- & ' a mut <Kind as PinnedRenderStateKind >:: PinnedUiHandle < Renderer > ,
93- Pin < & ' a mut <Kind as PinnedRenderStateKind >:: PinnedNonReactiveState < Renderer > > ,
94- Pin < & ' a mut <Kind as PinnedRenderStateKind >:: PinnedReactiveState > ,
95- > ;
96-
97- pub type UnpinnedMutRenderStatesOfKind < ' a , Kind , Renderer > = RenderStates <
98- //
99- & ' a mut <Kind as UnpinnedRenderStateKind >:: UnpinnedUiHandle < Renderer > ,
100- & ' a mut <Kind as UnpinnedRenderStateKind >:: UnpinnedNonReactiveState < Renderer > ,
101- & ' a mut <Kind as UnpinnedRenderStateKind >:: UnpinnedReactiveState ,
102- > ;
103-
104- pub type UnpinnedRenderStatesOfKind < Kind , Renderer > = RenderStates <
105- //
106- <Kind as UnpinnedRenderStateKind >:: UnpinnedUiHandle < Renderer > ,
107- <Kind as UnpinnedRenderStateKind >:: UnpinnedNonReactiveState < Renderer > ,
108- <Kind as UnpinnedRenderStateKind >:: UnpinnedReactiveState ,
109- > ;
110-
111- pub struct RenderStates < UH , NRS , RS > {
112- pub ui_handle : UH ,
113- pub non_reactive_state : NRS ,
114- pub reactive_state : RS ,
115- }
116-
117- pub ( crate ) type PinnedMutRenderStates < ' a , UH , NRS , RS > = RenderStates < & ' a mut UH , Pin < & ' a mut NRS > , Pin < & ' a mut RS > > ;
118- pub ( crate ) type UnpinnedMutRenderStates < ' a , UH , NRS , RS > = RenderStates < & ' a mut UH , & ' a mut NRS , & ' a mut RS > ;
119-
12065pub type PinnedUiHandleOfKind < R , K > = <K as PinnedRenderStateKind >:: PinnedUiHandle < R > ;
121- pub type UnpinnedUiHandleOfKind < R , K > = <K as UnpinnedRenderStateKind >:: UnpinnedUiHandle < R > ;
122-
123- pub struct PinMutRenderInitStates < ' a , NRS , RS > {
124- pub non_reactive_state : Pin < & ' a mut NRS > ,
125- pub reactive_state : Pin < & ' a mut RS > ,
126- }
66+ pub type PinnedUnmountedUiHandleOfKind < R , K > = <<K as PinnedRenderStateKind >:: PinnedUiHandle < R > as UiHandle < R > >:: Unmounted ;
67+ pub type PinnedStateOfKind < R , K > = <K as PinnedRenderStateKind >:: PinnedState < R > ;
68+ pub type PinnedStateDefaultOfKind < R , K > = <K as PinnedRenderStateKind >:: PinnedStateDefault < R > ;
12769
128- pub type PinMutRenderInitStatesOfKind < ' a , Kind , Renderer > = PinMutRenderInitStates < ' a , <Kind as PinnedRenderStateKind >:: PinnedNonReactiveState < Renderer > , <Kind as PinnedRenderStateKind >:: PinnedReactiveState > ;
70+ pub type UnpinnedUiHandleOfKind < R , K > = <K as UnpinnedRenderStateKind >:: UnpinnedUiHandle < R > ;
71+ pub type UnpinnedUnmountedUiHandleOfKind < R , K > = <<K as UnpinnedRenderStateKind >:: UnpinnedUiHandle < R > as UiHandle < R > >:: Unmounted ;
72+ pub type UnpinnedStateOfKind < R , K > = <K as UnpinnedRenderStateKind >:: UnpinnedState < R > ;
73+ pub type UnpinnedStateDefaultOfKind < R , K > = <K as UnpinnedRenderStateKind >:: UnpinnedStateDefault < R > ;
12974
13075pub trait CsrElement {
13176 type RenderStateKind : RenderStateKind ;
13277
78+ /// The implementation should _initialize_ `state_default` so that [`AsOptionMut::<PinnedState>::as_option_mut(state_default).is_some()`](AsOptionMut)
79+ /// or future usage will panic.
80+ /// Caller of this method cannot consider this requirement as a safety guarantee.
13381 fn pinned_render_init < Ctx : ?Sized + HtmlRenderContext > (
13482 //
13583 self ,
13684 render_context : & mut Ctx ,
137- states : PinMutRenderInitStatesOfKind < Self :: RenderStateKind , Ctx :: Renderer > ,
85+ state_default : Pin < & mut PinnedStateDefaultOfKind < Ctx :: Renderer , Self :: RenderStateKind > > ,
13886 ) -> PinnedUiHandleOfKind < Ctx :: Renderer , Self :: RenderStateKind > ;
13987
140- fn pinned_render_update < Ctx : ?Sized + HtmlRenderContext > (
141- //
88+ fn pinned_render_init_by_reusing < Ctx : ?Sized + HtmlRenderContext > (
14289 self ,
14390 render_context : & mut Ctx ,
144- states : PinnedMutRenderStatesOfKind < Self :: RenderStateKind , Ctx :: Renderer > ,
91+ reused_state : Pin < & mut PinnedStateOfKind < Ctx :: Renderer , Self :: RenderStateKind > > ,
92+ unmounted_ui_handle : PinnedUnmountedUiHandleOfKind < Ctx :: Renderer , Self :: RenderStateKind > ,
93+ ) -> PinnedUiHandleOfKind < Ctx :: Renderer , Self :: RenderStateKind > ;
94+
95+ fn pinned_render_update < Renderer : ?Sized + RenderHtml > (
96+ //
97+ self ,
98+ renderer : & mut Renderer ,
99+ state : Pin < & mut PinnedStateOfKind < Renderer , Self :: RenderStateKind > > ,
100+ ui_handle : & mut PinnedUiHandleOfKind < Renderer , Self :: RenderStateKind > ,
145101 ) ;
146102
147103 fn unpinned_render_init < Ctx : ?Sized + HtmlRenderContext > (
148104 //
149105 self ,
150106 render_context : & mut Ctx ,
151- ) -> UnpinnedRenderStatesOfKind < Self :: RenderStateKind , Ctx :: Renderer > ;
152-
153- fn unpinned_render_update < Ctx : ?Sized + HtmlRenderContext > (
107+ ) -> (
154108 //
109+ UnpinnedStateOfKind < Ctx :: Renderer , Self :: RenderStateKind > ,
110+ UnpinnedUiHandleOfKind < Ctx :: Renderer , Self :: RenderStateKind > ,
111+ ) ;
112+
113+ fn unpinned_render_init_by_reusing < Ctx : ?Sized + HtmlRenderContext > (
155114 self ,
156115 render_context : & mut Ctx ,
157- states : UnpinnedMutRenderStatesOfKind < Self :: RenderStateKind , Ctx :: Renderer > ,
116+ reused_state : & mut UnpinnedStateOfKind < Ctx :: Renderer , Self :: RenderStateKind > ,
117+ unmounted_ui_handle : UnpinnedUnmountedUiHandleOfKind < Ctx :: Renderer , Self :: RenderStateKind > ,
118+ ) -> UnpinnedUiHandleOfKind < Ctx :: Renderer , Self :: RenderStateKind > ;
119+
120+ fn unpinned_render_update < Renderer : ?Sized + RenderHtml > (
121+ //
122+ self ,
123+ renderer : & mut Renderer ,
124+ state : & mut UnpinnedStateOfKind < Renderer , Self :: RenderStateKind > ,
125+ ui_handle : & mut UnpinnedUiHandleOfKind < Renderer , Self :: RenderStateKind > ,
158126 ) ;
159127}
160128
0 commit comments