Skip to content

Commit a7dd2cc

Browse files
committed
wip: redesign csr
1 parent 3c5d386 commit a7dd2cc

File tree

24 files changed

+690
-694
lines changed

24 files changed

+690
-694
lines changed

packages/frender-common/src/reactive_value.rs

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4844
pub trait ProvideValueOfKind<VK: ?Sized + ReactiveValueKind> {
@@ -58,13 +54,19 @@ pub trait ReusableRendererOfKind<VK: ?Sized + ReactiveValueKind> {
5854

5955
pub 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> +
103105
impl<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+
}

packages/frender-common/src/reactive_value/csr_str.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use crate::{
66
};
77

88
use super::{
9-
ReactiveValue, ReactiveValueKind, ReactiveValueRenderInitPinned, ReactiveValueState,
10-
ReusableRendererOfKind,
9+
ReactiveValue, ReactiveValueKind, ReactiveValueState, RenderInitPinned, ReusableRendererOfKind,
1110
};
1211

1312
impl ReactiveValueKind for str {
@@ -37,43 +36,43 @@ impl<C> ReactiveValueState for State<C> {
3736
}
3837
}
3938

40-
pub struct RenderInit<Cache>(PhantomData<Cache>);
39+
pub struct RenderInit;
4140

42-
impl<Cache: ToAsRefStr> ReactiveValueRenderInitPinned<str> for RenderInit<Cache> {
43-
type State = State<Cache>;
44-
45-
fn render_init_pinned<Out>(
46-
self,
47-
renderer: impl FnOnce(TempStr<&str>) -> Out,
48-
state: Pin<&mut Self::State>,
49-
) -> Out {
41+
impl<Cache: ToAsRefStr, R: FnOnce(TempStr<&str>) -> Out, Out> RenderInitPinned<R, State<Cache>>
42+
for RenderInit
43+
{
44+
type Output = Out;
45+
fn render_init_pinned(self, renderer: R, state: Pin<&mut State<Cache>>) -> Self::Output {
5046
let State(cache) = state.get_mut();
5147
renderer(TempStr(cache.to_as_ref_str().as_ref()))
5248
}
5349
}
5450

5551
/// [`CsrStr`] are non reactive
5652
impl<T: CsrStr> ReactiveValue<str> for T {
57-
super::impl_reactive_value_unpinned_with_pinned!(
53+
type PinnedState = State<T::StaticStrCache>;
54+
type UnpinnedState = State<T::StaticStrCache>;
55+
type PinnedRenderInit<R: FnOnce(<str as ReactiveValueKind>::Value<'_>) -> Out, Out> =
56+
RenderInit;
57+
58+
crate::impl_reactive_value_with_mixed_unpinned!(
5859
type ReactiveValueKind = str;
5960
);
6061

61-
type PinnedState = State<T::StaticStrCache>;
62-
type PinnedRenderInit = RenderInit<T::StaticStrCache>;
63-
64-
fn pinned_render_init(self) -> (Self::PinnedState, Self::PinnedRenderInit) {
62+
fn pinned_render_init<R: FnOnce(<str as ReactiveValueKind>::Value<'_>) -> Out, Out>(
63+
self,
64+
) -> (Self::PinnedState, Self::PinnedRenderInit<R, Out>) {
6565
(
6666
State(self.into_into_static_str_cache().into_static_str_cache()),
67-
RenderInit(PhantomData),
67+
RenderInit,
6868
)
6969
}
7070

71-
fn pinned_render_init_by_reusing<Out>(
71+
fn unpinned_render_init_by_reusing<Out>(
7272
self,
7373
renderer: impl ReusableRendererOfKind<str, Output = Out>,
74-
reused_state: Pin<&mut Self::PinnedState>,
74+
State(cache): &mut Self::PinnedState,
7575
) -> Out {
76-
let State(cache) = reused_state.get_mut();
7776
if self.match_static_str_cache(cache) {
7877
struct Provide<'a, C>(&'a C);
7978

@@ -93,12 +92,11 @@ impl<T: CsrStr> ReactiveValue<str> for T {
9392
}
9493
}
9594

96-
fn pinned_render_update<Out>(
95+
fn unpinned_render_update<Out>(
9796
self,
9897
renderer: impl FnOnce(<str as super::ReactiveValueKind>::Value<'_>) -> Out,
99-
state: Pin<&mut Self::PinnedState>,
98+
State(cache): &mut Self::PinnedState,
10099
) -> Option<Out> {
101-
let State(cache) = state.get_mut();
102100
if self.match_static_str_cache(cache) {
103101
None
104102
} else {

packages/frender-common/src/reactive_value/simple_non_reactive.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use frender_macro_rules::impl_many;
44

55
use crate::{csr::StateUnmount, reactive_value::ProvideValueOfKind};
66

7-
use super::{ReactiveValue, ReactiveValueKind, ReactiveValueRenderInitPinned, ReactiveValueState};
7+
use super::{ReactiveValue, ReactiveValueKind, ReactiveValueState, RenderInitPinned};
88

99
trait KnownSimpleNonReactive: 'static + Copy + PartialEq {}
1010

@@ -54,38 +54,38 @@ impl<T: KnownSimpleNonReactive> ReactiveValueState for State<T> {
5454
}
5555
}
5656

57-
pub struct RenderInit<T>(PhantomData<T>);
57+
pub struct RenderInit;
5858

59-
impl<T: KnownSimpleNonReactive> ReactiveValueRenderInitPinned<T> for RenderInit<T> {
60-
type State = State<T>;
59+
impl<T: KnownSimpleNonReactive, R: FnOnce(<T as ReactiveValueKind>::Value<'_>) -> Out, Out>
60+
RenderInitPinned<R, State<T>> for RenderInit
61+
{
62+
type Output = Out;
6163

62-
fn render_init_pinned<Out>(
63-
self,
64-
renderer: impl FnOnce(T) -> Out,
65-
state: std::pin::Pin<&mut Self::State>,
66-
) -> Out {
64+
fn render_init_pinned(self, renderer: R, state: std::pin::Pin<&mut State<T>>) -> Self::Output {
6765
renderer(state.0)
6866
}
6967
}
7068

7169
impl<T: KnownSimpleNonReactive> ReactiveValue<T> for T {
72-
super::impl_reactive_value_unpinned_with_pinned!(
70+
type PinnedState = State<T>;
71+
type PinnedRenderInit<R: FnOnce(<T as ReactiveValueKind>::Value<'_>) -> Out, Out> = RenderInit;
72+
type UnpinnedState = State<T>;
73+
74+
crate::impl_reactive_value_with_mixed_unpinned!(
7375
type ReactiveValueKind = T;
7476
);
7577

76-
type PinnedState = State<T>;
77-
type PinnedRenderInit = RenderInit<T>;
78-
79-
fn pinned_render_init(self) -> (Self::PinnedState, Self::PinnedRenderInit) {
80-
(State(self), RenderInit(PhantomData))
78+
fn pinned_render_init<R: FnOnce(<T as ReactiveValueKind>::Value<'_>) -> Out, Out>(
79+
self,
80+
) -> (Self::PinnedState, Self::PinnedRenderInit<R, Out>) {
81+
(State(self), RenderInit)
8182
}
8283

83-
fn pinned_render_init_by_reusing<Out>(
84+
fn unpinned_render_init_by_reusing<Out>(
8485
self,
8586
renderer: impl super::ReusableRendererOfKind<T, Output = Out>,
86-
reused_state: std::pin::Pin<&mut Self::PinnedState>,
87+
State(cache): &mut Self::PinnedState,
8788
) -> Out {
88-
let State(cache) = reused_state.get_mut();
8989
if self == *cache {
9090
struct Provide<T>(T);
9191

@@ -102,12 +102,11 @@ impl<T: KnownSimpleNonReactive> ReactiveValue<T> for T {
102102
}
103103
}
104104

105-
fn pinned_render_update<Out>(
105+
fn unpinned_render_update<Out>(
106106
self,
107107
renderer: impl FnOnce(T) -> Out,
108-
state: std::pin::Pin<&mut Self::PinnedState>,
108+
State(cache): &mut Self::PinnedState,
109109
) -> Option<Out> {
110-
let State(cache) = state.get_mut();
111110
if self == *cache {
112111
None
113112
} else {
Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,54 @@
1+
use std::pin::Pin;
2+
3+
use frender_common::reactive_value::RenderInitPinned;
14
pub use frender_common::{HandleEvent, MaybeHandleEvent};
25

3-
pub trait RegisterOrUpdate<N: ?Sized, R: ?Sized, F> {
4-
fn register_or_update(self: std::pin::Pin<&mut Self>, node: &mut N, renderer: &mut R, f: F);
6+
pub trait PinnedRegisterUpdate<N: ?Sized, R: ?Sized, F> {
7+
type PinnedRegisterInit: for<'n, 'r> RenderInitPinned<
8+
//
9+
(&'n mut N, &'r mut R),
10+
Self,
11+
Output = (),
12+
>;
13+
fn pinned_register_init(
14+
node: &mut N,
15+
renderer: &mut R,
16+
f: F,
17+
) -> (Self, Self::PinnedRegisterInit)
18+
where
19+
Self: Sized;
20+
fn pinned_update(self: Pin<&mut Self>, node: &mut N, renderer: &mut R, f: F);
521
}
622

723
pub trait RegisterUpdate<N: ?Sized, R: ?Sized, F> {
824
fn register(node: &mut N, renderer: &mut R, f: F) -> Self;
925
fn update(&mut self, node: &mut N, renderer: &mut R, f: F);
1026
}
27+
28+
/*
29+
impl<
30+
//
31+
T: RegisterUpdate<N, R, F> + Unpin,
32+
N: ?Sized,
33+
R: ?Sized,
34+
F,
35+
> PinnedRegisterUpdate<N, R, F> for T
36+
{
37+
type PinnedRegisterInit = ();
38+
fn pinned_register(node: &mut N, renderer: &mut R, f: F) -> Self {
39+
T::register(node, renderer, f)
40+
}
41+
42+
fn pinned_register_init(
43+
self: Pin<&mut Self>,
44+
_: &mut N,
45+
_: &mut R,
46+
(): Self::PinnedRegisterInit,
47+
) {
48+
}
49+
50+
fn pinned_update(self: Pin<&mut Self>, node: &mut N, renderer: &mut R, f: F) {
51+
self.get_mut().update(node, renderer, f)
52+
}
53+
}
54+
*/

0 commit comments

Comments
 (0)