gpui: Add Global marker trait (#7095)

This should prevent a class of bugs where one queries the wrong type of
global, which results in oddities at runtime.

Release Notes:

- N/A

---------

Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
Piotr Osiewicz 2024-01-30 20:08:20 +01:00 committed by GitHub
parent 7bfa584eb6
commit e6ebe7974d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 449 additions and 237 deletions

View file

@ -19,6 +19,7 @@ use log::LevelFilter;
use assets::Assets;
use node_runtime::RealNodeRuntime;
use parking_lot::Mutex;
use release_channel::{parse_zed_link, AppCommitSha, ReleaseChannel, RELEASE_CHANNEL};
use serde::{Deserialize, Serialize};
use settings::{
default_settings, handle_settings_file_changes, watch_config_file, Settings, SettingsStore,
@ -34,14 +35,13 @@ use std::{
path::{Path, PathBuf},
sync::{
atomic::{AtomicU32, Ordering},
Arc, Weak,
Arc,
},
thread,
};
use theme::{ActiveTheme, ThemeRegistry, ThemeSettings};
use util::{
async_maybe,
channel::{parse_zed_link, AppCommitSha, ReleaseChannel, RELEASE_CHANNEL},
http::{self, HttpClient, ZedHttpClient},
paths::{self, CRASHES_DIR, CRASHES_RETIRED_DIR},
ResultExt,
@ -102,8 +102,7 @@ fn main() {
let open_listener = listener.clone();
app.on_open_urls(move |urls, _| open_listener.open_urls(&urls));
app.on_reopen(move |cx| {
if let Some(app_state) = cx
.try_global::<Weak<AppState>>()
if let Some(app_state) = AppState::try_global(cx)
.map(|app_state| app_state.upgrade())
.flatten()
{
@ -115,12 +114,12 @@ fn main() {
});
app.run(move |cx| {
cx.set_global(*RELEASE_CHANNEL);
ReleaseChannel::init(cx);
if let Some(build_sha) = option_env!("ZED_COMMIT_SHA") {
cx.set_global(AppCommitSha(build_sha.into()))
AppCommitSha::set_global(AppCommitSha(build_sha.into()), cx);
}
cx.set_global(listener.clone());
OpenListener::set_global(listener.clone(), cx);
load_embedded_fonts(cx);
@ -148,7 +147,7 @@ fn main() {
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.new_model(|cx| WorkspaceStore::new(client.clone(), cx));
cx.set_global(client.clone());
Client::set_global(client.clone(), cx);
zed::init(cx);
theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
@ -242,7 +241,7 @@ fn main() {
workspace_store,
node_runtime,
});
cx.set_global(Arc::downgrade(&app_state));
AppState::set_global(Arc::downgrade(&app_state), cx);
audio::init(Assets, cx);
auto_update::init(http.clone(), cx);
@ -565,7 +564,7 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
.or_else(|| info.payload().downcast_ref::<String>().map(|s| s.clone()))
.unwrap_or_else(|| "Box<Any>".to_string());
if *util::channel::RELEASE_CHANNEL == ReleaseChannel::Dev {
if *release_channel::RELEASE_CHANNEL == ReleaseChannel::Dev {
let location = info.location().unwrap();
let backtrace = Backtrace::new();
eprintln!(

View file

@ -5,7 +5,7 @@ use std::{
time::Duration,
};
use util::channel::ReleaseChannel;
use release_channel::ReleaseChannel;
const LOCALHOST: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
const CONNECT_TIMEOUT: Duration = Duration::from_millis(10);
@ -13,7 +13,7 @@ const RECEIVE_TIMEOUT: Duration = Duration::from_millis(35);
const SEND_TIMEOUT: Duration = Duration::from_millis(20);
fn address() -> SocketAddr {
let port = match *util::channel::RELEASE_CHANNEL {
let port = match *release_channel::RELEASE_CHANNEL {
ReleaseChannel::Dev => 43737,
ReleaseChannel::Preview => 43738,
ReleaseChannel::Stable => 43739,
@ -24,7 +24,7 @@ fn address() -> SocketAddr {
}
fn instance_handshake() -> &'static str {
match *util::channel::RELEASE_CHANNEL {
match *release_channel::RELEASE_CHANNEL {
ReleaseChannel::Dev => "Zed Editor Dev Instance Running",
ReleaseChannel::Nightly => "Zed Editor Nightly Instance Running",
ReleaseChannel::Preview => "Zed Editor Preview Instance Running",
@ -39,7 +39,7 @@ pub enum IsOnlyInstance {
}
pub fn ensure_only_instance() -> IsOnlyInstance {
if *db::ZED_STATELESS || *util::channel::RELEASE_CHANNEL == ReleaseChannel::Dev {
if *db::ZED_STATELESS || *release_channel::RELEASE_CHANNEL == ReleaseChannel::Dev {
return IsOnlyInstance::Yes;
}

View file

@ -6,8 +6,9 @@ use editor::Editor;
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
use futures::channel::{mpsc, oneshot};
use futures::{FutureExt, SinkExt, StreamExt};
use gpui::AsyncAppContext;
use gpui::{AppContext, AsyncAppContext, Global};
use language::{Bias, Point};
use release_channel::parse_zed_link;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::os::unix::prelude::OsStrExt;
@ -17,7 +18,6 @@ use std::sync::Arc;
use std::thread;
use std::time::Duration;
use std::{path::PathBuf, sync::atomic::AtomicBool};
use util::channel::parse_zed_link;
use util::paths::PathLikeWithPosition;
use util::ResultExt;
use workspace::AppState;
@ -42,7 +42,19 @@ pub struct OpenListener {
pub triggered: AtomicBool,
}
struct GlobalOpenListener(Arc<OpenListener>);
impl Global for GlobalOpenListener {}
impl OpenListener {
pub fn global(cx: &AppContext) -> Arc<Self> {
cx.global::<GlobalOpenListener>().0.clone()
}
pub fn set_global(listener: Arc<OpenListener>, cx: &mut AppContext) {
cx.set_global(GlobalOpenListener(listener))
}
pub fn new() -> (Self, UnboundedReceiver<OpenRequest>) {
let (tx, rx) = mpsc::unbounded();
(

View file

@ -20,6 +20,7 @@ use assets::Assets;
use futures::{channel::mpsc, select_biased, StreamExt};
use project_panel::ProjectPanel;
use quick_action_bar::QuickActionBar;
use release_channel::{AppCommitSha, ReleaseChannel};
use rope::Rope;
use search::project_search::ProjectSearchBar;
use settings::{initial_local_settings_content, KeymapFile, Settings, SettingsStore};
@ -27,7 +28,6 @@ use std::{borrow::Cow, ops::Deref, path::Path, sync::Arc};
use terminal_view::terminal_panel::{self, TerminalPanel};
use util::{
asset_str,
channel::{AppCommitSha, ReleaseChannel},
paths::{self, LOCAL_SETTINGS_RELATIVE_PATH},
ResultExt,
};
@ -202,8 +202,7 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
cx.toggle_full_screen();
})
.register_action(|_, action: &OpenZedUrl, cx| {
cx.global::<Arc<OpenListener>>()
.open_urls(&[action.url.clone()])
OpenListener::global(cx).open_urls(&[action.url.clone()])
})
.register_action(|_, action: &OpenBrowser, cx| cx.open_url(&action.url))
.register_action(move |_, _: &IncreaseBufferFontSize, cx| {
@ -370,12 +369,12 @@ fn initialize_pane(workspace: &mut Workspace, pane: &View<Pane>, cx: &mut ViewCo
}
fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
let app_name = cx.global::<ReleaseChannel>().display_name();
let app_name = ReleaseChannel::global(cx).display_name();
let version = env!("CARGO_PKG_VERSION");
let message = format!("{app_name} {version}");
let detail = cx.try_global::<AppCommitSha>().map(|sha| sha.0.as_ref());
let detail = AppCommitSha::try_global(cx).map(|sha| sha.0.clone());
let prompt = cx.prompt(PromptLevel::Info, &message, detail, &["OK"]);
let prompt = cx.prompt(PromptLevel::Info, &message, detail.as_deref(), &["OK"]);
cx.foreground_executor()
.spawn(async {
prompt.await.ok();