Start removing the Send impl for App
Co-authored-by: Antonio <antonio@zed.dev> Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
committed by
Nathan Sobo
co-authored by
Antonio
Nathan
parent
ea7fdef417
commit
57ffa8201e
@@ -1,9 +1,9 @@
|
||||
use super::BoolExt;
|
||||
use crate::{
|
||||
AnyWindowHandle, ClipboardItem, CursorStyle, DisplayId, Executor, InputEvent, MacDispatcher,
|
||||
MacDisplay, MacDisplayLinker, MacTextSystem, MacWindow, PathPromptOptions, Platform,
|
||||
PlatformDisplay, PlatformTextSystem, PlatformWindow, Result, SemanticVersion, VideoTimestamp,
|
||||
WindowOptions,
|
||||
AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId, ForegroundExecutor,
|
||||
InputEvent, MacDispatcher, MacDisplay, MacDisplayLinker, MacTextSystem, MacWindow,
|
||||
PathPromptOptions, Platform, PlatformDisplay, PlatformTextSystem, PlatformWindow, Result,
|
||||
SemanticVersion, VideoTimestamp, WindowOptions,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use block::ConcreteBlock;
|
||||
@@ -143,7 +143,8 @@ unsafe fn build_classes() {
|
||||
pub struct MacPlatform(Mutex<MacPlatformState>);
|
||||
|
||||
pub struct MacPlatformState {
|
||||
executor: Executor,
|
||||
background_executor: BackgroundExecutor,
|
||||
foreground_executor: ForegroundExecutor,
|
||||
text_system: Arc<MacTextSystem>,
|
||||
display_linker: MacDisplayLinker,
|
||||
pasteboard: id,
|
||||
@@ -164,8 +165,10 @@ pub struct MacPlatformState {
|
||||
|
||||
impl MacPlatform {
|
||||
pub fn new() -> Self {
|
||||
let dispatcher = Arc::new(MacDispatcher);
|
||||
Self(Mutex::new(MacPlatformState {
|
||||
executor: Executor::new(Arc::new(MacDispatcher)),
|
||||
background_executor: BackgroundExecutor::new(dispatcher.clone()),
|
||||
foreground_executor: ForegroundExecutor::new(dispatcher.clone()),
|
||||
text_system: Arc::new(MacTextSystem::new()),
|
||||
display_linker: MacDisplayLinker::new(),
|
||||
pasteboard: unsafe { NSPasteboard::generalPasteboard(nil) },
|
||||
@@ -345,8 +348,12 @@ impl MacPlatform {
|
||||
}
|
||||
|
||||
impl Platform for MacPlatform {
|
||||
fn executor(&self) -> Executor {
|
||||
self.0.lock().executor.clone()
|
||||
fn background_executor(&self) -> BackgroundExecutor {
|
||||
self.0.lock().background_executor.clone()
|
||||
}
|
||||
|
||||
fn foreground_executor(&self) -> crate::ForegroundExecutor {
|
||||
self.0.lock().foreground_executor.clone()
|
||||
}
|
||||
|
||||
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
||||
@@ -457,6 +464,10 @@ impl Platform for MacPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
// fn add_status_item(&self, _handle: AnyWindowHandle) -> Box<dyn platform::Window> {
|
||||
// Box::new(StatusItem::add(self.fonts()))
|
||||
// }
|
||||
|
||||
fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>> {
|
||||
MacDisplay::all()
|
||||
.into_iter()
|
||||
@@ -464,10 +475,6 @@ impl Platform for MacPlatform {
|
||||
.collect()
|
||||
}
|
||||
|
||||
// fn add_status_item(&self, _handle: AnyWindowHandle) -> Box<dyn platform::Window> {
|
||||
// Box::new(StatusItem::add(self.fonts()))
|
||||
// }
|
||||
|
||||
fn display(&self, id: DisplayId) -> Option<Rc<dyn PlatformDisplay>> {
|
||||
MacDisplay::find_by_id(id).map(|screen| Rc::new(screen) as Rc<_>)
|
||||
}
|
||||
@@ -481,7 +488,7 @@ impl Platform for MacPlatform {
|
||||
handle: AnyWindowHandle,
|
||||
options: WindowOptions,
|
||||
) -> Box<dyn PlatformWindow> {
|
||||
Box::new(MacWindow::open(handle, options, self.executor()))
|
||||
Box::new(MacWindow::open(handle, options, self.foreground_executor()))
|
||||
}
|
||||
|
||||
fn set_display_link_output_callback(
|
||||
@@ -589,8 +596,8 @@ impl Platform for MacPlatform {
|
||||
let path = path.to_path_buf();
|
||||
self.0
|
||||
.lock()
|
||||
.executor
|
||||
.spawn_on_main_local(async move {
|
||||
.background_executor
|
||||
.spawn(async move {
|
||||
let full_path = ns_string(path.to_str().unwrap_or(""));
|
||||
let root_full_path = ns_string("");
|
||||
let workspace: id = msg_send![class!(NSWorkspace), sharedWorkspace];
|
||||
@@ -674,23 +681,6 @@ impl Platform for MacPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
if url.is_null() {
|
||||
Err(anyhow!("resource not found"))
|
||||
} else {
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn on_menu_command(&self, callback: Box<dyn FnMut(&dyn Action)>) {
|
||||
// self.0.lock().menu_command = Some(callback);
|
||||
// }
|
||||
@@ -717,6 +707,23 @@ impl Platform for MacPlatform {
|
||||
// }
|
||||
// }
|
||||
|
||||
fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
if url.is_null() {
|
||||
Err(anyhow!("resource not found"))
|
||||
} else {
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_cursor_style(&self, style: CursorStyle) {
|
||||
unsafe {
|
||||
let new_cursor: id = match style {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::{display_bounds_from_native, ns_string, MacDisplay, MetalRenderer, NSRange};
|
||||
use crate::{
|
||||
display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, Executor, ExternalPaths,
|
||||
FileDropEvent, GlobalPixels, InputEvent, KeyDownEvent, Keystroke, Modifiers,
|
||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
|
||||
PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, Scene, Size,
|
||||
Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions, WindowPromptLevel,
|
||||
display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, ExternalPaths,
|
||||
FileDropEvent, ForegroundExecutor, GlobalPixels, InputEvent, KeyDownEvent, Keystroke,
|
||||
Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
|
||||
Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, Scene,
|
||||
Size, Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions, WindowPromptLevel,
|
||||
};
|
||||
use block::ConcreteBlock;
|
||||
use cocoa::{
|
||||
@@ -315,7 +315,7 @@ struct InsertText {
|
||||
|
||||
struct MacWindowState {
|
||||
handle: AnyWindowHandle,
|
||||
executor: Executor,
|
||||
executor: ForegroundExecutor,
|
||||
native_window: id,
|
||||
renderer: MetalRenderer,
|
||||
scene_to_render: Option<Scene>,
|
||||
@@ -451,7 +451,11 @@ unsafe impl Send for MacWindowState {}
|
||||
pub struct MacWindow(Arc<Mutex<MacWindowState>>);
|
||||
|
||||
impl MacWindow {
|
||||
pub fn open(handle: AnyWindowHandle, options: WindowOptions, executor: Executor) -> Self {
|
||||
pub fn open(
|
||||
handle: AnyWindowHandle,
|
||||
options: WindowOptions,
|
||||
executor: ForegroundExecutor,
|
||||
) -> Self {
|
||||
unsafe {
|
||||
let pool = NSAutoreleasePool::new(nil);
|
||||
|
||||
@@ -674,13 +678,10 @@ impl MacWindow {
|
||||
|
||||
impl Drop for MacWindow {
|
||||
fn drop(&mut self) {
|
||||
let this = self.0.clone();
|
||||
let executor = self.0.lock().executor.clone();
|
||||
executor
|
||||
.run_on_main(move || unsafe {
|
||||
this.lock().native_window.close();
|
||||
})
|
||||
.detach();
|
||||
let native_window = self.0.lock().native_window;
|
||||
unsafe {
|
||||
native_window.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,7 +808,7 @@ impl PlatformWindow for MacWindow {
|
||||
let native_window = self.0.lock().native_window;
|
||||
let executor = self.0.lock().executor.clone();
|
||||
executor
|
||||
.spawn_on_main_local(async move {
|
||||
.spawn(async move {
|
||||
let _: () = msg_send![
|
||||
alert,
|
||||
beginSheetModalForWindow: native_window
|
||||
@@ -824,7 +825,7 @@ impl PlatformWindow for MacWindow {
|
||||
let window = self.0.lock().native_window;
|
||||
let executor = self.0.lock().executor.clone();
|
||||
executor
|
||||
.spawn_on_main_local(async move {
|
||||
.spawn(async move {
|
||||
unsafe {
|
||||
let _: () = msg_send![window, makeKeyAndOrderFront: nil];
|
||||
}
|
||||
@@ -872,25 +873,17 @@ impl PlatformWindow for MacWindow {
|
||||
fn zoom(&self) {
|
||||
let this = self.0.lock();
|
||||
let window = this.native_window;
|
||||
this.executor
|
||||
.spawn_on_main_local(async move {
|
||||
unsafe {
|
||||
window.zoom_(nil);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
unsafe {
|
||||
window.zoom_(nil);
|
||||
}
|
||||
}
|
||||
|
||||
fn toggle_full_screen(&self) {
|
||||
let this = self.0.lock();
|
||||
let window = this.native_window;
|
||||
this.executor
|
||||
.spawn_on_main_local(async move {
|
||||
unsafe {
|
||||
window.toggleFullScreen_(nil);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
unsafe {
|
||||
window.toggleFullScreen_(nil);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_input(&self, callback: Box<dyn FnMut(InputEvent) -> bool>) {
|
||||
@@ -1189,7 +1182,7 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
||||
lock.synthetic_drag_counter += 1;
|
||||
let executor = lock.executor.clone();
|
||||
executor
|
||||
.spawn_on_main_local(synthetic_drag(
|
||||
.spawn(synthetic_drag(
|
||||
weak_window_state,
|
||||
lock.synthetic_drag_counter,
|
||||
event.clone(),
|
||||
@@ -1317,7 +1310,7 @@ extern "C" fn window_did_change_key_status(this: &Object, selector: Sel, _: id)
|
||||
let executor = lock.executor.clone();
|
||||
drop(lock);
|
||||
executor
|
||||
.spawn_on_main_local(async move {
|
||||
.spawn(async move {
|
||||
let mut lock = window_state.as_ref().lock();
|
||||
if let Some(mut callback) = lock.activate_callback.take() {
|
||||
drop(lock);
|
||||
|
||||
@@ -215,58 +215,3 @@ impl PlatformDispatcher for TestDispatcher {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::Executor;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
fn test_dispatch() {
|
||||
let dispatcher = TestDispatcher::new(StdRng::seed_from_u64(0));
|
||||
let executor = Executor::new(Arc::new(dispatcher));
|
||||
|
||||
let result = executor.block(async { executor.run_on_main(|| 1).await });
|
||||
assert_eq!(result, 1);
|
||||
|
||||
let result = executor.block({
|
||||
let executor = executor.clone();
|
||||
async move {
|
||||
executor
|
||||
.spawn_on_main({
|
||||
let executor = executor.clone();
|
||||
assert!(executor.is_main_thread());
|
||||
|| async move {
|
||||
assert!(executor.is_main_thread());
|
||||
let result = executor
|
||||
.spawn({
|
||||
let executor = executor.clone();
|
||||
async move {
|
||||
assert!(!executor.is_main_thread());
|
||||
|
||||
let result = executor
|
||||
.spawn_on_main({
|
||||
let executor = executor.clone();
|
||||
|| async move {
|
||||
assert!(executor.is_main_thread());
|
||||
2
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
assert!(!executor.is_main_thread());
|
||||
result
|
||||
}
|
||||
})
|
||||
.await;
|
||||
assert!(executor.is_main_thread());
|
||||
result
|
||||
}
|
||||
})
|
||||
.await
|
||||
}
|
||||
});
|
||||
assert_eq!(result, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
use crate::{DisplayId, Executor, Platform, PlatformTextSystem};
|
||||
use crate::{BackgroundExecutor, DisplayId, ForegroundExecutor, Platform, PlatformTextSystem};
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct TestPlatform {
|
||||
executor: Executor,
|
||||
background_executor: BackgroundExecutor,
|
||||
foreground_executor: ForegroundExecutor,
|
||||
}
|
||||
|
||||
impl TestPlatform {
|
||||
pub fn new(executor: Executor) -> Self {
|
||||
TestPlatform { executor }
|
||||
pub fn new(executor: BackgroundExecutor, foreground_executor: ForegroundExecutor) -> Self {
|
||||
TestPlatform {
|
||||
background_executor: executor,
|
||||
foreground_executor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo!("implement out what our tests needed in GPUI 1")
|
||||
impl Platform for TestPlatform {
|
||||
fn executor(&self) -> Executor {
|
||||
self.executor.clone()
|
||||
fn background_executor(&self) -> BackgroundExecutor {
|
||||
self.background_executor.clone()
|
||||
}
|
||||
|
||||
fn foreground_executor(&self) -> ForegroundExecutor {
|
||||
self.foreground_executor.clone()
|
||||
}
|
||||
|
||||
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
||||
|
||||
Reference in New Issue
Block a user