This commit is contained in:
Antonio Scandurra 2023-10-26 18:17:45 +02:00
parent 516236e044
commit 8e3314e680
9 changed files with 167 additions and 130 deletions

View file

@ -130,6 +130,7 @@ pub struct AppContext {
pub(crate) text_style_stack: Vec<TextStyleRefinement>,
pub(crate) globals_by_type: HashMap<TypeId, AnyBox>,
pub(crate) unit_entity: Handle<()>,
pub(crate) unit_view: View<()>,
pub(crate) entities: EntityMap,
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
pub(crate) keymap: Arc<Mutex<Keymap>>,
@ -653,12 +654,12 @@ impl AppContext {
}
impl Context for AppContext {
type EntityContext<'a, 'w, T> = ModelContext<'a, T>;
type EntityContext<'a, T> = ModelContext<'a, T>;
type Result<T> = T;
fn entity<T: 'static + Send>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Handle<T> {
self.update(|cx| {
let slot = cx.entities.reserve();
@ -670,7 +671,7 @@ impl Context for AppContext {
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> R {
self.update(|cx| {
let mut entity = cx.entities.lease(handle);

View file

@ -1,6 +1,6 @@
use crate::{
AnyWindowHandle, AppContext, Context, Executor, Handle, MainThread, ModelContext, Result, Task,
ViewContext, WindowContext,
WindowContext,
};
use anyhow::anyhow;
use derive_more::{Deref, DerefMut};
@ -14,12 +14,12 @@ pub struct AsyncAppContext {
}
impl Context for AsyncAppContext {
type EntityContext<'a, 'w, T> = ModelContext<'a, T>;
type EntityContext<'a, T> = ModelContext<'a, T>;
type Result<T> = Result<T>;
fn entity<T: 'static>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Self::Result<Handle<T>>
where
T: 'static + Send,
@ -35,7 +35,7 @@ impl Context for AsyncAppContext {
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> Self::Result<R> {
let app = self
.app
@ -216,12 +216,12 @@ impl AsyncWindowContext {
}
impl Context for AsyncWindowContext {
type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
type EntityContext<'a, T> = ModelContext<'a, T>;
type Result<T> = Result<T>;
fn entity<T>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Result<Handle<T>>
where
T: 'static + Send,
@ -233,7 +233,7 @@ impl Context for AsyncWindowContext {
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> Result<R> {
self.app
.update_window(self.window, |cx| cx.update_entity(handle, update))

View file

@ -284,7 +284,7 @@ impl<T: 'static> Handle<T> {
pub fn update<C, R>(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, T>) -> R,
) -> C::Result<R>
where
C: Context,
@ -427,7 +427,7 @@ impl<T: 'static> WeakHandle<T> {
pub fn update<C, R>(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut C::EntityContext<'_, T>) -> R,
) -> Result<R>
where
C: Context,

View file

@ -224,12 +224,12 @@ where
}
impl<'a, T> Context for ModelContext<'a, T> {
type EntityContext<'b, 'c, U> = ModelContext<'b, U>;
type EntityContext<'b, U> = ModelContext<'b, U>;
type Result<U> = U;
fn entity<U>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, U>) -> U,
) -> Handle<U>
where
U: 'static + Send,
@ -240,7 +240,7 @@ impl<'a, T> Context for ModelContext<'a, T> {
fn update_entity<U: 'static, R>(
&mut self,
handle: &Handle<U>,
update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, U>) -> R,
) -> R {
self.app.update_entity(handle, update)
}

View file

@ -12,12 +12,12 @@ pub struct TestAppContext {
}
impl Context for TestAppContext {
type EntityContext<'a, 'w, T> = ModelContext<'a, T>;
type EntityContext<'a, T> = ModelContext<'a, T>;
type Result<T> = T;
fn entity<T: 'static>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Self::Result<Handle<T>>
where
T: 'static + Send,
@ -29,7 +29,7 @@ impl Context for TestAppContext {
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> Self::Result<R> {
let mut lock = self.app.lock();
lock.update_entity(handle, update)

View file

@ -70,12 +70,12 @@ use taffy::TaffyLayoutEngine;
type AnyBox = Box<dyn Any + Send>;
pub trait Context {
type EntityContext<'a, 'w, T>;
type EntityContext<'a, T>;
type Result<T>;
fn entity<T>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Self::Result<Handle<T>>
where
T: 'static + Send;
@ -83,7 +83,7 @@ pub trait Context {
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> Self::Result<R>;
}
@ -111,12 +111,12 @@ impl<T> DerefMut for MainThread<T> {
}
impl<C: Context> Context for MainThread<C> {
type EntityContext<'a, 'w, T> = MainThread<C::EntityContext<'a, 'w, T>>;
type EntityContext<'a, T> = MainThread<C::EntityContext<'a, T>>;
type Result<T> = C::Result<T>;
fn entity<T>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Self::Result<Handle<T>>
where
T: 'static + Send,
@ -124,8 +124,8 @@ impl<C: Context> Context for MainThread<C> {
self.0.entity(|cx| {
let cx = unsafe {
mem::transmute::<
&mut C::EntityContext<'_, '_, T>,
&mut MainThread<C::EntityContext<'_, '_, T>>,
&mut C::EntityContext<'_, T>,
&mut MainThread<C::EntityContext<'_, T>>,
>(cx)
};
build_entity(cx)
@ -135,13 +135,13 @@ impl<C: Context> Context for MainThread<C> {
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> Self::Result<R> {
self.0.update_entity(handle, |entity, cx| {
let cx = unsafe {
mem::transmute::<
&mut C::EntityContext<'_, '_, T>,
&mut MainThread<C::EntityContext<'_, '_, T>>,
&mut C::EntityContext<'_, T>,
&mut MainThread<C::EntityContext<'_, T>>,
>(cx)
};
update(entity, cx)

View file

@ -331,9 +331,8 @@ pub trait StatefulInteractive<V: 'static>: StatelessInteractive<V> {
self.stateful_interaction().drag_listener =
Some(Box::new(move |view_state, cursor_offset, cx| {
let drag = listener(view_state, cx);
let view_handle = cx.handle().upgrade().unwrap();
let drag_handle_view = Some(
view(view_handle, move |view_state, cx| {
view(cx.handle().upgrade().unwrap(), move |view_state, cx| {
(drag.render_drag_handle)(view_state, cx)
})
.into_any(),

View file

@ -1,31 +1,18 @@
use parking_lot::Mutex;
use crate::{
AnyBox, AnyElement, BorrowWindow, Bounds, Component, Element, ElementId, EntityId, Handle,
LayoutId, Pixels, ViewContext, WindowContext,
LayoutId, Pixels, ViewContext, WeakHandle, WindowContext,
};
use parking_lot::Mutex;
use std::{
marker::PhantomData,
sync::{Arc, Weak},
};
use std::{marker::PhantomData, sync::Arc};
pub struct View<V> {
state: Handle<V>,
pub(crate) state: Handle<V>,
render: Arc<Mutex<dyn Fn(&mut V, &mut ViewContext<V>) -> AnyElement<V> + Send + 'static>>,
}
impl<V: 'static> View<V> {
pub fn into_any(self) -> AnyView {
AnyView(Arc::new(self))
}
}
impl<V> Clone for View<V> {
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
render: self.render.clone(),
}
}
}
pub fn view<V, E>(
state: Handle<V>,
render: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + 'static,
@ -41,6 +28,43 @@ where
}
}
impl<V: 'static> View<V> {
pub fn into_any(self) -> AnyView {
AnyView(Arc::new(self))
}
pub fn downgrade(&self) -> WeakView<V> {
WeakView {
state: self.state.downgrade(),
render: Arc::downgrade(&self.render),
}
}
}
impl<V: 'static> View<V> {
pub fn update<R>(
&self,
cx: &mut WindowContext,
f: impl FnOnce(&mut V, &mut ViewContext<V>) -> R,
) -> R {
let this = self.clone();
let mut lease = cx.app.entities.lease(&self.state);
let mut cx = ViewContext::mutable(&mut *cx.app, &mut *cx.window, this);
let result = f(&mut *lease, &mut cx);
cx.app.entities.end_lease(lease);
result
}
}
impl<V> Clone for View<V> {
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
render: self.render.clone(),
}
}
}
impl<V: 'static, ParentViewState: 'static> Component<ParentViewState> for View<V> {
fn render(self) -> AnyElement<ParentViewState> {
AnyElement::new(EraseViewState {
@ -63,7 +87,7 @@ impl<V: 'static> Element<()> for View<V> {
_: Option<Self::ElementState>,
cx: &mut ViewContext<()>,
) -> Self::ElementState {
self.state.update(cx, |state, cx| {
self.update(cx, |state, cx| {
let mut any_element = (self.render.lock())(state, cx);
any_element.initialize(state, cx);
any_element
@ -76,7 +100,7 @@ impl<V: 'static> Element<()> for View<V> {
element: &mut Self::ElementState,
cx: &mut ViewContext<()>,
) -> LayoutId {
self.state.update(cx, |state, cx| element.layout(state, cx))
self.update(cx, |state, cx| element.layout(state, cx))
}
fn paint(
@ -86,7 +110,20 @@ impl<V: 'static> Element<()> for View<V> {
element: &mut Self::ElementState,
cx: &mut ViewContext<()>,
) {
self.state.update(cx, |state, cx| element.paint(state, cx))
self.update(cx, |state, cx| element.paint(state, cx))
}
}
pub struct WeakView<V> {
state: WeakHandle<V>,
render: Weak<Mutex<dyn Fn(&mut V, &mut ViewContext<V>) -> AnyElement<V> + Send + 'static>>,
}
impl<V> WeakView<V> {
pub fn upgrade(&self) -> Option<View<V>> {
let state = self.state.upgrade()?;
let render = self.render.upgrade()?;
Some(View { state, render })
}
}
@ -153,7 +190,7 @@ impl<V: 'static> ViewObject for View<V> {
fn initialize(&self, cx: &mut WindowContext) -> AnyBox {
cx.with_element_id(self.entity_id(), |_global_id, cx| {
self.state.update(cx, |state, cx| {
self.update(cx, |state, cx| {
let mut any_element = Box::new((self.render.lock())(state, cx));
any_element.initialize(state, cx);
any_element as AnyBox
@ -163,7 +200,7 @@ impl<V: 'static> ViewObject for View<V> {
fn layout(&self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId {
cx.with_element_id(self.entity_id(), |_global_id, cx| {
self.state.update(cx, |state, cx| {
self.update(cx, |state, cx| {
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
element.layout(state, cx)
})
@ -172,7 +209,7 @@ impl<V: 'static> ViewObject for View<V> {
fn paint(&self, _: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext) {
cx.with_element_id(self.entity_id(), |_global_id, cx| {
self.state.update(cx, |state, cx| {
self.update(cx, |state, cx| {
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
element.paint(state, cx);
});

View file

@ -3,12 +3,12 @@ use crate::{
Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
Element, EntityId, EventEmitter, ExternalPaths, FileDropEvent, FocusEvent, FontId,
GlobalElementId, GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch,
KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, Modifiers, MonochromeSprite,
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas,
PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription,
TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle, WindowOptions,
SUBPIXEL_VARIANTS,
KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, ModelContext, Modifiers,
MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels,
PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams,
RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
Style, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, WeakHandle,
WeakView, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::Result;
use collections::HashMap;
@ -281,7 +281,7 @@ impl ContentMask<Pixels> {
}
pub struct WindowContext<'a, 'w> {
app: Reference<'a, AppContext>,
pub(crate) app: Reference<'a, AppContext>,
pub(crate) window: Reference<'w, Window>,
}
@ -800,43 +800,46 @@ impl<'a, 'w> WindowContext<'a, 'w> {
pub(crate) fn draw(&mut self) {
let unit_entity = self.unit_entity.clone();
self.update_entity(&unit_entity, |view, cx| {
cx.start_frame();
let mut root_view = self.window.root_view.take().unwrap();
let mut root_view_cx = ViewContext::mutable(
&mut self.app,
&mut self.window,
self.unit_entity.downgrade(),
);
let mut root_view = cx.window.root_view.take().unwrap();
root_view_cx.start_frame();
cx.stack(0, |cx| {
let available_space = cx.window.content_size.map(Into::into);
draw_any_view(&mut root_view, available_space, cx);
});
if let Some(mut active_drag) = cx.active_drag.take() {
cx.stack(1, |cx| {
let offset = cx.mouse_position() - active_drag.cursor_offset;
cx.with_element_offset(Some(offset), |cx| {
let available_space =
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
if let Some(drag_handle_view) = &mut active_drag.drag_handle_view {
draw_any_view(drag_handle_view, available_space, cx);
}
cx.active_drag = Some(active_drag);
});
});
}
cx.window.root_view = Some(root_view);
let scene = cx.window.scene_builder.build();
cx.run_on_main(view, |_, cx| {
cx.window
.platform_window
.borrow_on_main_thread()
.draw(scene);
cx.window.dirty = false;
})
.detach();
root_view_cx.stack(0, |cx| {
let available_space = cx.window.content_size.map(Into::into);
draw_any_view(&mut root_view, available_space, cx);
});
if let Some(mut active_drag) = self.app.active_drag.take() {
root_view_cx.stack(1, |cx| {
let offset = cx.mouse_position() - active_drag.cursor_offset;
cx.with_element_offset(Some(offset), |cx| {
let available_space =
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
if let Some(drag_handle_view) = &mut active_drag.drag_handle_view {
draw_any_view(drag_handle_view, available_space, cx);
}
cx.active_drag = Some(active_drag);
});
});
}
self.window.root_view = Some(root_view);
let scene = self.window.scene_builder.build();
self.run_on_main(|cx| {
cx.window
.platform_window
.borrow_on_main_thread()
.draw(scene);
cx.window.dirty = false;
})
.detach();
fn draw_any_view(
view: &mut AnyView,
available_space: Size<AvailableSpace>,
@ -1169,34 +1172,30 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
impl Context for WindowContext<'_, '_> {
type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
type EntityContext<'a, T> = ModelContext<'a, T>;
type Result<T> = T;
fn entity<T>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Handle<T>
where
T: 'static + Send,
{
let slot = self.app.entities.reserve();
let entity = build_entity(&mut ViewContext::mutable(
&mut *self.app,
&mut self.window,
slot.downgrade(),
));
let entity = build_entity(&mut ModelContext::mutable(&mut *self.app, slot.downgrade()));
self.entities.insert(slot, entity)
}
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> R {
let mut entity = self.entities.lease(handle);
let result = update(
&mut *entity,
&mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.downgrade()),
&mut ModelContext::mutable(&mut *self.app, handle.downgrade()),
);
self.entities.end_lease(entity);
result
@ -1389,7 +1388,7 @@ impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
pub struct ViewContext<'a, 'w, V> {
window_cx: WindowContext<'a, 'w>,
view_state: WeakHandle<V>,
view: View<V>,
}
impl<V> Borrow<AppContext> for ViewContext<'_, '_, V> {
@ -1417,15 +1416,19 @@ impl<V> BorrowMut<Window> for ViewContext<'_, '_, V> {
}
impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
fn mutable(app: &'a mut AppContext, window: &'w mut Window, view_state: WeakHandle<V>) -> Self {
pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window, view: View<V>) -> Self {
Self {
window_cx: WindowContext::mutable(app, window),
view_state,
view,
}
}
pub fn view(&self) -> WeakView<V> {
self.view.downgrade()
}
pub fn handle(&self) -> WeakHandle<V> {
self.view_state.clone()
self.view.state.downgrade()
}
pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
@ -1439,10 +1442,8 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
where
V: Any + Send,
{
let entity = self.handle();
self.window_cx.on_next_frame(move |cx| {
entity.update(cx, f).ok();
});
let view = self.view();
self.window_cx.on_next_frame(move |cx| view.update(cx, f));
}
pub fn observe<E>(
@ -1454,7 +1455,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
E: 'static,
V: Any + Send,
{
let this = self.handle();
let view = self.view();
let handle = handle.downgrade();
let window_handle = self.window.handle;
self.app.observers.insert(
@ -1462,7 +1463,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
Box::new(move |cx| {
cx.update_window(window_handle.id, |cx| {
if let Some(handle) = handle.upgrade() {
this.update(cx, |this, cx| on_notify(this, handle, cx))
view.update(cx, |this, cx| on_notify(this, handle, cx))
.is_ok()
} else {
false
@ -1480,7 +1481,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
+ Send
+ 'static,
) -> Subscription {
let this = self.handle();
let this = self.view();
let handle = handle.downgrade();
let window_handle = self.window.handle;
self.app.event_listeners.insert(
@ -1490,7 +1491,6 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
if let Some(handle) = handle.upgrade() {
let event = event.downcast_ref().expect("invalid event type");
this.update(cx, |this, cx| on_event(this, handle, event, cx))
.is_ok()
} else {
false
}
@ -1506,7 +1506,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
) -> Subscription {
let window_handle = self.window.handle;
self.app.release_listeners.insert(
self.view_state.entity_id,
self.view.entity_id,
Box::new(move |this, cx| {
let this = this.downcast_mut().expect("invalid entity type");
// todo!("are we okay with silently swallowing the error?")
@ -1523,7 +1523,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
where
V: Any + Send,
{
let this = self.handle();
let this = self.view();
let window_handle = self.window.handle;
self.app.release_listeners.insert(
handle.entity_id,
@ -1540,7 +1540,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
pub fn notify(&mut self) {
self.window_cx.notify();
self.window_cx.app.push_effect(Effect::Notify {
emitter: self.view_state.entity_id,
emitter: self.view.entity_id,
});
}
@ -1548,7 +1548,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
&mut self,
listener: impl Fn(&mut V, &FocusEvent, &mut ViewContext<V>) + Send + 'static,
) {
let handle = self.handle();
let handle = self.view();
self.window.focus_listeners.push(Box::new(move |event, cx| {
handle
.update(cx, |view, cx| listener(view, event, cx))
@ -1564,7 +1564,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
let old_stack_len = self.window.key_dispatch_stack.len();
if !self.window.freeze_key_dispatch_stack {
for (event_type, listener) in key_listeners {
let handle = self.handle();
let handle = self.view();
let listener = Box::new(
move |event: &dyn Any,
context_stack: &[&DispatchContext],
@ -1654,7 +1654,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
Task::ready(Ok(f(view, cx)))
} else {
let handle = self.handle().upgrade().unwrap();
let handle = self.view().upgrade().unwrap();
self.window_cx.run_on_main(move |cx| handle.update(cx, f))
}
}
@ -1667,7 +1667,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
R: Send + 'static,
Fut: Future<Output = R> + Send + 'static,
{
let handle = self.handle();
let handle = self.view();
self.window_cx.spawn(move |_, cx| {
let result = f(handle, cx);
async move { result.await }
@ -1689,7 +1689,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
f: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) + Send + 'static,
) -> Subscription {
let window_id = self.window.handle.id;
let handle = self.handle();
let handle = self.view();
self.global_observers.insert(
TypeId::of::<G>(),
Box::new(move |cx| {
@ -1705,7 +1705,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
&mut self,
handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + Send + 'static,
) {
let handle = self.handle().upgrade().unwrap();
let handle = self.view().upgrade().unwrap();
self.window_cx.on_mouse_event(move |event, phase, cx| {
handle.update(cx, |view, cx| {
handler(view, event, phase, cx);
@ -1720,7 +1720,7 @@ where
V::Event: Any + Send,
{
pub fn emit(&mut self, event: V::Event) {
let emitter = self.view_state.entity_id;
let emitter = self.view.entity_id;
self.app.push_effect(Effect::Emit {
emitter,
event: Box::new(event),
@ -1729,12 +1729,12 @@ where
}
impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
type EntityContext<'b, 'c, U> = ViewContext<'b, 'c, U>;
type EntityContext<'b, U> = ModelContext<'b, U>;
type Result<U> = U;
fn entity<T>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
) -> Handle<T>
where
T: 'static + Send,
@ -1745,7 +1745,7 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
fn update_entity<T: 'static, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
) -> R {
self.window_cx.update_entity(handle, update)
}