Skip to content

Commit

Permalink
Refactor how we store thread data
Browse files Browse the repository at this point in the history
We now store the information in a better way so we could filter on it easier and faster.
  • Loading branch information
RemcoSmitsDev committed Aug 11, 2024
1 parent 8e707e9 commit 05b475a
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

14 changes: 2 additions & 12 deletions crates/dap/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use smol::{
process::{self, Child},
};
use std::{
collections::HashMap,
collections::{BTreeMap, HashMap},
net::{Ipv4Addr, SocketAddrV4},
path::PathBuf,
process::Stdio,
Expand All @@ -38,16 +38,6 @@ use std::{
use task::{DebugAdapterConfig, DebugConnectionType, DebugRequestType, TCPHost};
use text::Point;

#[derive(Debug, Clone)]
pub enum ThreadEntry {
Scope(Scope),
Variable {
depth: usize,
variable: Variable,
has_children: bool,
},
}

#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ThreadStatus {
#[default]
Expand All @@ -65,7 +55,7 @@ pub struct DebugAdapterClientId(pub usize);
pub struct ThreadState {
pub status: ThreadStatus,
pub stack_frames: Vec<StackFrame>,
pub stack_frame_entries: HashMap<u64, Vec<ThreadEntry>>, // stack_frame_id -> ThreadEntry(scope & variables)
pub variables: BTreeMap<StackFrame, BTreeMap<Scope, Vec<(usize, Variable)>>>,
pub current_stack_frame_id: u64,
}

Expand Down
84 changes: 40 additions & 44 deletions crates/debugger_ui/src/debugger_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use anyhow::Result;
use dap::client::{DebugAdapterClientId, ThreadState, ThreadStatus};
use dap::requests::{Disconnect, Request, Scopes, StackTrace, StartDebugging, Variables};
use dap::transport::Payload;
use dap::{client::DebugAdapterClient, client::ThreadEntry, transport::Events};
use dap::{client::DebugAdapterClient, transport::Events};
use dap::{
Capabilities, ContinuedEvent, DisconnectArguments, ExitedEvent, OutputEvent, ScopesArguments,
StackFrame, StackTraceArguments, StartDebuggingRequestArguments, StoppedEvent, TerminatedEvent,
ThreadEvent, ThreadEventReason, VariablesArguments,
ThreadEvent, ThreadEventReason, Variable, VariablesArguments,
};
use editor::Editor;
use futures::future::try_join_all;
Expand All @@ -16,8 +16,9 @@ use gpui::{
Subscription, Task, View, ViewContext, WeakView,
};
use serde_json::json;
use std::collections::BTreeMap;
use std::path::Path;
use std::{collections::HashMap, sync::Arc};
use std::sync::Arc;
use task::DebugRequestType;
use ui::prelude::*;
use util::{merge_json_value_into, ResultExt};
Expand Down Expand Up @@ -393,7 +394,7 @@ impl DebugPanel {
client: Arc<DebugAdapterClient>,
variables_reference: u64,
depth: usize,
) -> Result<Vec<ThreadEntry>> {
) -> Result<Vec<(usize, Variable)>> {
let response = client
.request::<Variables>(VariablesArguments {
variables_reference,
Expand All @@ -408,35 +409,30 @@ impl DebugPanel {
for variable in response.variables {
let client = client.clone();
tasks.push(async move {
let mut entries = Vec::new();
entries.push(ThreadEntry::Variable {
depth,
variable: variable.clone(),
has_children: variable.variables_reference > 0,
});
let mut variables = vec![(depth, variable.clone())];

if variable.variables_reference > 0 {
let mut nested_entries = Box::pin(Self::fetch_variables(
let mut nested_variables = Box::pin(Self::fetch_variables(
client,
variable.variables_reference,
depth + 1,
))
.await?;

entries.append(&mut nested_entries);
variables.append(&mut nested_variables);
}

anyhow::Ok(entries)
anyhow::Ok(variables)
});
}

let mut entries = Vec::new();
let mut variables = Vec::new();

for mut variable_entries in try_join_all(tasks).await? {
entries.append(&mut variable_entries);
variables.append(&mut variable_entries);
}

anyhow::Ok(entries)
anyhow::Ok(variables)
}

fn handle_stopped_event(
Expand All @@ -461,65 +457,65 @@ impl DebugPanel {
})
.await?;

let mut thread_state = ThreadState::default();

let current_stack_frame =
stack_trace_response.stack_frames.first().unwrap().clone();
let mut scope_tasks = Vec::new();
for stack_frame in stack_trace_response.stack_frames.clone().into_iter() {
let frame_id = stack_frame.id;
let client = client.clone();
scope_tasks.push(async move {
anyhow::Ok((
frame_id,
stack_frame.clone(),
client
.request::<Scopes>(ScopesArguments { frame_id })
.request::<Scopes>(ScopesArguments {
frame_id: stack_frame.id,
})
.await?,
))
});
}

let mut stack_frame_entries: HashMap<u64, Vec<ThreadEntry>> = HashMap::new();

let mut tasks = Vec::new();

for (stack_frame_id, response) in try_join_all(scope_tasks).await? {
let mut stack_frame_tasks = Vec::new();
for (stack_frame, response) in try_join_all(scope_tasks).await? {
let client = client.clone();
tasks.push(async move {
let mut entries = Vec::new();
stack_frame_tasks.push(async move {
let mut variable_tasks = Vec::new();

for scope in response.scopes {
let scope_reference = scope.variables_reference;

entries.push(ThreadEntry::Scope(scope));

entries.append(
&mut Self::fetch_variables(client.clone(), scope_reference, 1)
.await?,
);
let client = client.clone();
variable_tasks.push(async move {
anyhow::Ok((
scope,
Self::fetch_variables(client, scope_reference, 1).await?,
))
});
}

anyhow::Ok((stack_frame_id, entries))
anyhow::Ok((stack_frame, try_join_all(variable_tasks).await?))
});
}

for (stack_frame_id, mut scope_entries) in try_join_all(tasks).await? {
let entries = stack_frame_entries
.entry(stack_frame_id)
.or_insert(Vec::default());
for (stack_frame, scopes) in try_join_all(stack_frame_tasks).await? {
let stack_frame_state = thread_state
.variables
.entry(stack_frame)
.or_insert_with(BTreeMap::default);

entries.append(&mut scope_entries);
for (scope, variables) in scopes {
stack_frame_state.insert(scope, variables);
}
}

this.update(&mut cx, |this, cx| {
let mut thread_state = client.thread_states();
let thread_state = thread_state
.entry(thread_id)
.or_insert(ThreadState::default());

thread_state.current_stack_frame_id = current_stack_frame.clone().id;
thread_state.stack_frames = stack_trace_response.stack_frames;
thread_state.stack_frame_entries = stack_frame_entries;
thread_state.status = ThreadStatus::Stopped;

client.thread_states().insert(thread_id, thread_state);

let existing_item = this
.pane
.read(cx)
Expand Down
55 changes: 42 additions & 13 deletions crates/debugger_ui/src/debugger_panel_item.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::debugger_panel::{DebugPanel, DebugPanelEvent};
use anyhow::Result;
use dap::client::{
DebugAdapterClient, DebugAdapterClientId, ThreadEntry, ThreadState, ThreadStatus,
};
use dap::client::{DebugAdapterClient, DebugAdapterClientId, ThreadState, ThreadStatus};
use dap::{
OutputEvent, OutputEventCategory, Scope, StackFrame, StoppedEvent, ThreadEvent, Variable,
};
Expand All @@ -11,6 +9,7 @@ use gpui::{
actions, list, AnyElement, AppContext, AsyncWindowContext, EventEmitter, FocusHandle,
FocusableView, ListState, Subscription, View, WeakView,
};
use std::collections::HashMap;
use std::sync::Arc;
use ui::{prelude::*, Tooltip};
use ui::{ListItem, WindowContext};
Expand All @@ -23,13 +22,24 @@ enum ThreadItem {
Output,
}

#[derive(Debug, Clone)]
pub enum ThreadEntry {
Scope(Scope),
Variable {
depth: usize,
variable: Variable,
has_children: bool,
},
}

pub struct DebugPanelItem {
thread_id: u64,
variable_list: ListState,
focus_handle: FocusHandle,
stack_frame_list: ListState,
output_editor: View<Editor>,
collapsed_variables: Vec<SharedString>,
stack_frame_entries: HashMap<u64, Vec<ThreadEntry>>,
active_thread_item: ThreadItem,
client: Arc<DebugAdapterClient>,
_subscriptions: Vec<Subscription>,
Expand Down Expand Up @@ -109,6 +119,7 @@ impl DebugPanelItem {
output_editor,
_subscriptions,
stack_frame_list,
stack_frame_entries: Default::default(),
collapsed_variables: Default::default(),
active_thread_item: ThreadItem::Variables,
}
Expand All @@ -135,9 +146,9 @@ impl DebugPanelItem {
let thread_state = this.current_thread_state();

this.stack_frame_list.reset(thread_state.stack_frames.len());
if let Some(stack_frame_id) = thread_state.stack_frames.first().map(|s| s.id) {
this.update_stack_frame_id(stack_frame_id);
this.build_variable_list_entries(stack_frame_id);
if let Some(stack_frame) = thread_state.stack_frames.first() {
this.update_stack_frame_id(stack_frame.id);
this.build_variable_list_entries(stack_frame);
};

cx.notify();
Expand Down Expand Up @@ -265,10 +276,9 @@ impl DebugPanelItem {
ix: usize,
cx: &mut ViewContext<Self>,
) -> AnyElement {
let thread_state = self.current_thread_state();
let Some(entries) = thread_state
let Some(entries) = self
.stack_frame_entries
.get(&thread_state.current_stack_frame_id)
.get(&self.current_thread_state().current_stack_frame_id)
else {
return div().into_any_element();
};
Expand Down Expand Up @@ -425,13 +435,31 @@ impl DebugPanelItem {
.into_any()
}

pub fn build_variable_list_entries(&mut self, stack_frame_id: u64) {
pub fn build_variable_list_entries(&mut self, stack_frame: &StackFrame) {
let thread_state = self.current_thread_state();
let Some(entries) = thread_state.stack_frame_entries.get(&stack_frame_id) else {

let Some(scopes_and_vars) = thread_state.variables.get(stack_frame) else {
return;
};

self.variable_list.reset(entries.len());
let mut entries: Vec<ThreadEntry> = Vec::default();

for (scope, variables) in scopes_and_vars {
entries.push(ThreadEntry::Scope(scope.clone()));

for (depth, variable) in variables {
entries.push(ThreadEntry::Variable {
depth: *depth,
variable: variable.clone(),
has_children: variable.variables_reference > 0,
});
}
}

let len = entries.len();
self.stack_frame_entries.insert(stack_frame.id, entries);

self.variable_list.reset(len);
}

// fn render_scopes(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
Expand Down Expand Up @@ -636,7 +664,8 @@ impl DebugPanelItem {
}
};

self.build_variable_list_entries(self.current_thread_state().current_stack_frame_id);
// TODO:
// self.build_variable_list_entries(self.current_thread_state().current_stack_frame_id);

cx.notify();
}
Expand Down

0 comments on commit 05b475a

Please sign in to comment.