Use observe for module list instead of clearing only when the length is different
This should fix issues when we update a module it's content. That wouldn't show up anymore. So by always resetting the list we should get the most up-to-date value. NOTE: We probably want to reduce the amount of resets and notifies every time we update the client state, even though we didn't update the modules. We could send and specific event from the client state, each time we update a module. So instead of using a observer we could use a normal event subscriber and only update the list based on that event
This commit is contained in:
@@ -33,7 +33,6 @@ pub enum DebugPanelItemEvent {
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub enum ThreadItem {
|
||||
Console,
|
||||
LoadedSource,
|
||||
@@ -41,15 +40,6 @@ pub enum ThreadItem {
|
||||
Variables,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
enum ThreadItem {
|
||||
Console,
|
||||
LoadedSource,
|
||||
Modules,
|
||||
Variables,
|
||||
}
|
||||
|
||||
impl ThreadItem {
|
||||
fn to_proto(&self) -> proto::DebuggerThreadItem {
|
||||
match self {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use dap::{client::DebugAdapterClientId, ModuleEvent};
|
||||
use gpui::{list, AnyElement, Empty, Entity, FocusHandle, Focusable, ListState};
|
||||
use gpui::{list, AnyElement, Empty, Entity, FocusHandle, Focusable, ListState, Subscription};
|
||||
use project::dap_session::DebugSession;
|
||||
use ui::prelude::*;
|
||||
|
||||
pub struct ModuleList {
|
||||
list: ListState,
|
||||
focus_handle: FocusHandle,
|
||||
_subscription: Subscription,
|
||||
session: Entity<DebugSession>,
|
||||
client_id: DebugAdapterClientId,
|
||||
modules_len: usize,
|
||||
}
|
||||
|
||||
impl ModuleList {
|
||||
@@ -32,45 +32,40 @@ impl ModuleList {
|
||||
},
|
||||
);
|
||||
|
||||
session.update(cx, |session, _cx| {
|
||||
session.client_state(*client_id).unwrap();
|
||||
let client_state = session.read(cx).client_state(*client_id).unwrap();
|
||||
|
||||
let _subscription = cx.observe(&client_state, |module_list, state, cx| {
|
||||
let modules_len = state.update(cx, |state, cx| state.modules(cx).len());
|
||||
|
||||
module_list.list.reset(modules_len);
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
Self {
|
||||
list,
|
||||
session,
|
||||
focus_handle,
|
||||
_subscription,
|
||||
client_id: *client_id,
|
||||
modules_len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_module_event(&mut self, event: &ModuleEvent, cx: &mut Context<Self>) {
|
||||
if let Some(state) = self.session.read(cx).client_state(self.client_id) {
|
||||
let modules_len = state.update(cx, |state, cx| {
|
||||
state.handle_module_event(event);
|
||||
state.modules(cx).len()
|
||||
});
|
||||
|
||||
if modules_len != self.modules_len {
|
||||
self.modules_len = modules_len;
|
||||
self.list.reset(self.modules_len);
|
||||
}
|
||||
|
||||
cx.notify()
|
||||
state.update(cx, |state, cx| state.handle_module_event(event, cx));
|
||||
}
|
||||
}
|
||||
|
||||
fn render_entry(&mut self, ix: usize, cx: &mut Context<Self>) -> AnyElement {
|
||||
let Some((module_name, module_path)) = self.session.update(cx, |session, cx| {
|
||||
session
|
||||
.client_state(self.client_id)?
|
||||
.update(cx, |state, cx| {
|
||||
state
|
||||
.modules(cx)
|
||||
.get(ix)
|
||||
.map(|module| (module.name.clone(), module.path.clone()))
|
||||
})
|
||||
let Some((module_name, module_path)) = maybe!({
|
||||
let client_state = self.session.read(cx).client_state(self.client_id)?;
|
||||
|
||||
client_state.update(cx, |state, cx| {
|
||||
state
|
||||
.modules(cx)
|
||||
.get(ix)
|
||||
.map(|module| (module.name.clone(), module.path.clone()))
|
||||
})
|
||||
}) else {
|
||||
return Empty.into_any();
|
||||
};
|
||||
@@ -100,19 +95,14 @@ impl Focusable for ModuleList {
|
||||
|
||||
impl Render for ModuleList {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let session = self.session.read(cx);
|
||||
let modules_len = session
|
||||
.client_state(self.client_id)
|
||||
.map_or(0usize, |state| {
|
||||
state.update(cx, |state, cx| state.modules(cx).len())
|
||||
if let Some(state) = self.session.read(cx).client_state(self.client_id) {
|
||||
state.update(cx, |state, cx| {
|
||||
state.modules(cx);
|
||||
});
|
||||
|
||||
if modules_len != self.modules_len {
|
||||
self.modules_len = modules_len;
|
||||
self.list.reset(self.modules_len);
|
||||
}
|
||||
|
||||
div()
|
||||
.track_focus(&self.focus_handle)
|
||||
.size_full()
|
||||
.p_1()
|
||||
.child(list(self.list.clone()).size_full())
|
||||
@@ -121,6 +111,7 @@ impl Render for ModuleList {
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
use dap::Module;
|
||||
use util::maybe;
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl ModuleList {
|
||||
|
||||
@@ -178,7 +178,7 @@ impl DebugAdapterClientState {
|
||||
&self.modules
|
||||
}
|
||||
|
||||
pub fn handle_module_event(&mut self, event: &dap::ModuleEvent) {
|
||||
pub fn handle_module_event(&mut self, event: &dap::ModuleEvent, cx: &mut Context<Self>) {
|
||||
match event.reason {
|
||||
dap::ModuleEventReason::New => self.modules.push(event.module.clone()),
|
||||
dap::ModuleEventReason::Changed => {
|
||||
@@ -188,6 +188,7 @@ impl DebugAdapterClientState {
|
||||
}
|
||||
dap::ModuleEventReason::Removed => self.modules.retain(|m| m.id != event.module.id),
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn loaded_sources(&mut self, cx: &mut Context<Self>) -> &[Source] {
|
||||
|
||||
Reference in New Issue
Block a user