Skip to content

Commit

Permalink
Implement debug_paint toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
itome committed Jun 3, 2024
1 parent 81ac871 commit 3c6d4d9
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 0 deletions.
7 changes: 7 additions & 0 deletions crates/devtools/src/protocols/flutter_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use color_eyre::Result;
use futures::Future;
use serde::{Deserialize, Serialize};

use crate::util::{deserialize_bool_from_string, serialize_bool_to_string};

pub trait FlutterExtensionProtocol {
fn list_views(&self) -> impl Future<Output = Result<FlutterViewList>> + Send;

Expand Down Expand Up @@ -417,6 +419,11 @@ pub struct IsolateRefInFlutterExtension {
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Togglable {
pub r#type: String,
// This is a bool but it is represented as a string in the response
#[serde(
deserialize_with = "deserialize_bool_from_string",
serialize_with = "serialize_bool_to_string"
)]
pub enabled: bool,
pub method: String,
}
Expand Down
26 changes: 26 additions & 0 deletions crates/devtools/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use serde::{de, Serializer};

#[macro_export]
macro_rules! params {
( $( $k:expr => $v:expr ),* ) => {
Expand All @@ -12,3 +14,27 @@ macro_rules! params {
params! { $( $k => $v ),* }
};
}

pub(crate) fn deserialize_bool_from_string<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: de::Deserializer<'de>,
{
let s: &str = de::Deserialize::deserialize(deserializer)?;

match s {
"true" => Ok(true),
"false" => Ok(false),
_ => Err(de::Error::unknown_variant(s, &["true", "false"])),
}
}

pub(crate) fn serialize_bool_to_string<S>(b: &bool, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if *b {
serializer.serialize_str("true")
} else {
serializer.serialize_str("false")
}
}
9 changes: 9 additions & 0 deletions src/components/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ impl AppComponent {
.send(ThunkAction::HotRestart.into())?;
Ok(())
}

fn toggle_debug_paint(&self) -> Result<()> {
self.action_tx
.as_ref()
.ok_or_else(|| eyre!("action_tx is None"))?
.send(ThunkAction::ToggleDebugPaint.into())?;
Ok(())
}
}

impl Component for AppComponent {
Expand All @@ -57,6 +65,7 @@ impl Component for AppComponent {
match key.code {
KeyCode::Char('r') => self.hot_reload()?,
KeyCode::Char('R') => self.hot_restart()?,
KeyCode::Char('p') => self.toggle_debug_paint()?,
_ => {}
}
Ok(())
Expand Down
25 changes: 25 additions & 0 deletions src/redux/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,29 @@ pub enum Action {

EnterNetworkRequest,
ExitNetworkRequest,

SetDebugPaintEnabled {
session_id: String,
enabled: bool,
},
SetSlowAnimationsEnabled {
session_id: String,
enabled: bool,
},
SetDebugPaintBaselinesEnabled {
session_id: String,
enabled: bool,
},
SetRepaintRainbowEnabled {
session_id: String,
enabled: bool,
},
SetInvertOversizedImagesEnabled {
session_id: String,
enabled: bool,
},
SetShowPerformanceOverlayEnabled {
session_id: String,
enabled: bool,
},
}
120 changes: 120 additions & 0 deletions src/redux/reducer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1180,5 +1180,125 @@ pub fn reducer(state: State, action: Action) -> State {
focus: Focus::DevTools(DevTools::Inspector),
..state
},
Action::SetDebugPaintEnabled {
session_id,
enabled,
} => State {
sessions: state
.sessions
.into_iter()
.map(|s| {
if s.id == session_id {
SessionState {
debug_paint_enabled: enabled,
..s
}
} else {
s
}
})
.collect(),
..state
},
Action::SetSlowAnimationsEnabled {
session_id,
enabled,
} => State {
sessions: state
.sessions
.into_iter()
.map(|s| {
if s.id == session_id {
SessionState {
slow_animations_enabled: enabled,
..s
}
} else {
s
}
})
.collect(),
..state
},
Action::SetDebugPaintBaselinesEnabled {
session_id,
enabled,
} => State {
sessions: state
.sessions
.into_iter()
.map(|s| {
if s.id == session_id {
SessionState {
debug_paint_baselines_enabled: enabled,
..s
}
} else {
s
}
})
.collect(),
..state
},
Action::SetRepaintRainbowEnabled {
session_id,
enabled,
} => State {
sessions: state
.sessions
.into_iter()
.map(|s| {
if s.id == session_id {
SessionState {
repaint_rainbow_enabled: enabled,
..s
}
} else {
s
}
})
.collect(),
..state
},
Action::SetInvertOversizedImagesEnabled {
session_id,
enabled,
} => State {
sessions: state
.sessions
.into_iter()
.map(|s| {
if s.id == session_id {
SessionState {
invert_oversized_images_enabled: enabled,
..s
}
} else {
s
}
})
.collect(),
..state
},
Action::SetShowPerformanceOverlayEnabled {
session_id,
enabled,
} => State {
sessions: state
.sessions
.into_iter()
.map(|s| {
if s.id == session_id {
SessionState {
show_performance_overlay_enabled: enabled,
..s
}
} else {
s
}
})
.collect(),
..state
},
}
}
7 changes: 7 additions & 0 deletions src/redux/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ pub struct SessionState {
pub selected_widget_object_group: Option<String>,
pub selected_widget_details_tree: Option<DiagnosticNode>,
pub opened_widget_details_value_ids: HashSet<String>,

pub debug_paint_enabled: bool,
pub slow_animations_enabled: bool,
pub debug_paint_baselines_enabled: bool,
pub repaint_rainbow_enabled: bool,
pub invert_oversized_images_enabled: bool,
pub show_performance_overlay_enabled: bool,
}

#[derive(Default, Clone, PartialEq, Eq)]
Expand Down
5 changes: 5 additions & 0 deletions src/redux/thunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod load_vscode_launch_setting;
pub mod run_new_app;
pub mod run_new_vm_service;
pub mod stop_app;
pub mod toggle_debug_paint;
pub mod watch_devices;
pub mod watch_frames;
pub mod watch_requests;
Expand All @@ -39,6 +40,7 @@ pub enum ThunkAction {
HotReload,
HotRestart,
StopApp,
ToggleDebugPaint,
}

pub fn thunk_impl<Api>(
Expand Down Expand Up @@ -78,5 +80,8 @@ where
ThunkAction::LoadDetailsSubtree { value_id } => Box::new(
load_details_subtree::LoadDetailsSubtreeThunk::new(context, value_id),
),
ThunkAction::ToggleDebugPaint => {
Box::new(toggle_debug_paint::ToggleDebugPaintThunk::new(context))
}
}
}
69 changes: 69 additions & 0 deletions src/redux/thunk/toggle_debug_paint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use async_trait::async_trait;
use color_eyre::eyre::Result;
use std::{sync::Arc, time::Duration};

use redux_rs::{middlewares::thunk::Thunk, StoreApi};

use crate::redux::{
action::Action,
selector::current_session::current_session_selector_cloned,
state::{SessionState, State},
};

use devtools::{
protocols::{flutter_extension::FlutterExtensionProtocol, vm_service::VmServiceProtocol},
vm_service::VmService,
};

use super::context::Context;

pub struct ToggleDebugPaintThunk {
context: Arc<Context>,
}

impl ToggleDebugPaintThunk {
pub fn new(context: Arc<Context>) -> Self {
Self { context }
}
}

#[async_trait]
impl<Api> Thunk<State, Action, Api> for ToggleDebugPaintThunk
where
Api: StoreApi<State, Action> + Send + Sync + 'static,
{
async fn execute(&self, store: Arc<Api>) {
let Some(SessionState {
id: session_id,
debug_paint_enabled,
..
}) = store.select(current_session_selector_cloned).await
else {
return;
};

let Some(session) = self.context.manager.session(session_id.clone()).await else {
return;
};
let vm_service = &session.vm_service;

let Ok(vm) = vm_service.get_vm().await else {
return;
};
let Some(main_isolate) = vm.isolates.iter().find(|isolate| isolate.name == "main") else {
return;
};

if let Ok(togglable) = vm_service
.debug_paint(&main_isolate.id, Some(!debug_paint_enabled))
.await
{
store
.dispatch(Action::SetDebugPaintEnabled {
session_id,
enabled: togglable.enabled,
})
.await;
}
}
}

0 comments on commit 3c6d4d9

Please sign in to comment.