mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Merge branch 'zed2' of github.com:zed-industries/zed into zed2
This commit is contained in:
commit
08a4e53cfe
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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::*;
|
||||
|
150
crates/gpui2/src/platform/test/dispatcher.rs
Normal file
150
crates/gpui2/src/platform/test/dispatcher.rs
Normal 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);
|
||||
}
|
||||
}
|
194
crates/gpui2/src/platform/test/platform.rs
Normal file
194
crates/gpui2/src/platform/test/platform.rs
Normal 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!()
|
||||
}
|
||||
}
|
@ -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(),
|
||||
|
@ -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};
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user