use parking_lot::Mutex; use crate::{ AnyElement, Bounds, Element, Handle, IntoAnyElement, LayoutId, Pixels, Result, ViewContext, WindowContext, }; use std::{any::Any, marker::PhantomData, sync::Arc}; pub struct View { state: Handle, render: Arc) -> AnyElement + Send + Sync + 'static>, parent_state_type: PhantomData

, } impl View { pub fn into_any(self) -> AnyView

{ AnyView { view: Arc::new(Mutex::new(self)), parent_state_type: PhantomData, } } } impl Clone for View { fn clone(&self) -> Self { Self { state: self.state.clone(), render: self.render.clone(), parent_state_type: PhantomData, } } } pub type RootView = View; pub fn view( state: Handle, render: impl Fn(&mut S, &mut ViewContext) -> E + Send + Sync + 'static, ) -> View where S: 'static + Send + Sync, P: 'static, E: Element, { View { state, render: Arc::new(move |state, cx| render(state, cx).into_any()), parent_state_type: PhantomData, } } impl Element for View { type State = P; type FrameState = AnyElement; fn layout( &mut self, _: &mut Self::State, cx: &mut ViewContext, ) -> Result<(LayoutId, Self::FrameState)> { self.state.update(cx, |state, cx| { let mut element = (self.render)(state, cx); let layout_id = element.layout(state, cx)?; Ok((layout_id, element)) }) } fn paint( &mut self, _: Bounds, _: &mut Self::State, element: &mut Self::FrameState, cx: &mut ViewContext, ) -> Result<()> { self.state .update(cx, |state, cx| element.paint(state, None, cx)) } } trait ViewObject: Send + 'static { fn layout(&mut self, cx: &mut WindowContext) -> Result<(LayoutId, Box)>; fn paint( &mut self, bounds: Bounds, element: &mut dyn Any, cx: &mut WindowContext, ) -> Result<()>; } impl ViewObject for View { fn layout(&mut self, cx: &mut WindowContext) -> Result<(LayoutId, Box)> { self.state.update(cx, |state, cx| { let mut element = (self.render)(state, cx); let layout_id = element.layout(state, cx)?; let element = Box::new(element) as Box; Ok((layout_id, element)) }) } fn paint( &mut self, _: Bounds, element: &mut dyn Any, cx: &mut WindowContext, ) -> Result<()> { self.state.update(cx, |state, cx| { let element = element.downcast_mut::>().unwrap(); element.paint(state, None, cx) }) } } pub struct AnyView { view: Arc>, parent_state_type: PhantomData, } impl Element for AnyView { type State = (); type FrameState = Box; fn layout( &mut self, _: &mut Self::State, cx: &mut ViewContext, ) -> Result<(LayoutId, Self::FrameState)> { self.view.lock().layout(cx) } fn paint( &mut self, bounds: Bounds, _: &mut (), element: &mut Box, cx: &mut ViewContext, ) -> Result<()> { self.view.lock().paint(bounds, element.as_mut(), cx) } } impl Clone for AnyView { fn clone(&self) -> Self { Self { view: self.view.clone(), parent_state_type: PhantomData, } } }