any_props.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. use std::marker::PhantomData;
  2. use futures_util::Future;
  3. use crate::{
  4. factory::ReturnType,
  5. scopes::{Scope, ScopeState},
  6. Element,
  7. };
  8. pub trait AnyProps<'a> {
  9. fn as_ptr(&self) -> *const ();
  10. fn render(&'a self, bump: &'a ScopeState) -> Element<'a>;
  11. unsafe fn memoize(&self, other: &dyn AnyProps) -> bool;
  12. }
  13. pub(crate) struct VComponentProps<'a, P, A, F = Element<'a>>
  14. where
  15. F: ReturnType<'a, A>,
  16. {
  17. pub render_fn: fn(Scope<'a, P>) -> F,
  18. pub memo: unsafe fn(&P, &P) -> bool,
  19. pub props: *const P,
  20. pub _marker: PhantomData<A>,
  21. }
  22. impl<'a> VComponentProps<'a, (), ()> {
  23. pub fn new_empty(render_fn: fn(Scope) -> Element) -> Self {
  24. Self {
  25. render_fn,
  26. memo: <() as PartialEq>::eq,
  27. props: std::ptr::null_mut(),
  28. _marker: PhantomData,
  29. }
  30. }
  31. }
  32. impl<'a, P, A, F: ReturnType<'a, A>> VComponentProps<'a, P, A, F> {
  33. pub(crate) fn new(
  34. render_fn: fn(Scope<'a, P>) -> F,
  35. memo: unsafe fn(&P, &P) -> bool,
  36. props: *const P,
  37. ) -> Self {
  38. Self {
  39. render_fn,
  40. memo,
  41. props,
  42. _marker: PhantomData,
  43. }
  44. }
  45. }
  46. impl<'a, P, A, F: ReturnType<'a, A>> AnyProps<'a> for VComponentProps<'a, P, A, F> {
  47. fn as_ptr(&self) -> *const () {
  48. &self.props as *const _ as *const ()
  49. }
  50. // Safety:
  51. // this will downcast the other ptr as our swallowed type!
  52. // you *must* make this check *before* calling this method
  53. // if your functions are not the same, then you will downcast a pointer into a different type (UB)
  54. unsafe fn memoize(&self, other: &dyn AnyProps) -> bool {
  55. let real_other: &P = &*(other.as_ptr() as *const _ as *const P);
  56. let real_us: &P = &*(self.as_ptr() as *const _ as *const P);
  57. (self.memo)(real_us, real_other)
  58. }
  59. fn render<'b>(&'b self, scope: &'b ScopeState) -> Element<'b> {
  60. // Make sure the scope ptr is not null
  61. // self.props.state.set(scope);
  62. let scope = Scope {
  63. props: unsafe { &*self.props },
  64. scope,
  65. };
  66. // Call the render function directly
  67. // todo: implement async
  68. // let res = match self.render_fn {
  69. // ComponentFn::Sync(f) => {
  70. // let f = unsafe { std::mem::transmute(f) };
  71. // f(scope)
  72. // }
  73. // ComponentFn::Async(_) => todo!(),
  74. // };
  75. todo!()
  76. }
  77. }