Merge branch 'zed2' of github.com:zed-industries/zed into zed2

This commit is contained in:
Marshall Bowers 2023-10-25 17:38:52 +02:00
commit 08a4e53cfe
10 changed files with 372 additions and 198 deletions

View File

@ -39,9 +39,9 @@ impl App {
Self::new(current_platform(), asset_source, http_client)
}
#[cfg(any(test, feature = "test"))]
pub fn test() -> Self {
let platform = Arc::new(super::TestPlatform::new());
#[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)

View File

@ -145,8 +145,10 @@ impl Executor {
match future.as_mut().poll(&mut cx) {
Poll::Ready(result) => return result,
Poll::Pending => {
// todo!("call tick on test dispatcher")
parker.park();
if !self.dispatcher.poll() {
// todo!("forbid_parking")
parker.park();
}
}
}
}

View File

@ -1,7 +1,7 @@
mod keystroke;
#[cfg(target_os = "macos")]
mod mac;
#[cfg(any(test, feature = "test"))]
#[cfg(any(test, feature = "test-support"))]
mod test;
use crate::{
@ -30,7 +30,7 @@ use std::{
pub use keystroke::*;
#[cfg(target_os = "macos")]
pub use mac::*;
#[cfg(any(test, feature = "test"))]
#[cfg(any(test, feature = "test-support"))]
pub use test::*;
pub use time::UtcOffset;
@ -161,6 +161,9 @@ pub trait PlatformDispatcher: Send + Sync {
fn dispatch(&self, runnable: Runnable);
fn dispatch_on_main_thread(&self, runnable: Runnable);
fn dispatch_after(&self, duration: Duration, runnable: Runnable);
fn poll(&self) -> bool;
#[cfg(any(test, feature = "test-support"))]
fn advance_clock(&self, duration: Duration);
}
pub trait PlatformTextSystem: Send + Sync {

View File

@ -67,6 +67,14 @@ impl PlatformDispatcher for MacDispatcher {
);
}
}
fn poll(&self) -> bool {
false
}
fn advance_clock(&self, _: Duration) {
unimplemented!()
}
}
extern "C" fn trampoline(runnable: *mut c_void) {

View File

@ -1,188 +1,5 @@
use super::Platform;
use crate::{DisplayId, Executor};
mod dispatcher;
mod platform;
pub struct TestPlatform;
impl TestPlatform {
pub fn new() -> Self {
TestPlatform
}
}
// todo!("implement out what our tests needed in GPUI 1")
impl Platform for TestPlatform {
fn executor(&self) -> Executor {
unimplemented!()
}
fn text_system(&self) -> std::sync::Arc<dyn crate::PlatformTextSystem> {
unimplemented!()
}
fn run(&self, _on_finish_launching: Box<dyn FnOnce()>) {
unimplemented!()
}
fn quit(&self) {
unimplemented!()
}
fn restart(&self) {
unimplemented!()
}
fn activate(&self, _ignoring_other_apps: bool) {
unimplemented!()
}
fn hide(&self) {
unimplemented!()
}
fn hide_other_apps(&self) {
unimplemented!()
}
fn unhide_other_apps(&self) {
unimplemented!()
}
fn displays(&self) -> Vec<std::rc::Rc<dyn crate::PlatformDisplay>> {
unimplemented!()
}
fn display(&self, _id: DisplayId) -> Option<std::rc::Rc<dyn crate::PlatformDisplay>> {
unimplemented!()
}
fn main_window(&self) -> Option<crate::AnyWindowHandle> {
unimplemented!()
}
fn open_window(
&self,
_handle: crate::AnyWindowHandle,
_options: crate::WindowOptions,
) -> Box<dyn crate::PlatformWindow> {
unimplemented!()
}
fn set_display_link_output_callback(
&self,
_display_id: DisplayId,
_callback: Box<dyn FnMut(&crate::VideoTimestamp, &crate::VideoTimestamp)>,
) {
unimplemented!()
}
fn start_display_link(&self, _display_id: DisplayId) {
unimplemented!()
}
fn stop_display_link(&self, _display_id: DisplayId) {
unimplemented!()
}
fn open_url(&self, _url: &str) {
unimplemented!()
}
fn on_open_urls(&self, _callback: Box<dyn FnMut(Vec<String>)>) {
unimplemented!()
}
fn prompt_for_paths(
&self,
_options: crate::PathPromptOptions,
) -> futures::channel::oneshot::Receiver<Option<Vec<std::path::PathBuf>>> {
unimplemented!()
}
fn prompt_for_new_path(
&self,
_directory: &std::path::Path,
) -> futures::channel::oneshot::Receiver<Option<std::path::PathBuf>> {
unimplemented!()
}
fn reveal_path(&self, _path: &std::path::Path) {
unimplemented!()
}
fn on_become_active(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_resign_active(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_quit(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_reopen(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_event(&self, _callback: Box<dyn FnMut(crate::InputEvent) -> bool>) {
unimplemented!()
}
fn os_name(&self) -> &'static str {
unimplemented!()
}
fn os_version(&self) -> anyhow::Result<crate::SemanticVersion> {
unimplemented!()
}
fn app_version(&self) -> anyhow::Result<crate::SemanticVersion> {
unimplemented!()
}
fn app_path(&self) -> anyhow::Result<std::path::PathBuf> {
unimplemented!()
}
fn local_timezone(&self) -> time::UtcOffset {
unimplemented!()
}
fn path_for_auxiliary_executable(&self, _name: &str) -> anyhow::Result<std::path::PathBuf> {
unimplemented!()
}
fn set_cursor_style(&self, _style: crate::CursorStyle) {
unimplemented!()
}
fn should_auto_hide_scrollbars(&self) -> bool {
unimplemented!()
}
fn write_to_clipboard(&self, _item: crate::ClipboardItem) {
unimplemented!()
}
fn read_from_clipboard(&self) -> Option<crate::ClipboardItem> {
unimplemented!()
}
fn write_credentials(
&self,
_url: &str,
_username: &str,
_password: &[u8],
) -> anyhow::Result<()> {
unimplemented!()
}
fn read_credentials(&self, _url: &str) -> anyhow::Result<Option<(String, Vec<u8>)>> {
unimplemented!()
}
fn delete_credentials(&self, _url: &str) -> anyhow::Result<()> {
unimplemented!()
}
}
pub use dispatcher::*;
pub use platform::*;

View File

@ -0,0 +1,150 @@
use crate::PlatformDispatcher;
use async_task::Runnable;
use collections::{BTreeMap, VecDeque};
use parking_lot::Mutex;
use rand::prelude::*;
use std::time::{Duration, Instant};
pub struct TestDispatcher(Mutex<TestDispatcherState>);
struct TestDispatcherState {
random: StdRng,
foreground: VecDeque<Runnable>,
background: Vec<Runnable>,
delayed: BTreeMap<Instant, Runnable>,
time: Instant,
is_main_thread: bool,
}
impl TestDispatcher {
pub fn new(random: StdRng) -> Self {
let state = TestDispatcherState {
random,
foreground: VecDeque::new(),
background: Vec::new(),
delayed: BTreeMap::new(),
time: Instant::now(),
is_main_thread: true,
};
TestDispatcher(Mutex::new(state))
}
}
impl PlatformDispatcher for TestDispatcher {
fn is_main_thread(&self) -> bool {
self.0.lock().is_main_thread
}
fn dispatch(&self, runnable: Runnable) {
self.0.lock().background.push(runnable);
}
fn dispatch_on_main_thread(&self, runnable: Runnable) {
self.0.lock().foreground.push_back(runnable);
}
fn dispatch_after(&self, duration: std::time::Duration, runnable: Runnable) {
let mut state = self.0.lock();
let next_time = state.time + duration;
state.delayed.insert(next_time, runnable);
}
fn poll(&self) -> bool {
let mut state = self.0.lock();
while let Some((deadline, _)) = state.delayed.first_key_value() {
if *deadline > state.time {
break;
}
let (_, runnable) = state.delayed.pop_first().unwrap();
state.background.push(runnable);
}
if state.foreground.is_empty() && state.background.is_empty() {
return false;
}
let foreground_len = state.foreground.len();
let background_len = state.background.len();
let main_thread = background_len == 0
|| state
.random
.gen_ratio(foreground_len as u32, background_len as u32);
let was_main_thread = state.is_main_thread;
state.is_main_thread = main_thread;
let runnable = if main_thread {
state.foreground.pop_front().unwrap()
} else {
let ix = state.random.gen_range(0..background_len);
state.background.remove(ix)
};
drop(state);
runnable.run();
self.0.lock().is_main_thread = was_main_thread;
true
}
fn advance_clock(&self, by: Duration) {
self.0.lock().time += by;
}
}
#[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);
}
}

View File

@ -0,0 +1,194 @@
use crate::{DisplayId, Executor, Platform, PlatformTextSystem, TestDispatcher};
use rand::prelude::*;
use std::sync::Arc;
pub struct TestPlatform {
executor: Executor,
}
impl TestPlatform {
pub fn new(seed: u64) -> Self {
let rng = StdRng::seed_from_u64(seed);
TestPlatform {
executor: Executor::new(Arc::new(TestDispatcher::new(rng))),
}
}
}
// todo!("implement out what our tests needed in GPUI 1")
impl Platform for TestPlatform {
fn executor(&self) -> Executor {
self.executor.clone()
}
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
Arc::new(crate::platform::mac::MacTextSystem::new())
}
fn run(&self, _on_finish_launching: Box<dyn FnOnce()>) {
unimplemented!()
}
fn quit(&self) {
unimplemented!()
}
fn restart(&self) {
unimplemented!()
}
fn activate(&self, _ignoring_other_apps: bool) {
unimplemented!()
}
fn hide(&self) {
unimplemented!()
}
fn hide_other_apps(&self) {
unimplemented!()
}
fn unhide_other_apps(&self) {
unimplemented!()
}
fn displays(&self) -> Vec<std::rc::Rc<dyn crate::PlatformDisplay>> {
unimplemented!()
}
fn display(&self, _id: DisplayId) -> Option<std::rc::Rc<dyn crate::PlatformDisplay>> {
unimplemented!()
}
fn main_window(&self) -> Option<crate::AnyWindowHandle> {
unimplemented!()
}
fn open_window(
&self,
_handle: crate::AnyWindowHandle,
_options: crate::WindowOptions,
) -> Box<dyn crate::PlatformWindow> {
unimplemented!()
}
fn set_display_link_output_callback(
&self,
_display_id: DisplayId,
_callback: Box<dyn FnMut(&crate::VideoTimestamp, &crate::VideoTimestamp)>,
) {
unimplemented!()
}
fn start_display_link(&self, _display_id: DisplayId) {
unimplemented!()
}
fn stop_display_link(&self, _display_id: DisplayId) {
unimplemented!()
}
fn open_url(&self, _url: &str) {
unimplemented!()
}
fn on_open_urls(&self, _callback: Box<dyn FnMut(Vec<String>)>) {
unimplemented!()
}
fn prompt_for_paths(
&self,
_options: crate::PathPromptOptions,
) -> futures::channel::oneshot::Receiver<Option<Vec<std::path::PathBuf>>> {
unimplemented!()
}
fn prompt_for_new_path(
&self,
_directory: &std::path::Path,
) -> futures::channel::oneshot::Receiver<Option<std::path::PathBuf>> {
unimplemented!()
}
fn reveal_path(&self, _path: &std::path::Path) {
unimplemented!()
}
fn on_become_active(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_resign_active(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_quit(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_reopen(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_event(&self, _callback: Box<dyn FnMut(crate::InputEvent) -> bool>) {
unimplemented!()
}
fn os_name(&self) -> &'static str {
unimplemented!()
}
fn os_version(&self) -> anyhow::Result<crate::SemanticVersion> {
unimplemented!()
}
fn app_version(&self) -> anyhow::Result<crate::SemanticVersion> {
unimplemented!()
}
fn app_path(&self) -> anyhow::Result<std::path::PathBuf> {
unimplemented!()
}
fn local_timezone(&self) -> time::UtcOffset {
unimplemented!()
}
fn path_for_auxiliary_executable(&self, _name: &str) -> anyhow::Result<std::path::PathBuf> {
unimplemented!()
}
fn set_cursor_style(&self, _style: crate::CursorStyle) {
unimplemented!()
}
fn should_auto_hide_scrollbars(&self) -> bool {
unimplemented!()
}
fn write_to_clipboard(&self, _item: crate::ClipboardItem) {
unimplemented!()
}
fn read_from_clipboard(&self) -> Option<crate::ClipboardItem> {
unimplemented!()
}
fn write_credentials(
&self,
_url: &str,
_username: &str,
_password: &[u8],
) -> anyhow::Result<()> {
unimplemented!()
}
fn read_credentials(&self, _url: &str) -> anyhow::Result<Option<(String, Vec<u8>)>> {
unimplemented!()
}
fn delete_credentials(&self, _url: &str) -> anyhow::Result<()> {
unimplemented!()
}
}

View File

@ -143,7 +143,7 @@ mod tests {
#[test]
fn test_wrap_line() {
App::test().run(|cx| {
App::test(0).run(|cx| {
let text_system = cx.text_system().clone();
let mut wrapper = LineWrapper::new(
text_system.font_id(&font("Courier")).unwrap(),

View File

@ -12,10 +12,10 @@ pub use util::*;
// timer.race(future).await
// }
#[cfg(any(test, feature = "test"))]
#[cfg(any(test, feature = "test-support"))]
pub struct CwdBacktrace<'a>(pub &'a backtrace::Backtrace);
#[cfg(any(test, feature = "test"))]
#[cfg(any(test, feature = "test-support"))]
impl<'a> std::fmt::Debug for CwdBacktrace<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use backtrace::{BacktraceFmt, BytesOrWideString};

View File

@ -1819,7 +1819,7 @@ impl AnyWindowHandle {
}
}
#[cfg(any(test, feature = "test"))]
#[cfg(any(test, feature = "test-support"))]
impl From<SmallVec<[u32; 16]>> for StackingOrder {
fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
StackingOrder(small_vec)