WIP

Antonio Scandurra created

Change summary

crates/editor2/src/items.rs   |   2 
crates/workspace2/src/item.rs | 162 ++++++++++++++++++------------------
2 files changed, 84 insertions(+), 80 deletions(-)

Detailed changes

crates/editor2/src/items.rs 🔗

@@ -576,7 +576,7 @@ impl Item for Editor {
     }
 
     fn tab_content<T: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<T> {
-        todo!();
+        AnyElement::new(gpui::ParentElement::child(gpui::div(), "HEY"))
 
         // Flex::row()
         //     .with_child(Label::new(self.title(cx).to_string(), style.label.clone()).into_any())

crates/workspace2/src/item.rs 🔗

@@ -15,7 +15,6 @@ use gpui2::{
     AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, FocusHandle, HighlightStyle,
     Model, Pixels, Point, Render, SharedString, Task, View, ViewContext, WeakView, WindowContext,
 };
-use parking_lot::Mutex;
 use project2::{Project, ProjectEntryId, ProjectPath};
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
@@ -23,8 +22,10 @@ use settings2::Settings;
 use smallvec::SmallVec;
 use std::{
     any::{Any, TypeId},
+    cell::RefCell,
     ops::Range,
     path::PathBuf,
+    rc::Rc,
     sync::{
         atomic::{AtomicBool, Ordering},
         Arc,
@@ -412,91 +413,94 @@ impl<T: Item> ItemHandle for View<T> {
             .is_none()
         {
             let mut pending_autosave = DelayedDebouncedEditAction::new();
-            let pending_update = Arc::new(Mutex::new(None));
+            let pending_update = Rc::new(RefCell::new(None));
             let pending_update_scheduled = Arc::new(AtomicBool::new(false));
 
-            let event_subscription = Some(cx.subscribe(self, move |workspace, item, event, cx| {
-                let pane = if let Some(pane) = workspace
-                    .panes_by_item
-                    .get(&item.id())
-                    .and_then(|pane| pane.upgrade())
-                {
-                    pane
-                } else {
-                    log::error!("unexpected item event after pane was dropped");
-                    return;
-                };
-
-                if let Some(item) = item.to_followable_item_handle(cx) {
-                    let _is_project_item = item.is_project_item(cx);
-                    let leader_id = workspace.leader_for_pane(&pane);
-
-                    if leader_id.is_some() && item.should_unfollow_on_event(event, cx) {
-                        workspace.unfollow(&pane, cx);
-                    }
-
-                    if item.add_event_to_update_proto(event, &mut *pending_update.lock(), cx)
-                        && !pending_update_scheduled.load(Ordering::SeqCst)
+            let mut event_subscription =
+                Some(cx.subscribe(self, move |workspace, item, event, cx| {
+                    let pane = if let Some(pane) = workspace
+                        .panes_by_item
+                        .get(&item.id())
+                        .and_then(|pane| pane.upgrade())
                     {
-                        pending_update_scheduled.store(true, Ordering::SeqCst);
-                        todo!("replace with on_next_frame?");
-                        // cx.after_window_update({
-                        //     let pending_update = pending_update.clone();
-                        //     let pending_update_scheduled = pending_update_scheduled.clone();
-                        //     move |this, cx| {
-                        //         pending_update_scheduled.store(false, Ordering::SeqCst);
-                        //         this.update_followers(
-                        //             is_project_item,
-                        //             proto::update_followers::Variant::UpdateView(
-                        //                 proto::UpdateView {
-                        //                     id: item
-                        //                         .remote_id(&this.app_state.client, cx)
-                        //                         .map(|id| id.to_proto()),
-                        //                     variant: pending_update.borrow_mut().take(),
-                        //                     leader_id,
-                        //                 },
-                        //             ),
-                        //             cx,
-                        //         );
-                        //     }
-                        // });
-                    }
-                }
-
-                for item_event in T::to_item_events(event).into_iter() {
-                    match item_event {
-                        ItemEvent::CloseItem => {
-                            pane.update(cx, |pane, cx| {
-                                pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
-                            })
-                            .detach_and_log_err(cx);
-                            return;
+                        pane
+                    } else {
+                        log::error!("unexpected item event after pane was dropped");
+                        return;
+                    };
+
+                    if let Some(item) = item.to_followable_item_handle(cx) {
+                        let is_project_item = item.is_project_item(cx);
+                        let leader_id = workspace.leader_for_pane(&pane);
+
+                        if leader_id.is_some() && item.should_unfollow_on_event(event, cx) {
+                            workspace.unfollow(&pane, cx);
                         }
 
-                        ItemEvent::UpdateTab => {
-                            pane.update(cx, |_, cx| {
-                                cx.emit(pane::Event::ChangeItemTitle);
-                                cx.notify();
+                        if item.add_event_to_update_proto(
+                            event,
+                            &mut *pending_update.borrow_mut(),
+                            cx,
+                        ) && !pending_update_scheduled.load(Ordering::SeqCst)
+                        {
+                            pending_update_scheduled.store(true, Ordering::SeqCst);
+                            cx.on_next_frame({
+                                let pending_update = pending_update.clone();
+                                let pending_update_scheduled = pending_update_scheduled.clone();
+                                move |this, cx| {
+                                    pending_update_scheduled.store(false, Ordering::SeqCst);
+                                    this.update_followers(
+                                        is_project_item,
+                                        proto::update_followers::Variant::UpdateView(
+                                            proto::UpdateView {
+                                                id: item
+                                                    .remote_id(&this.app_state.client, cx)
+                                                    .map(|id| id.to_proto()),
+                                                variant: pending_update.borrow_mut().take(),
+                                                leader_id,
+                                            },
+                                        ),
+                                        cx,
+                                    );
+                                }
                             });
                         }
+                    }
 
-                        ItemEvent::Edit => {
-                            let autosave = WorkspaceSettings::get_global(cx).autosave;
-                            if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
-                                let delay = Duration::from_millis(milliseconds);
-                                let item = item.clone();
-                                pending_autosave.fire_new(delay, cx, move |workspace, cx| {
-                                    Pane::autosave_item(&item, workspace.project().clone(), cx)
+                    for item_event in T::to_item_events(event).into_iter() {
+                        match item_event {
+                            ItemEvent::CloseItem => {
+                                pane.update(cx, |pane, cx| {
+                                    pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
+                                })
+                                .detach_and_log_err(cx);
+                                return;
+                            }
+
+                            ItemEvent::UpdateTab => {
+                                pane.update(cx, |_, cx| {
+                                    cx.emit(pane::Event::ChangeItemTitle);
+                                    cx.notify();
                                 });
                             }
-                        }
 
-                        _ => {}
+                            ItemEvent::Edit => {
+                                let autosave = WorkspaceSettings::get_global(cx).autosave;
+                                if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
+                                    let delay = Duration::from_millis(milliseconds);
+                                    let item = item.clone();
+                                    pending_autosave.fire_new(delay, cx, move |workspace, cx| {
+                                        Pane::autosave_item(&item, workspace.project().clone(), cx)
+                                    });
+                                }
+                            }
+
+                            _ => {}
+                        }
                     }
-                }
-            }));
+                }));
 
-            todo!("observe focus");
+            // todo!()
             // cx.observe_focus(self, move |workspace, item, focused, cx| {
             //     if !focused
             //         && WorkspaceSettings::get_global(cx).autosave == AutosaveSetting::OnFocusChange
@@ -507,12 +511,12 @@ impl<T: Item> ItemHandle for View<T> {
             // })
             // .detach();
 
-            // let item_id = self.id();
-            // cx.observe_release(self, move |workspace, _, _| {
-            //     workspace.panes_by_item.remove(&item_id);
-            //     event_subscription.take();
-            // })
-            // .detach();
+            let item_id = self.id();
+            cx.observe_release(self, move |workspace, _, _| {
+                workspace.panes_by_item.remove(&item_id);
+                event_subscription.take();
+            })
+            .detach();
         }
 
         cx.defer(|workspace, cx| {