@@ -39,72 +39,11 @@ pub struct App(Arc<Mutex<AppContext>>);
impl App {
pub fn production(asset_source: Arc<dyn AssetSource>) -> Self {
- let http_client = http::client();
- Self::new(current_platform(), asset_source, http_client)
- }
-
- #[cfg(any(test, feature = "test-support"))]
- pub fn test(seed: u64) -> Self {
- let platform = Arc::new(crate::TestPlatform::new(seed));
- let asset_source = Arc::new(());
- let http_client = util::http::FakeHttpClient::with_404_response();
- Self::new(platform, asset_source, http_client)
- }
-
- fn new(
- platform: Arc<dyn Platform>,
- asset_source: Arc<dyn AssetSource>,
- http_client: Arc<dyn HttpClient>,
- ) -> Self {
- let executor = platform.executor();
- assert!(
- executor.is_main_thread(),
- "must construct App on main thread"
- );
-
- let text_system = Arc::new(TextSystem::new(platform.text_system()));
- let mut entities = EntityMap::new();
- let unit_entity = entities.insert(entities.reserve(), ());
- let app_metadata = AppMetadata {
- os_name: platform.os_name(),
- os_version: platform.os_version().ok(),
- app_version: platform.app_version().ok(),
- };
-
- Self(Arc::new_cyclic(|this| {
- Mutex::new(AppContext {
- this: this.clone(),
- text_system,
- platform: MainThreadOnly::new(platform, executor.clone()),
- app_metadata,
- flushing_effects: false,
- pending_updates: 0,
- next_frame_callbacks: Default::default(),
- executor,
- svg_renderer: SvgRenderer::new(asset_source.clone()),
- asset_source,
- image_cache: ImageCache::new(http_client),
- text_style_stack: Vec::new(),
- globals_by_type: HashMap::default(),
- unit_entity,
- entities,
- windows: SlotMap::with_key(),
- keymap: Arc::new(RwLock::new(Keymap::default())),
- global_action_listeners: HashMap::default(),
- action_builders: HashMap::default(),
- pending_effects: VecDeque::new(),
- pending_notifications: HashSet::default(),
- pending_global_notifications: HashSet::default(),
- observers: SubscriberSet::new(),
- event_listeners: SubscriberSet::new(),
- release_listeners: SubscriberSet::new(),
- global_observers: SubscriberSet::new(),
- quit_observers: SubscriberSet::new(),
- layout_id_buffer: Default::default(),
- propagate_event: true,
- active_drag: None,
- })
- }))
+ Self(AppContext::new(
+ current_platform(),
+ asset_source,
+ http::client(),
+ ))
}
pub fn run<F>(self, on_finish_launching: F)
@@ -210,6 +149,62 @@ pub struct AppContext {
}
impl AppContext {
+ pub(crate) fn new(
+ platform: Arc<dyn Platform>,
+ asset_source: Arc<dyn AssetSource>,
+ http_client: Arc<dyn HttpClient>,
+ ) -> Arc<Mutex<Self>> {
+ let executor = platform.executor();
+ assert!(
+ executor.is_main_thread(),
+ "must construct App on main thread"
+ );
+
+ let text_system = Arc::new(TextSystem::new(platform.text_system()));
+ let mut entities = EntityMap::new();
+ let unit_entity = entities.insert(entities.reserve(), ());
+ let app_metadata = AppMetadata {
+ os_name: platform.os_name(),
+ os_version: platform.os_version().ok(),
+ app_version: platform.app_version().ok(),
+ };
+
+ Arc::new_cyclic(|this| {
+ Mutex::new(AppContext {
+ this: this.clone(),
+ text_system,
+ platform: MainThreadOnly::new(platform, executor.clone()),
+ app_metadata,
+ flushing_effects: false,
+ pending_updates: 0,
+ next_frame_callbacks: Default::default(),
+ executor,
+ svg_renderer: SvgRenderer::new(asset_source.clone()),
+ asset_source,
+ image_cache: ImageCache::new(http_client),
+ text_style_stack: Vec::new(),
+ globals_by_type: HashMap::default(),
+ unit_entity,
+ entities,
+ windows: SlotMap::with_key(),
+ keymap: Arc::new(RwLock::new(Keymap::default())),
+ global_action_listeners: HashMap::default(),
+ action_builders: HashMap::default(),
+ pending_effects: VecDeque::new(),
+ pending_notifications: HashSet::default(),
+ pending_global_notifications: HashSet::default(),
+ observers: SubscriberSet::new(),
+ event_listeners: SubscriberSet::new(),
+ release_listeners: SubscriberSet::new(),
+ global_observers: SubscriberSet::new(),
+ quit_observers: SubscriberSet::new(),
+ layout_id_buffer: Default::default(),
+ propagate_event: true,
+ active_drag: None,
+ })
+ })
+ }
+
pub fn quit(&mut self) {
let mut futures = Vec::new();
@@ -1,6 +1,6 @@
use crate::{
AnyWindowHandle, AppContext, AsyncAppContext, Context, Executor, Handle, MainThread,
- ModelContext, Result, Task, WindowContext,
+ ModelContext, Result, Task, TestDispatcher, TestPlatform, WindowContext,
};
use parking_lot::Mutex;
use std::{any::Any, future::Future, sync::Arc};
@@ -37,6 +37,17 @@ impl Context for TestAppContext {
}
impl TestAppContext {
+ pub fn new(dispatcher: TestDispatcher) -> Self {
+ let executor = Executor::new(Arc::new(dispatcher));
+ let platform = Arc::new(TestPlatform::new(executor.clone()));
+ let asset_source = Arc::new(());
+ let http_client = util::http::FakeHttpClient::with_404_response();
+ Self {
+ app: AppContext::new(platform, asset_source, http_client),
+ executor,
+ }
+ }
+
pub fn refresh(&mut self) -> Result<()> {
let mut lock = self.app.lock();
lock.refresh();
@@ -47,27 +58,27 @@ impl TestAppContext {
&self.executor
}
- pub fn update<R>(&self, f: impl FnOnce(&mut AppContext) -> R) -> Result<R> {
+ pub fn update<R>(&self, f: impl FnOnce(&mut AppContext) -> R) -> R {
let mut lock = self.app.lock();
- Ok(f(&mut *lock))
+ f(&mut *lock)
}
pub fn read_window<R>(
&self,
handle: AnyWindowHandle,
- update: impl FnOnce(&WindowContext) -> R,
- ) -> Result<R> {
+ read: impl FnOnce(&WindowContext) -> R,
+ ) -> R {
let mut app_context = self.app.lock();
- app_context.read_window(handle.id, update)
+ app_context.read_window(handle.id, read).unwrap()
}
pub fn update_window<R>(
&self,
handle: AnyWindowHandle,
update: impl FnOnce(&mut WindowContext) -> R,
- ) -> Result<R> {
+ ) -> R {
let mut app = self.app.lock();
- app.update_window(handle.id, update)
+ app.update_window(handle.id, update).unwrap()
}
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut + Send + 'static) -> Task<R>
@@ -94,22 +105,22 @@ impl TestAppContext {
pub fn run_on_main<R>(
&self,
f: impl FnOnce(&mut MainThread<AppContext>) -> R + Send + 'static,
- ) -> Result<Task<R>>
+ ) -> Task<R>
where
R: Send + 'static,
{
let mut app_context = self.app.lock();
- Ok(app_context.run_on_main(f))
+ app_context.run_on_main(f)
}
- pub fn has_global<G: 'static>(&self) -> Result<bool> {
+ pub fn has_global<G: 'static>(&self) -> bool {
let lock = self.app.lock();
- Ok(lock.has_global::<G>())
+ lock.has_global::<G>()
}
- pub fn read_global<G: 'static, R>(&self, read: impl FnOnce(&G, &AppContext) -> R) -> Result<R> {
+ pub fn read_global<G: 'static, R>(&self, read: impl FnOnce(&G, &AppContext) -> R) -> R {
let lock = self.app.lock();
- Ok(read(lock.global(), &lock))
+ read(lock.global(), &lock)
}
pub fn try_read_global<G: 'static, R>(
@@ -123,9 +134,9 @@ impl TestAppContext {
pub fn update_global<G: 'static, R>(
&mut self,
update: impl FnOnce(&mut G, &mut AppContext) -> R,
- ) -> Result<R> {
+ ) -> R {
let mut lock = self.app.lock();
- Ok(lock.update_global(update))
+ lock.update_global(update)
}
fn to_async(&self) -> AsyncAppContext {
@@ -1,5 +1,4 @@
-use crate::{DisplayId, Executor, Platform, PlatformTextSystem, TestDispatcher};
-use rand::prelude::*;
+use crate::{DisplayId, Executor, Platform, PlatformTextSystem};
use std::sync::Arc;
pub struct TestPlatform {
@@ -7,11 +6,8 @@ pub struct TestPlatform {
}
impl TestPlatform {
- pub fn new(seed: u64) -> Self {
- let rng = StdRng::seed_from_u64(seed);
- TestPlatform {
- executor: Executor::new(Arc::new(TestDispatcher::new(rng))),
- }
+ pub fn new(executor: Executor) -> Self {
+ TestPlatform { executor }
}
}