Skip to content

Commit c042884

Browse files
committed
feat: now Option as CsrElement doesn't preserve its state
1 parent 9f6093d commit c042884

File tree

1 file changed

+67
-75
lines changed

1 file changed

+67
-75
lines changed

packages/frender-html/src/elements/option.rs

Lines changed: 67 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,7 @@ where
143143
pub struct Kind<K>(super::Kind<K>);
144144

145145
impl<K: UnpinnedRenderStateKind> UnpinnedRenderStateKind for Kind<K> {
146-
type UnpinnedUiHandle<R: RenderHtml + ?Sized> = UiHandleMaybe<
147-
UiHandleWithNonReactiveState<K::UnpinnedUiHandle<R>, K::UnpinnedNonReactiveState<R>>,
148-
UiHandleWithNonReactiveState<<K::UnpinnedUiHandle<R> as UiHandle<R>>::Unmounted, K::UnpinnedNonReactiveState<R>>,
149-
>;
146+
type UnpinnedUiHandle<R: RenderHtml + ?Sized> = Option<UiHandleWithNonReactiveState<K::UnpinnedUiHandle<R>, K::UnpinnedNonReactiveState<R>>>;
150147
type UnpinnedNonReactiveState<R: RenderHtml + ?Sized> = ();
151148
type UnpinnedReactiveState = K::UnpinnedReactiveState;
152149
}
@@ -164,23 +161,24 @@ impl<K: UnpinnedRenderStateKindPollRender> UnpinnedRenderStateKindPollRender for
164161
reactive_state,
165162
} = states;
166163

167-
match ui_handle {
168-
UiHandleMaybe::Mounted(UiHandleWithNonReactiveState { ui_handle, non_reactive_state }) => K::unpinned_poll_render(
164+
if let Some(UiHandleWithNonReactiveState { ui_handle, non_reactive_state }) = ui_handle {
165+
K::unpinned_poll_render(
169166
renderer,
170167
RenderStates {
171168
ui_handle,
172169
non_reactive_state,
173170
reactive_state,
174171
},
175172
cx,
176-
),
177-
_ => Poll::Ready(()),
173+
)
174+
} else {
175+
Poll::Ready(())
178176
}
179177
}
180178
}
181179

182180
impl<K: PinnedRenderStateKind> PinnedRenderStateKind for Kind<K> {
183-
type PinnedUiHandle<R: RenderHtml + ?Sized> = UiHandleMaybeMounted<K::PinnedUiHandle<R>, R>;
181+
type PinnedUiHandle<R: RenderHtml + ?Sized> = Option<K::PinnedUiHandle<R>>;
184182
type PinnedNonReactiveState<R: RenderHtml + ?Sized> = K::PinnedNonReactiveState<R>;
185183
type PinnedReactiveState = K::PinnedReactiveState;
186184
}
@@ -198,17 +196,18 @@ impl<K: PinnedRenderStateKindPollRender> PinnedRenderStateKindPollRender for Kin
198196
reactive_state,
199197
} = states;
200198

201-
match ui_handle {
202-
UiHandleMaybe::Mounted(ui_handle) => K::pinned_poll_render(
199+
if let Some(ui_handle) = ui_handle {
200+
K::pinned_poll_render(
203201
renderer,
204202
RenderStates {
205203
ui_handle,
206204
non_reactive_state,
207205
reactive_state,
208206
},
209207
cx,
210-
),
211-
_ => Poll::Ready(()),
208+
)
209+
} else {
210+
Poll::Ready(())
212211
}
213212
}
214213
}
@@ -225,8 +224,8 @@ impl<E: CsrElement> CsrElement for Option<E> {
225224
states: crate::element::PinMutRenderInitStatesOfKind<Self::RenderStateKind, Ctx::Renderer>,
226225
) -> crate::element::PinnedUiHandleOfKind<Ctx::Renderer, Self::RenderStateKind> {
227226
match self {
228-
Some(this) => UiHandleMaybe::Mounted(this.pinned_render_init(render_context, states)),
229-
None => UiHandleMaybe::BeforeMounted,
227+
Some(this) => Some(this.pinned_render_init(render_context, states)),
228+
None => None,
230229
}
231230
}
232231

@@ -236,38 +235,34 @@ impl<E: CsrElement> CsrElement for Option<E> {
236235
render_context: &mut Ctx,
237236
RenderStates {
238237
ui_handle,
239-
non_reactive_state,
238+
mut non_reactive_state,
240239
reactive_state,
241240
}: crate::element::PinnedMutRenderStatesOfKind<Self::RenderStateKind, Ctx::Renderer>,
242241
) {
243-
match self {
244-
Some(this) => {
245-
let ui_handle = match ui_handle {
246-
ui_handle @ UiHandleMaybe::BeforeMounted => {
247-
*ui_handle = UiHandleMaybe::Mounted(this.pinned_render_init(render_context, PinMutRenderInitStates { non_reactive_state, reactive_state }));
248-
return;
249-
}
250-
UiHandleMaybe::Mounted(ui_handle) => ui_handle,
251-
ui_handle @ UiHandleMaybe::Unmounted(_) => ui_handle.mount_unmounted(render_context),
252-
};
253-
254-
this.pinned_render_update(
255-
render_context,
256-
RenderStates {
257-
ui_handle,
258-
non_reactive_state,
259-
reactive_state,
260-
},
261-
);
262-
}
263-
None => {
264-
// states are not set to default
265-
// just ui handle gets unmounted
266-
// and ReactiveState got state_unmounted
267-
if ui_handle.unmount_in_place(render_context.renderer_mut()) {
268-
reactive_state.state_unmount()
242+
match (self, ui_handle) {
243+
(None, ui_handle) => {
244+
if let Some(ui_handle) = ui_handle.take() {
245+
// NonReactiveState is dropped and set to default
246+
non_reactive_state.set(Default::default());
247+
248+
// ReactiveState is state_unmounted but not set to default
249+
reactive_state.state_unmount();
250+
251+
// ui handle is unmounted and dropped
252+
_ = ui_handle.unmount(render_context.renderer_mut());
269253
}
270254
}
255+
(Some(this), ui_handle @ None) => {
256+
*ui_handle = Some(this.pinned_render_init(render_context, PinMutRenderInitStates { non_reactive_state, reactive_state }));
257+
}
258+
(Some(this), Some(ui_handle)) => this.pinned_render_update(
259+
render_context,
260+
RenderStates {
261+
ui_handle,
262+
non_reactive_state,
263+
reactive_state,
264+
},
265+
),
271266
}
272267
}
273268

@@ -284,13 +279,13 @@ impl<E: CsrElement> CsrElement for Option<E> {
284279
reactive_state,
285280
} = this.unpinned_render_init(render_context);
286281
RenderStates {
287-
ui_handle: UiHandleMaybe::Mounted(UiHandleWithNonReactiveState { ui_handle, non_reactive_state }),
282+
ui_handle: Some(UiHandleWithNonReactiveState { ui_handle, non_reactive_state }),
288283
non_reactive_state: (),
289284
reactive_state,
290285
}
291286
}
292287
None => RenderStates {
293-
ui_handle: UiHandleMaybe::BeforeMounted,
288+
ui_handle: None,
294289
non_reactive_state: (),
295290
reactive_state: Default::default(), // Note default reactive state is used when None.render_init()
296291
},
@@ -308,39 +303,36 @@ impl<E: CsrElement> CsrElement for Option<E> {
308303
non_reactive_state: (),
309304
reactive_state,
310305
} = states;
311-
match self {
312-
Some(this) => {
313-
let UiHandleWithNonReactiveState { ui_handle, non_reactive_state } = match ui_handle {
314-
ui_handle @ UiHandleMaybe::BeforeMounted => {
315-
let states = this.unpinned_render_init(render_context);
316-
*reactive_state = states.reactive_state;
317-
*ui_handle = UiHandleMaybe::Mounted(UiHandleWithNonReactiveState {
318-
ui_handle: states.ui_handle,
319-
non_reactive_state: states.non_reactive_state,
320-
});
321-
return;
322-
}
323-
UiHandleMaybe::Mounted(mounted) => mounted,
324-
unmounted @ UiHandleMaybe::Unmounted(_) => unmounted.mount_unmounted(render_context),
325-
};
326-
327-
this.unpinned_render_update(
328-
render_context,
329-
RenderStates {
330-
ui_handle,
331-
non_reactive_state,
332-
reactive_state,
333-
},
334-
);
335-
}
336-
None => {
337-
// states are not set to default
338-
// just ui handle gets unmounted
339-
// and ReactiveState got state_unmounted
340-
if ui_handle.unmount_in_place(render_context.renderer_mut()) {
341-
Pin::new(reactive_state).state_unmount()
306+
307+
match (self, ui_handle) {
308+
(None, ui_handle) => {
309+
if let Some(UiHandleWithNonReactiveState { ui_handle, non_reactive_state }) = ui_handle.take() {
310+
// NonReactiveState is dropped
311+
drop(non_reactive_state);
312+
313+
// ReactiveState is state_unmounted but not set to default
314+
Pin::new(reactive_state).state_unmount();
315+
316+
// ui handle is unmounted and dropped
317+
_ = ui_handle.unmount(render_context.renderer_mut());
342318
}
343319
}
320+
(Some(this), ui_handle @ None) => {
321+
let states = this.unpinned_render_init(render_context);
322+
*reactive_state = states.reactive_state;
323+
*ui_handle = Some(UiHandleWithNonReactiveState {
324+
ui_handle: states.ui_handle,
325+
non_reactive_state: states.non_reactive_state,
326+
});
327+
}
328+
(Some(this), Some(UiHandleWithNonReactiveState { ui_handle, non_reactive_state })) => this.unpinned_render_update(
329+
render_context,
330+
RenderStates {
331+
ui_handle,
332+
non_reactive_state,
333+
reactive_state,
334+
},
335+
),
344336
}
345337
}
346338
}

0 commit comments

Comments
 (0)