Checkpoint: Reproduction with Avatar story
This commit is contained in:
+35
-11
@@ -5,6 +5,7 @@ mod model_context;
|
||||
mod test_context;
|
||||
|
||||
pub use async_context::*;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
pub use entity_map::*;
|
||||
pub use model_context::*;
|
||||
use refineable::Refineable;
|
||||
@@ -27,7 +28,7 @@ use parking_lot::Mutex;
|
||||
use slotmap::SlotMap;
|
||||
use std::{
|
||||
any::{type_name, Any, TypeId},
|
||||
cell::RefCell,
|
||||
cell::{Ref, RefCell, RefMut},
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
ops::{Deref, DerefMut},
|
||||
@@ -38,7 +39,29 @@ use std::{
|
||||
};
|
||||
use util::http::{self, HttpClient};
|
||||
|
||||
pub struct App(Rc<RefCell<AppContext>>);
|
||||
pub struct AppCell {
|
||||
app: RefCell<AppContext>,
|
||||
}
|
||||
impl AppCell {
|
||||
pub fn borrow(&self) -> AppRef {
|
||||
AppRef(self.app.borrow())
|
||||
}
|
||||
|
||||
pub fn borrow_mut(&self, label: &str) -> AppRefMut {
|
||||
let thread_id = std::thread::current().id();
|
||||
|
||||
eprintln!(">>> borrowing {thread_id:?}: {label}");
|
||||
AppRefMut(self.app.borrow_mut())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deref, DerefMut)]
|
||||
pub struct AppRef<'a>(Ref<'a, AppContext>);
|
||||
|
||||
#[derive(Deref, DerefMut)]
|
||||
pub struct AppRefMut<'a>(RefMut<'a, AppContext>);
|
||||
|
||||
pub struct App(Rc<AppCell>);
|
||||
|
||||
/// Represents an application before it is fully launched. Once your app is
|
||||
/// configured, you'll start the app with `App::run`.
|
||||
@@ -61,7 +84,8 @@ impl App {
|
||||
let this = self.0.clone();
|
||||
let platform = self.0.borrow().platform.clone();
|
||||
platform.run(Box::new(move || {
|
||||
let cx = &mut *this.borrow_mut();
|
||||
dbg!("run callback");
|
||||
let cx = &mut *this.borrow_mut("app::borrow_mut");
|
||||
on_finish_launching(cx);
|
||||
}));
|
||||
}
|
||||
@@ -75,7 +99,7 @@ impl App {
|
||||
let this = Rc::downgrade(&self.0);
|
||||
self.0.borrow().platform.on_open_urls(Box::new(move |urls| {
|
||||
if let Some(app) = this.upgrade() {
|
||||
callback(urls, &mut *app.borrow_mut());
|
||||
callback(urls, &mut *app.borrow_mut("app.rs::on_open_urls"));
|
||||
}
|
||||
}));
|
||||
self
|
||||
@@ -86,9 +110,9 @@ impl App {
|
||||
F: 'static + FnMut(&mut AppContext),
|
||||
{
|
||||
let this = Rc::downgrade(&self.0);
|
||||
self.0.borrow_mut().platform.on_reopen(Box::new(move || {
|
||||
self.0.borrow_mut("app.rs::on_reopen").platform.on_reopen(Box::new(move || {
|
||||
if let Some(app) = this.upgrade() {
|
||||
callback(&mut app.borrow_mut());
|
||||
callback(&mut app.borrow_mut("app.rs::on_reopen(callback)"));
|
||||
}
|
||||
}));
|
||||
self
|
||||
@@ -119,7 +143,7 @@ type QuitHandler = Box<dyn FnOnce(&mut AppContext) -> LocalBoxFuture<'static, ()
|
||||
type ReleaseListener = Box<dyn FnOnce(&mut dyn Any, &mut AppContext) + 'static>;
|
||||
|
||||
pub struct AppContext {
|
||||
this: Weak<RefCell<AppContext>>,
|
||||
this: Weak<AppCell>,
|
||||
pub(crate) platform: Rc<dyn Platform>,
|
||||
app_metadata: AppMetadata,
|
||||
text_system: Arc<TextSystem>,
|
||||
@@ -157,7 +181,7 @@ impl AppContext {
|
||||
platform: Rc<dyn Platform>,
|
||||
asset_source: Arc<dyn AssetSource>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
) -> Rc<RefCell<Self>> {
|
||||
) -> Rc<AppCell> {
|
||||
let executor = platform.background_executor();
|
||||
let foreground_executor = platform.foreground_executor();
|
||||
assert!(
|
||||
@@ -174,8 +198,8 @@ impl AppContext {
|
||||
app_version: platform.app_version().ok(),
|
||||
};
|
||||
|
||||
Rc::new_cyclic(|this| {
|
||||
RefCell::new(AppContext {
|
||||
Rc::new_cyclic(|this| AppCell {
|
||||
app: RefCell::new(AppContext {
|
||||
this: this.clone(),
|
||||
text_system,
|
||||
platform,
|
||||
@@ -206,7 +230,7 @@ impl AppContext {
|
||||
layout_id_buffer: Default::default(),
|
||||
propagate_event: true,
|
||||
active_drag: None,
|
||||
})
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use crate::{
|
||||
AnyView, AnyWindowHandle, AppContext, BackgroundExecutor, Context, ForegroundExecutor, Model,
|
||||
ModelContext, Render, Result, Task, View, ViewContext, VisualContext, WindowContext,
|
||||
AnyView, AnyWindowHandle, AppCell, AppContext, BackgroundExecutor, Context, ForegroundExecutor,
|
||||
Model, ModelContext, Render, Result, Task, View, ViewContext, VisualContext, WindowContext,
|
||||
WindowHandle,
|
||||
};
|
||||
use anyhow::{anyhow, Context as _};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use std::{cell::RefCell, future::Future, rc::Weak};
|
||||
use std::{future::Future, rc::Weak};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AsyncAppContext {
|
||||
pub(crate) app: Weak<RefCell<AppContext>>,
|
||||
pub(crate) app: Weak<AppCell>,
|
||||
pub(crate) background_executor: BackgroundExecutor,
|
||||
pub(crate) foreground_executor: ForegroundExecutor,
|
||||
}
|
||||
@@ -28,7 +28,8 @@ impl Context for AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut app = app.borrow_mut();
|
||||
dbg!("BUILD MODEL A");
|
||||
let mut app = app.borrow_mut("gpui2/async_context.rs::build_model");
|
||||
Ok(app.build_model(build_model))
|
||||
}
|
||||
|
||||
@@ -41,7 +42,8 @@ impl Context for AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut app = app.borrow_mut();
|
||||
dbg!("UPDATE MODEL B");
|
||||
let mut app = app.borrow_mut("gpui2/async_context.rs::update_model");
|
||||
Ok(app.update_model(handle, update))
|
||||
}
|
||||
|
||||
@@ -50,7 +52,8 @@ impl Context for AsyncAppContext {
|
||||
F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
|
||||
{
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut lock = app.borrow_mut();
|
||||
dbg!("UPDATE WINDOW C");
|
||||
let mut lock = app.borrow_mut("gpui2/async_context::update_window");
|
||||
lock.update_window(window, f)
|
||||
}
|
||||
}
|
||||
@@ -61,7 +64,8 @@ impl AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.borrow_mut();
|
||||
dbg!("REFRESH");
|
||||
let mut lock = app.borrow_mut("async_context.rs::refresh");
|
||||
lock.refresh();
|
||||
Ok(())
|
||||
}
|
||||
@@ -79,7 +83,7 @@ impl AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.borrow_mut();
|
||||
let mut lock = app.borrow_mut("async_context.rs::update");
|
||||
Ok(f(&mut *lock))
|
||||
}
|
||||
|
||||
@@ -95,7 +99,7 @@ impl AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.borrow_mut();
|
||||
let mut lock = app.borrow_mut("open_window");
|
||||
Ok(lock.open_window(options, build_root_view))
|
||||
}
|
||||
|
||||
@@ -112,7 +116,7 @@ impl AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = app.borrow_mut();
|
||||
let app = app.borrow_mut("has_global");
|
||||
Ok(app.has_global::<G>())
|
||||
}
|
||||
|
||||
@@ -121,7 +125,8 @@ impl AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = app.borrow_mut(); // Need this to compile
|
||||
dbg!("read global");
|
||||
let app = app.borrow_mut("async_context.rs::read_global");
|
||||
Ok(read(app.global(), &app))
|
||||
}
|
||||
|
||||
@@ -130,7 +135,8 @@ impl AsyncAppContext {
|
||||
read: impl FnOnce(&G, &AppContext) -> R,
|
||||
) -> Option<R> {
|
||||
let app = self.app.upgrade()?;
|
||||
let app = app.borrow_mut();
|
||||
dbg!("try read global");
|
||||
let app = app.borrow_mut("async_context.rs::try_read_global");
|
||||
Some(read(app.try_global()?, &app))
|
||||
}
|
||||
|
||||
@@ -142,7 +148,8 @@ impl AsyncAppContext {
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut app = app.borrow_mut();
|
||||
dbg!("update global");
|
||||
let mut app = app.borrow_mut("async_context.rs::update_global");
|
||||
Ok(app.update_global(update))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use crate::{
|
||||
AnyView, AnyWindowHandle, AppContext, AsyncAppContext, BackgroundExecutor, Context,
|
||||
EventEmitter, ForegroundExecutor, Model, ModelContext, Result, Task, TestDispatcher,
|
||||
TestPlatform, WindowContext,
|
||||
TestPlatform, WindowContext, AppCell,
|
||||
};
|
||||
use anyhow::{anyhow, bail};
|
||||
use futures::{Stream, StreamExt};
|
||||
use std::{cell::RefCell, future::Future, rc::Rc, sync::Arc, time::Duration};
|
||||
use std::{future::Future, rc::Rc, sync::Arc, time::Duration};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TestAppContext {
|
||||
pub app: Rc<RefCell<AppContext>>,
|
||||
pub app: Rc<AppCell>,
|
||||
pub background_executor: BackgroundExecutor,
|
||||
pub foreground_executor: ForegroundExecutor,
|
||||
}
|
||||
@@ -24,7 +24,7 @@ impl Context for TestAppContext {
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
let mut app = self.app.borrow_mut();
|
||||
let mut app = self.app.borrow_mut("test_context.rs::build_model");
|
||||
app.build_model(build_model)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ impl Context for TestAppContext {
|
||||
handle: &Model<T>,
|
||||
update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
|
||||
) -> Self::Result<R> {
|
||||
let mut app = self.app.borrow_mut();
|
||||
let mut app = self.app.borrow_mut("test_context::update_model");
|
||||
app.update_model(handle, update)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ impl Context for TestAppContext {
|
||||
where
|
||||
F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
|
||||
{
|
||||
let mut lock = self.app.borrow_mut();
|
||||
let mut lock = self.app.borrow_mut("test_context::update_window");
|
||||
lock.update_window(window, f)
|
||||
}
|
||||
}
|
||||
@@ -65,11 +65,11 @@ impl TestAppContext {
|
||||
}
|
||||
|
||||
pub fn quit(&self) {
|
||||
self.app.borrow_mut().quit();
|
||||
self.app.borrow_mut("test_context.rs::quit").quit();
|
||||
}
|
||||
|
||||
pub fn refresh(&mut self) -> Result<()> {
|
||||
let mut app = self.app.borrow_mut();
|
||||
let mut app = self.app.borrow_mut("test_context.rs::refresh");
|
||||
app.refresh();
|
||||
Ok(())
|
||||
}
|
||||
@@ -83,7 +83,7 @@ impl TestAppContext {
|
||||
}
|
||||
|
||||
pub fn update<R>(&self, f: impl FnOnce(&mut AppContext) -> R) -> R {
|
||||
let mut cx = self.app.borrow_mut();
|
||||
let mut cx = self.app.borrow_mut("test_context::update");
|
||||
cx.update(f)
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ impl TestAppContext {
|
||||
&mut self,
|
||||
update: impl FnOnce(&mut G, &mut AppContext) -> R,
|
||||
) -> R {
|
||||
let mut lock = self.app.borrow_mut();
|
||||
let mut lock = self.app.borrow_mut("test_context.rs::update_global");
|
||||
lock.update_global(update)
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,9 @@ where
|
||||
let corner_radii = style.corner_radii;
|
||||
|
||||
if let Some(uri) = self.uri.clone() {
|
||||
let image_future = cx.image_cache.get(uri);
|
||||
// eprintln!(">>> image_cache.get({uri}");
|
||||
let image_future = cx.image_cache.get(uri.clone());
|
||||
// eprintln!("<<< image_cache.get({uri}");
|
||||
if let Some(data) = image_future
|
||||
.clone()
|
||||
.now_or_never()
|
||||
@@ -123,7 +125,9 @@ where
|
||||
} else {
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
if image_future.await.log_err().is_some() {
|
||||
eprintln!(">>> on_next_frame");
|
||||
cx.on_next_frame(|cx| cx.notify());
|
||||
eprintln!("<<< on_next_frame")
|
||||
}
|
||||
})
|
||||
.detach()
|
||||
|
||||
@@ -42,6 +42,7 @@ impl PlatformDispatcher for MacDispatcher {
|
||||
}
|
||||
|
||||
fn dispatch(&self, runnable: Runnable) {
|
||||
println!("DISPATCH");
|
||||
unsafe {
|
||||
dispatch_async_f(
|
||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.try_into().unwrap(), 0),
|
||||
@@ -52,6 +53,7 @@ impl PlatformDispatcher for MacDispatcher {
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: Runnable) {
|
||||
println!("DISPATCH ON MAIN THREAD");
|
||||
unsafe {
|
||||
dispatch_async_f(
|
||||
dispatch_get_main_queue(),
|
||||
|
||||
@@ -58,11 +58,23 @@ mod stories {
|
||||
.child(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1714999?v=4",
|
||||
))
|
||||
.child(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/326587?v=4",
|
||||
))
|
||||
// .child(Avatar::new(
|
||||
// "https://avatars.githubusercontent.com/u/482957?v=4",
|
||||
// ))
|
||||
// .child(Avatar::new(
|
||||
// "https://avatars.githubusercontent.com/u/1714999?v=4",
|
||||
// ))
|
||||
// .child(Avatar::new(
|
||||
// "https://avatars.githubusercontent.com/u/1486634?v=4",
|
||||
// ))
|
||||
.child(Story::label(cx, "Rounded rectangle"))
|
||||
.child(
|
||||
Avatar::new("https://avatars.githubusercontent.com/u/1714999?v=4")
|
||||
.shape(Shape::RoundedRectangle),
|
||||
)
|
||||
// .child(
|
||||
// Avatar::new("https://avatars.githubusercontent.com/u/1714999?v=4")
|
||||
// .shape(Shape::RoundedRectangle),
|
||||
// )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,11 +139,11 @@ impl Player {
|
||||
}
|
||||
|
||||
pub fn cursor_color<V: 'static>(&self, cx: &mut ViewContext<V>) -> Hsla {
|
||||
cx.theme().styles.player.0[self.index].cursor
|
||||
cx.theme().styles.player.0[self.index % cx.theme().styles.player.0.len()].cursor
|
||||
}
|
||||
|
||||
pub fn selection_color<V: 'static>(&self, cx: &mut ViewContext<V>) -> Hsla {
|
||||
cx.theme().styles.player.0[self.index].selection
|
||||
cx.theme().styles.player.0[self.index % cx.theme().styles.player.0.len()].selection
|
||||
}
|
||||
|
||||
pub fn avatar_src(&self) -> &str {
|
||||
|
||||
Reference in New Issue
Block a user