This commit is contained in:
Nathan Sobo 2023-08-10 10:26:48 -06:00
parent dd6425e898
commit 0bf607cd2d
48 changed files with 319 additions and 325 deletions

View file

@ -7,42 +7,6 @@ pub mod test_app_context;
pub(crate) mod window;
mod window_input_handler;
use std::{
any::{type_name, Any, TypeId},
cell::RefCell,
fmt::{self, Debug},
hash::{Hash, Hasher},
marker::PhantomData,
mem,
ops::{Deref, DerefMut, Range},
path::{Path, PathBuf},
pin::Pin,
rc::{self, Rc},
sync::{Arc, Weak},
time::Duration,
};
use anyhow::{anyhow, Context, Result};
use derive_more::Deref;
use parking_lot::Mutex;
use postage::oneshot;
use smallvec::SmallVec;
use smol::prelude::*;
use util::ResultExt;
use uuid::Uuid;
pub use action::*;
use callback_collection::CallbackCollection;
use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
pub use menu::*;
use platform::Event;
#[cfg(any(test, feature = "test-support"))]
use ref_counts::LeakDetector;
#[cfg(any(test, feature = "test-support"))]
pub use test_app_context::{ContextHandle, TestAppContext};
use window_input_handler::WindowInputHandler;
use crate::{
elements::{AnyElement, AnyRootElement, RootElement},
executor::{self, Task},
@ -57,8 +21,39 @@ use crate::{
window::{Window, WindowContext},
AssetCache, AssetSource, ClipboardItem, FontCache, MouseRegionId,
};
use self::ref_counts::RefCounts;
pub use action::*;
use anyhow::{anyhow, Context, Result};
use callback_collection::CallbackCollection;
use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
use derive_more::Deref;
pub use menu::*;
use parking_lot::Mutex;
use platform::Event;
use postage::oneshot;
#[cfg(any(test, feature = "test-support"))]
use ref_counts::LeakDetector;
use ref_counts::RefCounts;
use smallvec::SmallVec;
use smol::prelude::*;
use std::{
any::{type_name, Any, TypeId},
cell::RefCell,
fmt::{self, Debug},
hash::{Hash, Hasher},
marker::PhantomData,
mem,
ops::{Deref, DerefMut, Range},
path::{Path, PathBuf},
pin::Pin,
rc::{self, Rc},
sync::{Arc, Weak},
time::Duration,
};
#[cfg(any(test, feature = "test-support"))]
pub use test_app_context::{ContextHandle, TestAppContext};
use util::ResultExt;
use uuid::Uuid;
use window_input_handler::WindowInputHandler;
pub trait Entity: 'static {
type Event;
@ -634,7 +629,7 @@ impl AppContext {
pub fn add_action<A, V, F, R>(&mut self, handler: F)
where
A: Action,
V: View,
V: 'static,
F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
{
self.add_action_internal(handler, false)
@ -643,7 +638,7 @@ impl AppContext {
pub fn capture_action<A, V, F>(&mut self, handler: F)
where
A: Action,
V: View,
V: 'static,
F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
{
self.add_action_internal(handler, true)
@ -652,7 +647,7 @@ impl AppContext {
fn add_action_internal<A, V, F, R>(&mut self, mut handler: F, capture: bool)
where
A: Action,
V: View,
V: 'static,
F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
{
let handler = Box::new(
@ -693,7 +688,7 @@ impl AppContext {
pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
where
A: Action,
V: View,
V: 'static,
F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
{
self.add_action(move |view, action, cx| {
@ -892,8 +887,8 @@ impl AppContext {
fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
where
V: 'static,
F: 'static + FnMut(ViewHandle<V>, bool, &mut WindowContext) -> bool,
V: View,
{
let subscription_id = post_inc(&mut self.next_subscription_id);
let observed = handle.downgrade();
@ -1376,15 +1371,15 @@ impl AppContext {
self.windows.keys().copied()
}
pub fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
pub fn read_view<V: 'static>(&self, handle: &ViewHandle<V>) -> &V {
if let Some(view) = self.views.get(&(handle.window, handle.view_id)) {
view.as_any().downcast_ref().expect("downcast is type safe")
} else {
panic!("circular view reference for type {}", type_name::<T>());
panic!("circular view reference for type {}", type_name::<V>());
}
}
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
fn upgrade_view_handle<V: 'static>(&self, handle: &WeakViewHandle<V>) -> Option<ViewHandle<V>> {
if self.ref_counts.lock().is_entity_alive(handle.view_id) {
Some(ViewHandle::new(
handle.window,
@ -2537,10 +2532,7 @@ pub trait AnyView {
}
}
impl<V> AnyView for V
where
V: View,
{
impl<V: View> AnyView for V {
fn as_any(&self) -> &dyn Any {
self
}
@ -2872,7 +2864,7 @@ pub struct ViewContext<'a, 'b, T: ?Sized> {
view_type: PhantomData<T>,
}
impl<'a, 'b, T: View> Deref for ViewContext<'a, 'b, T> {
impl<'a, 'b, V> Deref for ViewContext<'a, 'b, V> {
type Target = WindowContext<'a>;
fn deref(&self) -> &Self::Target {
@ -2880,13 +2872,13 @@ impl<'a, 'b, T: View> Deref for ViewContext<'a, 'b, T> {
}
}
impl<T: View> DerefMut for ViewContext<'_, '_, T> {
impl<'a, 'b, V> DerefMut for ViewContext<'a, 'b, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.window_context
}
}
impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> {
pub(crate) fn mutable(window_context: &'b mut WindowContext<'a>, view_id: usize) -> Self {
Self {
window_context: Reference::Mutable(window_context),
@ -2907,6 +2899,12 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
&mut self.window_context
}
pub fn notify(&mut self) {
let window = self.window_handle;
let view_id = self.view_id;
self.window_context.notify_view(window, view_id);
}
pub fn handle(&self) -> ViewHandle<V> {
ViewHandle::new(
self.window_handle,
@ -3220,21 +3218,6 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
})
}
pub fn emit(&mut self, payload: V::Event) {
self.window_context
.pending_effects
.push_back(Effect::Event {
entity_id: self.view_id,
payload: Box::new(payload),
});
}
pub fn notify(&mut self) {
let window = self.window_handle;
let view_id = self.view_id;
self.window_context.notify_view(window, view_id);
}
pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
let handle = self.handle();
self.window_context
@ -3327,6 +3310,17 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
}
}
impl<V: View> ViewContext<'_, '_, V> {
pub fn emit(&mut self, payload: V::Event) {
self.window_context
.pending_effects
.push_back(Effect::Event {
entity_id: self.view_id,
payload: Box::new(payload),
});
}
}
impl<V> BorrowAppContext for ViewContext<'_, '_, V> {
fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
BorrowAppContext::read_with(&*self.window_context, f)
@ -3375,7 +3369,7 @@ pub struct LayoutContext<'a, 'b, 'c, V> {
pub refreshing: bool,
}
impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> LayoutContext<'a, 'b, 'c, V> {
pub fn new(
view_context: &'c mut ViewContext<'a, 'b, V>,
new_parents: &'c mut HashMap<usize, usize>,
@ -3458,7 +3452,7 @@ impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> {
}
}
impl<'a, 'b, 'c, V: View> Deref for LayoutContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> Deref for LayoutContext<'a, 'b, 'c, V> {
type Target = ViewContext<'a, 'b, V>;
fn deref(&self) -> &Self::Target {
@ -3466,13 +3460,13 @@ impl<'a, 'b, 'c, V: View> Deref for LayoutContext<'a, 'b, 'c, V> {
}
}
impl<V: View> DerefMut for LayoutContext<'_, '_, '_, V> {
impl<V> DerefMut for LayoutContext<'_, '_, '_, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.view_context
}
}
impl<V: View> BorrowAppContext for LayoutContext<'_, '_, '_, V> {
impl<V> BorrowAppContext for LayoutContext<'_, '_, '_, V> {
fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
BorrowAppContext::read_with(&*self.view_context, f)
}
@ -3482,7 +3476,7 @@ impl<V: View> BorrowAppContext for LayoutContext<'_, '_, '_, V> {
}
}
impl<V: View> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
impl<V> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
type Result<T> = T;
fn read_window<T, F: FnOnce(&WindowContext) -> T>(&self, window: AnyWindowHandle, f: F) -> T {
@ -3512,12 +3506,12 @@ impl<V: View> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
}
}
pub struct PaintContext<'a, 'b, 'c, V: View> {
pub struct PaintContext<'a, 'b, 'c, V> {
view_context: &'c mut ViewContext<'a, 'b, V>,
text_style_stack: Vec<Arc<TextStyle>>,
}
impl<'a, 'b, 'c, V: View> PaintContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> PaintContext<'a, 'b, 'c, V> {
pub fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self {
Self {
view_context,
@ -3544,7 +3538,7 @@ impl<'a, 'b, 'c, V: View> PaintContext<'a, 'b, 'c, V> {
}
}
impl<'a, 'b, 'c, V: View> Deref for PaintContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> Deref for PaintContext<'a, 'b, 'c, V> {
type Target = ViewContext<'a, 'b, V>;
fn deref(&self) -> &Self::Target {
@ -3552,13 +3546,13 @@ impl<'a, 'b, 'c, V: View> Deref for PaintContext<'a, 'b, 'c, V> {
}
}
impl<V: View> DerefMut for PaintContext<'_, '_, '_, V> {
impl<V> DerefMut for PaintContext<'_, '_, '_, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.view_context
}
}
impl<V: View> BorrowAppContext for PaintContext<'_, '_, '_, V> {
impl<V> BorrowAppContext for PaintContext<'_, '_, '_, V> {
fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
BorrowAppContext::read_with(&*self.view_context, f)
}
@ -3568,7 +3562,7 @@ impl<V: View> BorrowAppContext for PaintContext<'_, '_, '_, V> {
}
}
impl<V: View> BorrowWindowContext for PaintContext<'_, '_, '_, V> {
impl<V> BorrowWindowContext for PaintContext<'_, '_, '_, V> {
type Result<T> = T;
fn read_window<T, F>(&self, window: AnyWindowHandle, f: F) -> Self::Result<T>
@ -3600,12 +3594,12 @@ impl<V: View> BorrowWindowContext for PaintContext<'_, '_, '_, V> {
}
}
pub struct EventContext<'a, 'b, 'c, V: View> {
pub struct EventContext<'a, 'b, 'c, V> {
view_context: &'c mut ViewContext<'a, 'b, V>,
pub(crate) handled: bool,
}
impl<'a, 'b, 'c, V: View> EventContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> EventContext<'a, 'b, 'c, V> {
pub(crate) fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self {
EventContext {
view_context,
@ -3618,7 +3612,7 @@ impl<'a, 'b, 'c, V: View> EventContext<'a, 'b, 'c, V> {
}
}
impl<'a, 'b, 'c, V: View> Deref for EventContext<'a, 'b, 'c, V> {
impl<'a, 'b, 'c, V> Deref for EventContext<'a, 'b, 'c, V> {
type Target = ViewContext<'a, 'b, V>;
fn deref(&self) -> &Self::Target {
@ -3626,13 +3620,13 @@ impl<'a, 'b, 'c, V: View> Deref for EventContext<'a, 'b, 'c, V> {
}
}
impl<V: View> DerefMut for EventContext<'_, '_, '_, V> {
impl<V> DerefMut for EventContext<'_, '_, '_, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.view_context
}
}
impl<V: View> BorrowAppContext for EventContext<'_, '_, '_, V> {
impl<V> BorrowAppContext for EventContext<'_, '_, '_, V> {
fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
BorrowAppContext::read_with(&*self.view_context, f)
}
@ -3642,7 +3636,7 @@ impl<V: View> BorrowAppContext for EventContext<'_, '_, '_, V> {
}
}
impl<V: View> BorrowWindowContext for EventContext<'_, '_, '_, V> {
impl<V> BorrowWindowContext for EventContext<'_, '_, '_, V> {
type Result<T> = T;
fn read_window<T, F: FnOnce(&WindowContext) -> T>(&self, window: AnyWindowHandle, f: F) -> T {
@ -3970,7 +3964,7 @@ impl<V> Clone for WindowHandle<V> {
impl<V> Copy for WindowHandle<V> {}
impl<V: View> WindowHandle<V> {
impl<V: 'static> WindowHandle<V> {
fn new(window_id: usize) -> Self {
WindowHandle {
any_handle: AnyWindowHandle::new(window_id, TypeId::of::<V>()),
@ -4008,7 +4002,9 @@ impl<V: View> WindowHandle<V> {
.update(cx, update)
})
}
}
impl<V: View> WindowHandle<V> {
pub fn replace_root<C, F>(&self, cx: &mut C, build_root: F) -> C::Result<ViewHandle<V>>
where
C: BorrowWindowContext,
@ -4088,7 +4084,7 @@ impl AnyWindowHandle {
self.update(cx, |cx| cx.add_view(build_view))
}
pub fn downcast<V: View>(self) -> Option<WindowHandle<V>> {
pub fn downcast<V: 'static>(self) -> Option<WindowHandle<V>> {
if self.root_view_type == TypeId::of::<V>() {
Some(WindowHandle {
any_handle: self,
@ -4099,7 +4095,7 @@ impl AnyWindowHandle {
}
}
pub fn root_is<V: View>(&self) -> bool {
pub fn root_is<V: 'static>(&self) -> bool {
self.root_view_type == TypeId::of::<V>()
}
@ -4177,9 +4173,9 @@ impl AnyWindowHandle {
}
#[repr(transparent)]
pub struct ViewHandle<T> {
pub struct ViewHandle<V> {
any_handle: AnyViewHandle,
view_type: PhantomData<T>,
view_type: PhantomData<V>,
}
impl<T> Deref for ViewHandle<T> {
@ -4190,15 +4186,15 @@ impl<T> Deref for ViewHandle<T> {
}
}
impl<T: View> ViewHandle<T> {
impl<V: 'static> ViewHandle<V> {
fn new(window: AnyWindowHandle, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
Self {
any_handle: AnyViewHandle::new(window, view_id, TypeId::of::<T>(), ref_counts.clone()),
any_handle: AnyViewHandle::new(window, view_id, TypeId::of::<V>(), ref_counts.clone()),
view_type: PhantomData,
}
}
pub fn downgrade(&self) -> WeakViewHandle<T> {
pub fn downgrade(&self) -> WeakViewHandle<V> {
WeakViewHandle::new(self.window, self.view_id)
}
@ -4214,14 +4210,14 @@ impl<T: View> ViewHandle<T> {
self.view_id
}
pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
pub fn read<'a>(&self, cx: &'a AppContext) -> &'a V {
cx.read_view(self)
}
pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> C::Result<S>
where
C: BorrowWindowContext,
F: FnOnce(&T, &ViewContext<T>) -> S,
F: FnOnce(&V, &ViewContext<V>) -> S,
{
cx.read_window(self.window, |cx| {
let cx = ViewContext::immutable(cx, self.view_id);
@ -4232,7 +4228,7 @@ impl<T: View> ViewHandle<T> {
pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> C::Result<S>
where
C: BorrowWindowContext,
F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
F: FnOnce(&mut V, &mut ViewContext<V>) -> S,
{
let mut update = Some(update);
@ -4368,8 +4364,8 @@ impl AnyViewHandle {
TypeId::of::<T>() == self.view_type
}
pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
if self.is::<T>() {
pub fn downcast<V: 'static>(self) -> Option<ViewHandle<V>> {
if self.is::<V>() {
Some(ViewHandle {
any_handle: self,
view_type: PhantomData,
@ -4379,8 +4375,8 @@ impl AnyViewHandle {
}
}
pub fn downcast_ref<T: View>(&self) -> Option<&ViewHandle<T>> {
if self.is::<T>() {
pub fn downcast_ref<V: 'static>(&self) -> Option<&ViewHandle<V>> {
if self.is::<V>() {
Some(unsafe { mem::transmute(self) })
} else {
None
@ -4579,7 +4575,7 @@ impl<T> WeakHandle for WeakViewHandle<T> {
}
}
impl<V: View> WeakViewHandle<V> {
impl<V: 'static> WeakViewHandle<V> {
fn new(window: AnyWindowHandle, view_id: usize) -> Self {
Self {
any_handle: AnyWeakViewHandle {
@ -4619,7 +4615,7 @@ impl<V: View> WeakViewHandle<V> {
cx.read(|cx| {
let handle = cx
.upgrade_view_handle(self)
.ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
.ok_or_else(|| anyhow!("view was dropped"))?;
cx.read_window(self.window, |cx| handle.read_with(cx, read))
.ok_or_else(|| anyhow!("window was removed"))
})
@ -4633,14 +4629,14 @@ impl<V: View> WeakViewHandle<V> {
cx.update(|cx| {
let handle = cx
.upgrade_view_handle(self)
.ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
.ok_or_else(|| anyhow!("view was dropped"))?;
cx.update_window(self.window, |cx| handle.update(cx, update))
.ok_or_else(|| anyhow!("window was removed"))
})
}
}
impl<T> Deref for WeakViewHandle<T> {
impl<V> Deref for WeakViewHandle<V> {
type Target = AnyWeakViewHandle;
fn deref(&self) -> &Self::Target {
@ -4648,7 +4644,7 @@ impl<T> Deref for WeakViewHandle<T> {
}
}
impl<T> Clone for WeakViewHandle<T> {
impl<V> Clone for WeakViewHandle<V> {
fn clone(&self) -> Self {
Self {
any_handle: self.any_handle.clone(),