@@ -35,14 +35,10 @@ impl<T: ReactiveValueState> ReactiveValueState for Option<T> {
3535 }
3636}
3737
38- pub trait ReactiveValueRenderInitPinned < VK : ?Sized + ReactiveValueKind > {
39- type State ;
38+ pub trait RenderInitPinned < R , S : ?Sized > {
39+ type Output ;
4040
41- fn render_init_pinned < Out > (
42- self ,
43- renderer : impl FnOnce ( VK :: Value < ' _ > ) -> Out ,
44- state : Pin < & mut Self :: State > ,
45- ) -> Out ;
41+ fn render_init_pinned ( self , renderer : R , state : Pin < & mut S > ) -> Self :: Output ;
4642}
4743
4844pub trait ProvideValueOfKind < VK : ?Sized + ReactiveValueKind > {
@@ -58,13 +54,19 @@ pub trait ReusableRendererOfKind<VK: ?Sized + ReactiveValueKind> {
5854
5955pub trait ReactiveValue < VK : ?Sized + ReactiveValueKind > {
6056 type PinnedState : ReactiveValueState < ReactiveValueKind = VK > ;
61- type PinnedRenderInit : ReactiveValueRenderInitPinned < VK , State = Self :: PinnedState > ;
57+ type PinnedRenderInit < R : FnOnce ( VK :: Value < ' _ > ) -> Out , Out > : RenderInitPinned <
58+ R ,
59+ Self :: PinnedState ,
60+ Output = Out ,
61+ > ;
6262
6363 /// Requires [`Unpin`] so that [`ReactiveValueState`] can be reused without defining another trait taking `&mut self`.
6464 type UnpinnedState : Unpin + ReactiveValueState < ReactiveValueKind = VK > ;
6565
6666 /// `state` is `Default::default()` at a pinned place.
67- fn pinned_render_init ( self ) -> ( Self :: PinnedState , Self :: PinnedRenderInit ) ;
67+ fn pinned_render_init < R : FnOnce ( VK :: Value < ' _ > ) -> Out , Out > (
68+ self ,
69+ ) -> ( Self :: PinnedState , Self :: PinnedRenderInit < R , Out > ) ;
6870
6971 /// `old_state` has been [unmounted](ReactiveStrStateUnmount::reactive_value_state_unmount) but not necessarily set to `Default::default()`.
7072 fn pinned_render_init_by_reusing < Out > (
@@ -103,30 +105,31 @@ pub trait ReactiveValueExt<VK: ?Sized + ReactiveValueKind>: ReactiveValue<VK> +
103105impl < T : ReactiveValue < VK > , VK : ?Sized + ReactiveValueKind > ReactiveValueExt < VK > for T { }
104106
105107#[ macro_export]
106- macro_rules! impl_reactive_value_unpinned_with_pinned {
108+ macro_rules! impl_reactive_value_unpinned_init_with_pinned {
107109 (
108110 type ReactiveValueKind = $ReactiveValueKind: ty;
109111 ) => {
110- type UnpinnedState = Self :: PinnedState ;
111-
112112 fn unpinned_render_init<Out >(
113113 self ,
114114 renderer: impl :: core:: ops:: FnOnce (
115115 <$ReactiveValueKind as $crate:: reactive_value:: ReactiveValueKind >:: Value <' _>,
116116 ) -> Out ,
117117 ) -> ( Self :: UnpinnedState , Out ) {
118- let ( mut state, render_init) = <Self as $crate:: reactive_value:: ReactiveValue <
119- $ReactiveValueKind,
120- >>:: pinned_render_init( self ) ;
121-
122- let out =
123- <Self :: PinnedRenderInit as $crate:: reactive_value:: ReactiveValueRenderInitPinned <
124- $ReactiveValueKind,
125- >>:: render_init_pinned(
126- render_init, renderer, :: core:: pin:: Pin :: new( & mut state)
127- ) ;
128- ( state, out)
118+ $crate:: reactive_value:: unpinned_render_init_with_pinned( self , renderer)
129119 }
120+ } ;
121+ }
122+
123+ #[ macro_export]
124+ macro_rules! impl_reactive_value_unpinned_with_pinned {
125+ (
126+ type ReactiveValueKind = $ReactiveValueKind: ty;
127+ ) => {
128+ type UnpinnedState = Self :: PinnedState ;
129+
130+ $crate:: impl_reactive_value_unpinned_init_with_pinned!(
131+ type ReactiveValueKind = $ReactiveValueKind;
132+ ) ;
130133
131134 fn unpinned_render_init_by_reusing<Out >(
132135 self ,
@@ -138,7 +141,7 @@ macro_rules! impl_reactive_value_unpinned_with_pinned {
138141 ) -> Out {
139142 #[ rustfmt:: skip]
140143 return <Self as $crate:: reactive_value:: ReactiveValue :: <
141- $ReactiveValueKind
144+ $ReactiveValueKind,
142145 >>:: pinned_render_init_by_reusing(
143146 self ,
144147 renderer,
@@ -161,4 +164,76 @@ macro_rules! impl_reactive_value_unpinned_with_pinned {
161164 } ;
162165}
163166
164- use impl_reactive_value_unpinned_with_pinned;
167+ #[ macro_export]
168+ macro_rules! impl_reactive_value_pinned_reuse_and_update_with_unpinned {
169+ (
170+ type ReactiveValueKind = $ReactiveValueKind: ty;
171+ ) => {
172+ fn pinned_render_init_by_reusing<Out >(
173+ self ,
174+ renderer: impl $crate:: reactive_value:: ReusableRendererOfKind <
175+ $ReactiveValueKind,
176+ Output = Out ,
177+ >,
178+ reused_state: :: core:: pin:: Pin <& mut Self :: PinnedState >,
179+ ) -> Out {
180+ #[ rustfmt:: skip]
181+ return <Self as $crate:: reactive_value:: ReactiveValue :: <
182+ $ReactiveValueKind,
183+ >>:: unpinned_render_init_by_reusing(
184+ self ,
185+ renderer,
186+ :: core:: pin:: Pin :: get_mut( reused_state) ,
187+ ) ;
188+ }
189+
190+ fn pinned_render_update<Out >(
191+ self ,
192+ renderer: impl :: core:: ops:: FnOnce (
193+ <$ReactiveValueKind as $crate:: reactive_value:: ReactiveValueKind >:: Value <' _>,
194+ ) -> Out ,
195+ state: :: core:: pin:: Pin <& mut Self :: UnpinnedState >,
196+ ) -> Option <Out > {
197+ #[ rustfmt:: skip]
198+ return <Self as $crate:: reactive_value:: ReactiveValue :: <
199+ $ReactiveValueKind,
200+ >>:: unpinned_render_update(
201+ self ,
202+ renderer,
203+ :: core:: pin:: Pin :: get_mut( state) ,
204+ ) ;
205+ }
206+ } ;
207+ }
208+
209+ #[ macro_export]
210+ macro_rules! impl_reactive_value_with_mixed_unpinned {
211+ (
212+ type ReactiveValueKind = $ReactiveValueKind: ty;
213+ ) => {
214+ $crate:: impl_reactive_value_unpinned_init_with_pinned!(
215+ type ReactiveValueKind = $ReactiveValueKind;
216+ ) ;
217+ $crate:: impl_reactive_value_pinned_reuse_and_update_with_unpinned!(
218+ type ReactiveValueKind = $ReactiveValueKind;
219+ ) ;
220+ } ;
221+ }
222+
223+ pub fn unpinned_render_init_with_pinned <
224+ V : ReactiveValue < VK > ,
225+ VK : ?Sized + ReactiveValueKind ,
226+ Out ,
227+ R : FnOnce ( VK :: Value < ' _ > ) -> Out ,
228+ > (
229+ this : V ,
230+ renderer : R ,
231+ ) -> ( V :: PinnedState , Out )
232+ where
233+ V :: PinnedState : Unpin ,
234+ {
235+ let ( mut state, render_init) = V :: pinned_render_init :: < R , Out > ( this) ;
236+
237+ let out = render_init. render_init_pinned ( renderer, :: core:: pin:: Pin :: new ( & mut state) ) ;
238+ ( state, out)
239+ }
0 commit comments