WIP
This commit is contained in:
+28
-22
@@ -406,24 +406,6 @@ impl AppContext {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||
where
|
||||
G: 'static + Send + Sync,
|
||||
{
|
||||
let mut global = self
|
||||
.global_stacks_by_type
|
||||
.get_mut(&TypeId::of::<G>())
|
||||
.and_then(|stack| stack.pop())
|
||||
.ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
|
||||
.unwrap();
|
||||
let result = f(global.downcast_mut().unwrap(), self);
|
||||
self.global_stacks_by_type
|
||||
.get_mut(&TypeId::of::<G>())
|
||||
.unwrap()
|
||||
.push(global);
|
||||
result
|
||||
}
|
||||
|
||||
pub fn default_global<G: 'static + Default + Sync + Send>(&mut self) -> &mut G {
|
||||
let stack = self
|
||||
.global_stacks_by_type
|
||||
@@ -448,18 +430,20 @@ impl AppContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn push_global<T: Send + Sync + 'static>(&mut self, state: T) {
|
||||
pub(crate) fn push_global<T: Send + Sync + 'static>(&mut self, global: T) {
|
||||
self.global_stacks_by_type
|
||||
.entry(TypeId::of::<T>())
|
||||
.or_default()
|
||||
.push(Box::new(state));
|
||||
.push(Box::new(global));
|
||||
}
|
||||
|
||||
pub(crate) fn pop_global<T: 'static>(&mut self) {
|
||||
pub(crate) fn pop_global<T: 'static>(&mut self) -> Box<T> {
|
||||
self.global_stacks_by_type
|
||||
.get_mut(&TypeId::of::<T>())
|
||||
.and_then(|stack| stack.pop())
|
||||
.expect("state stack underflow");
|
||||
.expect("state stack underflow")
|
||||
.downcast()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn push_text_style(&mut self, text_style: TextStyleRefinement) {
|
||||
@@ -497,6 +481,10 @@ impl Context for AppContext {
|
||||
type EntityContext<'a, 'w, T: Send + Sync + 'static> = ModelContext<'a, T>;
|
||||
type Result<T> = T;
|
||||
|
||||
fn refresh(&mut self) {
|
||||
self.push_effect(Effect::Refresh);
|
||||
}
|
||||
|
||||
fn entity<T: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||
@@ -524,6 +512,24 @@ impl Context for AppContext {
|
||||
fn read_global<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
|
||||
read(self.global(), self)
|
||||
}
|
||||
|
||||
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||
where
|
||||
G: 'static + Send + Sync,
|
||||
{
|
||||
let mut global = self
|
||||
.global_stacks_by_type
|
||||
.get_mut(&TypeId::of::<G>())
|
||||
.and_then(|stack| stack.pop())
|
||||
.ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
|
||||
.unwrap();
|
||||
let result = f(global.downcast_mut().unwrap(), self);
|
||||
self.global_stacks_by_type
|
||||
.get_mut(&TypeId::of::<G>())
|
||||
.unwrap()
|
||||
.push(global);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl MainThread<AppContext> {
|
||||
|
||||
@@ -13,6 +13,16 @@ impl Context for AsyncAppContext {
|
||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ModelContext<'a, T>;
|
||||
type Result<T> = Result<T>;
|
||||
|
||||
fn refresh(&mut self) -> Self::Result<()> {
|
||||
let app = self
|
||||
.0
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.lock(); // Need this to compile
|
||||
lock.refresh();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn entity<T: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||
@@ -21,7 +31,7 @@ impl Context for AsyncAppContext {
|
||||
.0
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.lock();
|
||||
let mut lock = app.lock(); // Need this to compile
|
||||
Ok(lock.entity(build_entity))
|
||||
}
|
||||
|
||||
@@ -34,7 +44,7 @@ impl Context for AsyncAppContext {
|
||||
.0
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.lock();
|
||||
let mut lock = app.lock(); // Need this to compile
|
||||
Ok(lock.update_entity(handle, update))
|
||||
}
|
||||
|
||||
@@ -46,9 +56,21 @@ impl Context for AsyncAppContext {
|
||||
.0
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.lock();
|
||||
let lock = app.lock(); // Need this to compile
|
||||
Ok(lock.read_global(read))
|
||||
}
|
||||
|
||||
fn update_global<G: 'static + Send + Sync, R>(
|
||||
&mut self,
|
||||
update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||
) -> Self::Result<R> {
|
||||
let app = self
|
||||
.0
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut lock = app.lock(); // Need this to compile
|
||||
Ok(lock.update_global(update))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncAppContext {
|
||||
@@ -106,6 +128,10 @@ impl Context for AsyncWindowContext {
|
||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
|
||||
type Result<T> = Result<T>;
|
||||
|
||||
fn refresh(&mut self) -> Self::Result<()> {
|
||||
self.app.refresh()
|
||||
}
|
||||
|
||||
fn entity<R: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R,
|
||||
@@ -129,4 +155,12 @@ impl Context for AsyncWindowContext {
|
||||
) -> Result<R> {
|
||||
self.app.read_window(self.window, |cx| cx.read_global(read))
|
||||
}
|
||||
|
||||
fn update_global<G: 'static + Send + Sync, R>(
|
||||
&mut self,
|
||||
update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||
) -> Result<R> {
|
||||
self.app
|
||||
.update_window(self.window, |cx| cx.update_global(update))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,10 @@ impl<'a, T: 'static> Context for ModelContext<'a, T> {
|
||||
type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>;
|
||||
type Result<U> = U;
|
||||
|
||||
fn refresh(&mut self) {
|
||||
self.app.refresh();
|
||||
}
|
||||
|
||||
fn entity<U: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
|
||||
@@ -157,4 +161,14 @@ impl<'a, T: 'static> Context for ModelContext<'a, T> {
|
||||
) -> R {
|
||||
read(self.app.global(), self)
|
||||
}
|
||||
|
||||
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||
where
|
||||
G: 'static + Send + Sync,
|
||||
{
|
||||
let mut global = self.app.pop_global::<G>();
|
||||
let result = f(global.as_mut(), self);
|
||||
self.app.push_global(global);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,11 @@ impl Executor {
|
||||
Task::Spawned(task)
|
||||
}
|
||||
|
||||
pub fn block<R>(&self, future: impl Future<Output = R>) -> R {
|
||||
// todo!("integrate with deterministic dispatcher")
|
||||
futures::executor::block_on(future)
|
||||
}
|
||||
|
||||
pub fn is_main_thread(&self) -> bool {
|
||||
self.dispatcher.is_main_thread()
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ pub trait Context {
|
||||
type EntityContext<'a, 'w, T: 'static + Send + Sync>;
|
||||
type Result<T>;
|
||||
|
||||
fn refresh(&mut self) -> Self::Result<()>;
|
||||
|
||||
fn entity<T: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||
@@ -85,6 +87,13 @@ pub trait Context {
|
||||
&self,
|
||||
read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
|
||||
) -> Self::Result<R>;
|
||||
|
||||
fn update_global<G, R>(
|
||||
&mut self,
|
||||
f: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||
) -> Self::Result<R>
|
||||
where
|
||||
G: 'static + Send + Sync;
|
||||
}
|
||||
|
||||
pub enum GlobalKey {
|
||||
@@ -115,6 +124,10 @@ impl<C: Context> Context for MainThread<C> {
|
||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>;
|
||||
type Result<T> = C::Result<T>;
|
||||
|
||||
fn refresh(&mut self) -> Self::Result<()> {
|
||||
self.0.refresh()
|
||||
}
|
||||
|
||||
fn entity<T: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||
@@ -160,6 +173,21 @@ impl<C: Context> Context for MainThread<C> {
|
||||
read(global, cx)
|
||||
})
|
||||
}
|
||||
|
||||
fn update_global<G: 'static + Send + Sync, R>(
|
||||
&mut self,
|
||||
update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||
) -> Self::Result<R> {
|
||||
self.0.update_global(|global, cx| {
|
||||
let cx = unsafe {
|
||||
mem::transmute::<
|
||||
&mut C::BorrowedContext<'_, '_>,
|
||||
&mut MainThread<C::BorrowedContext<'_, '_>>,
|
||||
>(cx)
|
||||
};
|
||||
update(global, cx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub trait BorrowAppContext {
|
||||
|
||||
@@ -1060,6 +1060,10 @@ impl Context for WindowContext<'_, '_> {
|
||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
|
||||
type Result<T> = T;
|
||||
|
||||
fn refresh(&mut self) {
|
||||
self.app.refresh();
|
||||
}
|
||||
|
||||
fn entity<T: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||
@@ -1090,6 +1094,16 @@ impl Context for WindowContext<'_, '_> {
|
||||
fn read_global<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
|
||||
read(self.app.global(), self)
|
||||
}
|
||||
|
||||
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||
where
|
||||
G: 'static + Send + Sync,
|
||||
{
|
||||
let mut global = self.app.pop_global::<G>();
|
||||
let result = f(global.as_mut(), self);
|
||||
self.app.push_global(global);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
|
||||
@@ -1540,6 +1554,10 @@ where
|
||||
type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
|
||||
type Result<U> = U;
|
||||
|
||||
fn refresh(&mut self) {
|
||||
self.app.refresh();
|
||||
}
|
||||
|
||||
fn entity<T2: Send + Sync + 'static>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
|
||||
@@ -1561,6 +1579,16 @@ where
|
||||
) -> R {
|
||||
read(self.global(), self)
|
||||
}
|
||||
|
||||
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||
where
|
||||
G: 'static + Send + Sync,
|
||||
{
|
||||
let mut global = self.app.pop_global::<G>();
|
||||
let result = f(global.as_mut(), self);
|
||||
self.app.push_global(global);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
|
||||
|
||||
Reference in New Issue
Block a user