Skip to content

Commit

Permalink
gpui: Add Global marker trait (#7095)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
3 people authored Jan 30, 2024
1 parent 7bfa584 commit e6ebe79
Show file tree
Hide file tree
Showing 59 changed files with 449 additions and 237 deletions.
24 changes: 22 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ members = [
"crates/project_symbols",
"crates/quick_action_bar",
"crates/recent_projects",
"crates/release_channel",
"crates/rope",
"crates/rpc",
"crates/search",
Expand Down
12 changes: 10 additions & 2 deletions crates/audio/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{io::Cursor, sync::Arc};

use anyhow::Result;
use collections::HashMap;
use gpui::{AppContext, AssetSource};
use gpui::{AppContext, AssetSource, Global};
use rodio::{
source::{Buffered, SamplesConverter},
Decoder, Source,
Expand All @@ -15,6 +15,10 @@ pub struct SoundRegistry {
assets: Box<dyn AssetSource>,
}

struct GlobalSoundRegistry(Arc<SoundRegistry>);

impl Global for GlobalSoundRegistry {}

impl SoundRegistry {
pub fn new(source: impl AssetSource) -> Arc<Self> {
Arc::new(Self {
Expand All @@ -24,7 +28,11 @@ impl SoundRegistry {
}

pub fn global(cx: &AppContext) -> Arc<Self> {
cx.global::<Arc<Self>>().clone()
cx.global::<GlobalSoundRegistry>().0.clone()
}

pub(crate) fn set_global(source: impl AssetSource, cx: &mut AppContext) {
cx.set_global(GlobalSoundRegistry(SoundRegistry::new(source)));
}

pub fn get(&self, name: &str) -> Result<impl Source<Item = f32>> {
Expand Down
6 changes: 4 additions & 2 deletions crates/audio/src/audio.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use assets::SoundRegistry;
use gpui::{AppContext, AssetSource};
use gpui::{AppContext, AssetSource, Global};
use rodio::{OutputStream, OutputStreamHandle};
use util::ResultExt;

mod assets;

pub fn init(source: impl AssetSource, cx: &mut AppContext) {
cx.set_global(SoundRegistry::new(source));
SoundRegistry::set_global(source, cx);
cx.set_global(Audio::new());
}

Expand Down Expand Up @@ -37,6 +37,8 @@ pub struct Audio {
output_handle: Option<OutputStreamHandle>,
}

impl Global for Audio {}

impl Audio {
pub fn new() -> Self {
Self {
Expand Down
1 change: 1 addition & 0 deletions crates/auto_update/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ client = { path = "../client" }
gpui = { path = "../gpui" }
menu = { path = "../menu" }
project = { path = "../project" }
release_channel = { path = "../release_channel" }
settings = { path = "../settings" }
theme = { path = "../theme" }
workspace = { path = "../workspace" }
Expand Down
34 changes: 18 additions & 16 deletions crates/auto_update/src/auto_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use client::{Client, TelemetrySettings, ZED_APP_PATH, ZED_APP_VERSION};
use db::kvp::KEY_VALUE_STORE;
use db::RELEASE_CHANNEL;
use gpui::{
actions, AppContext, AsyncAppContext, Context as _, Model, ModelContext, SemanticVersion, Task,
ViewContext, VisualContext, WindowContext,
actions, AppContext, AsyncAppContext, Context as _, Global, Model, ModelContext,
SemanticVersion, Task, ViewContext, VisualContext, WindowContext,
};
use isahc::AsyncBody;

Expand All @@ -18,18 +18,15 @@ use smol::io::AsyncReadExt;
use settings::{Settings, SettingsStore};
use smol::{fs::File, process::Command};

use release_channel::{AppCommitSha, ReleaseChannel};
use std::{
env::consts::{ARCH, OS},
ffi::OsString,
sync::Arc,
time::Duration,
};
use update_notification::UpdateNotification;
use util::http::HttpClient;
use util::{
channel::{AppCommitSha, ReleaseChannel},
http::ZedHttpClient,
};
use util::http::{HttpClient, ZedHttpClient};
use workspace::Workspace;

const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification";
Expand Down Expand Up @@ -94,6 +91,11 @@ impl Settings for AutoUpdateSetting {
}
}

#[derive(Default)]
struct GlobalAutoUpdate(Option<Model<AutoUpdater>>);

impl Global for GlobalAutoUpdate {}

pub fn init(http_client: Arc<ZedHttpClient>, cx: &mut AppContext) {
AutoUpdateSetting::register(cx);

Expand Down Expand Up @@ -127,7 +129,7 @@ pub fn init(http_client: Arc<ZedHttpClient>, cx: &mut AppContext) {

updater
});
cx.set_global(Some(auto_updater));
cx.set_global(GlobalAutoUpdate(Some(auto_updater)));
}
}

Expand All @@ -146,7 +148,7 @@ pub fn check(_: &Check, cx: &mut WindowContext) {

pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) -> Option<()> {
let auto_updater = AutoUpdater::get(cx)?;
let release_channel = cx.try_global::<ReleaseChannel>()?;
let release_channel = ReleaseChannel::try_global(cx)?;

if matches!(
release_channel,
Expand Down Expand Up @@ -191,7 +193,7 @@ pub fn notify_of_any_new_update(cx: &mut ViewContext<Workspace>) -> Option<()> {

impl AutoUpdater {
pub fn get(cx: &mut AppContext) -> Option<Model<Self>> {
cx.default_global::<Option<Model<Self>>>().clone()
cx.default_global::<GlobalAutoUpdate>().0.clone()
}

fn new(current_version: SemanticVersion, http_client: Arc<ZedHttpClient>) -> Self {
Expand Down Expand Up @@ -253,8 +255,7 @@ impl AutoUpdater {
OS, ARCH
));
cx.update(|cx| {
if let Some(param) = cx
.try_global::<ReleaseChannel>()
if let Some(param) = ReleaseChannel::try_global(cx)
.map(|release_channel| release_channel.release_query_param())
.flatten()
{
Expand All @@ -276,7 +277,9 @@ impl AutoUpdater {

let should_download = match *RELEASE_CHANNEL {
ReleaseChannel::Nightly => cx
.try_read_global::<AppCommitSha, _>(|sha, _| release.version != sha.0)
.update(|cx| AppCommitSha::try_global(cx).map(|sha| release.version != sha.0))
.ok()
.flatten()
.unwrap_or(true),
_ => release.version.parse::<SemanticVersion>()? > current_version,
};
Expand Down Expand Up @@ -311,9 +314,8 @@ impl AutoUpdater {
let mut dmg_file = File::create(&dmg_path).await?;

let (installation_id, release_channel, telemetry) = cx.update(|cx| {
let installation_id = cx.global::<Arc<Client>>().telemetry().installation_id();
let release_channel = cx
.try_global::<ReleaseChannel>()
let installation_id = Client::global(cx).telemetry().installation_id();
let release_channel = ReleaseChannel::try_global(cx)
.map(|release_channel| release_channel.display_name());
let telemetry = TelemetrySettings::get_global(cx).metrics;

Expand Down
4 changes: 2 additions & 2 deletions crates/auto_update/src/update_notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use gpui::{
SemanticVersion, StatefulInteractiveElement, Styled, ViewContext,
};
use menu::Cancel;
use util::channel::ReleaseChannel;
use release_channel::ReleaseChannel;
use workspace::ui::{h_flex, v_flex, Icon, IconName, Label, StyledExt};

pub struct UpdateNotification {
Expand All @@ -14,7 +14,7 @@ impl EventEmitter<DismissEvent> for UpdateNotification {}

impl Render for UpdateNotification {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl IntoElement {
let app_name = cx.global::<ReleaseChannel>().display_name();
let app_name = ReleaseChannel::global(cx).display_name();

v_flex()
.on_action(cx.listener(UpdateNotification::dismiss))
Expand Down
17 changes: 13 additions & 4 deletions crates/call/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use client::{proto, Client, TypedEnvelope, User, UserStore, ZED_ALWAYS_ACTIVE};
use collections::HashSet;
use futures::{channel::oneshot, future::Shared, Future, FutureExt};
use gpui::{
AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, Subscription, Task,
WeakModel,
AppContext, AsyncAppContext, Context, EventEmitter, Global, Model, ModelContext, Subscription,
Task, WeakModel,
};
use postage::watch;
use project::Project;
Expand All @@ -21,11 +21,15 @@ use std::sync::Arc;
pub use participant::ParticipantLocation;
pub use room::Room;

struct GlobalActiveCall(Model<ActiveCall>);

impl Global for GlobalActiveCall {}

pub fn init(client: Arc<Client>, user_store: Model<UserStore>, cx: &mut AppContext) {
CallSettings::register(cx);

let active_call = cx.new_model(|cx| ActiveCall::new(client, user_store, cx));
cx.set_global(active_call);
cx.set_global(GlobalActiveCall(active_call));
}

pub struct OneAtATime {
Expand Down Expand Up @@ -154,7 +158,12 @@ impl ActiveCall {
}

pub fn global(cx: &AppContext) -> Model<Self> {
cx.global::<Model<Self>>().clone()
cx.global::<GlobalActiveCall>().0.clone()
}

pub fn try_global(cx: &AppContext) -> Option<Model<Self>> {
cx.try_global::<GlobalActiveCall>()
.map(|call| call.0.clone())
}

pub fn invite(
Expand Down
1 change: 1 addition & 0 deletions crates/channel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ util = { path = "../util" }
rpc = { path = "../rpc" }
text = { path = "../text" }
language = { path = "../language" }
release_channel = { path = "../release_channel" }
settings = { path = "../settings" }
feature_flags = { path = "../feature_flags" }
sum_tree = { path = "../sum_tree" }
Expand Down
Loading

0 comments on commit e6ebe79

Please sign in to comment.