Skip to content

Commit a5533f5

Browse files
committed
interpreter: Support debug-hooks
1 parent 9942afd commit a5533f5

File tree

5 files changed

+68
-2
lines changed

5 files changed

+68
-2
lines changed

internal/interpreter/api.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,12 @@ impl ComponentInstance {
12901290
d.set_property(comp.borrow(), &name, value)
12911291
}
12921292

1293+
/// Set a callback triggered by `@debug-hook`-ed properties.
1294+
#[cfg(feature = "internal-highlight")]
1295+
pub fn set_debug_hook_callback(&self, observer: Option<crate::debug_hook::DebugHookCallback>) {
1296+
crate::debug_hook::set_debug_hook_callback(observer);
1297+
}
1298+
12931299
/// Set a handler for the callback with the given name. A callback with that
12941300
/// name must be defined in the document otherwise an error will be returned.
12951301
///

internal/interpreter/debug_hook.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright © SixtyFPS GmbH <[email protected]>
2+
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3+
4+
use crate::{eval::ComponentInstance, Value};
5+
6+
use smol_str::SmolStr;
7+
8+
pub type DebugHookCallback = Box<dyn Fn(&str, usize, &crate::Value) -> Value>;
9+
10+
thread_local! { static DEBUG_HOOK_CALLBACK: std::cell::RefCell<Option<DebugHookCallback>> = Default::default(); }
11+
12+
pub(crate) fn set_debug_hook_callback(func: Option<DebugHookCallback>) {
13+
DEBUG_HOOK_CALLBACK.with(|callback| {
14+
*callback.borrow_mut() = func;
15+
})
16+
}
17+
18+
fn find_repeat_count(instance: &ComponentInstance) -> usize {
19+
// FIXME: Do something to find the component's repeated index.
20+
match instance {
21+
ComponentInstance::InstanceRef(_) => 0,
22+
ComponentInstance::GlobalComponent(_) => 0,
23+
}
24+
}
25+
26+
pub(crate) fn debug_hook_triggered(
27+
instance: &ComponentInstance,
28+
id: SmolStr,
29+
value: Value,
30+
) -> Value {
31+
let repeat_count = find_repeat_count(instance);
32+
DEBUG_HOOK_CALLBACK.with(|callback| {
33+
if let Some(callback) = &*callback.borrow() {
34+
callback(id.as_str(), repeat_count, &value)
35+
} else {
36+
value
37+
}
38+
})
39+
}

internal/interpreter/eval.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,13 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon
396396
}
397397
}
398398
Expression::EmptyComponentFactory => Value::ComponentFactory(Default::default()),
399-
Expression::DebugHook { expression, .. } => eval_expression(expression, local_context),
399+
Expression::DebugHook { expression, id: _id } => {
400+
let value = eval_expression(expression, local_context);
401+
#[cfg(feature = "internal-highlight")]
402+
let value = crate::debug_hook::debug_hook_triggered(&local_context.component_instance, _id.clone(), value);
403+
value
404+
405+
}
400406
}
401407
}
402408

internal/interpreter/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ compile_error!(
7979
);
8080

8181
mod api;
82+
#[cfg(feature = "internal-highlight")]
83+
mod debug_hook;
8284
mod dynamic_item_tree;
8385
mod dynamic_type;
8486
mod eval;

tools/lsp/preview.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct PreviewState {
128128
preview_loading_delay_timer: Option<slint::Timer>,
129129
initial_live_data: preview_data::PreviewDataMap,
130130
current_live_data: preview_data::PreviewDataMap,
131+
debug_hook_random_state: std::hash::RandomState,
131132
}
132133

133134
impl PreviewState {
@@ -1296,6 +1297,7 @@ async fn parse_source(
12961297
source_code: String,
12971298
style: String,
12981299
component: Option<String>,
1300+
debug_hook_random_state: std::hash::RandomState,
12991301
file_loader_fallback: impl Fn(
13001302
String,
13011303
) -> core::pin::Pin<
@@ -1331,6 +1333,9 @@ async fn parse_source(
13311333
cc.include_paths = include_paths;
13321334
cc.library_paths = library_paths;
13331335

1336+
cc.debug_info = true;
1337+
cc.debug_hooks = Some(debug_hook_random_state);
1338+
13341339
let (open_file_fallback, source_file_versions) =
13351340
common::document_cache::document_cache_parts_setup(
13361341
cc,
@@ -1353,7 +1358,12 @@ async fn reload_preview_impl(
13531358
) -> Result<(), PlatformError> {
13541359
start_parsing();
13551360

1356-
if let Some(component_instance) = component_instance() {
1361+
let (component_instance, debug_hook_random_state) = PREVIEW_STATE.with(|preview_state| {
1362+
let preview_state = preview_state.borrow();
1363+
(preview_state.component_instance(), preview_state.debug_hook_random_state.clone())
1364+
});
1365+
1366+
if let Some(component_instance) = component_instance {
13571367
let live_preview_data =
13581368
preview_data::query_preview_data_properties_and_callbacks(&component_instance);
13591369
set_current_live_data(live_preview_data);
@@ -1370,6 +1380,7 @@ async fn reload_preview_impl(
13701380
source,
13711381
style,
13721382
component.component.clone(),
1383+
debug_hook_random_state,
13731384
move |path| {
13741385
let path = path.to_owned();
13751386
Box::pin(async move {
@@ -1897,6 +1908,7 @@ pub mod test {
18971908

18981909
let path = main_test_file_name();
18991910
let source_code = code.get(&path).unwrap().clone();
1911+
let debug_hook_random_state = std::hash::RandomState::default();
19001912
let (diagnostics, component_definition, _, _) = spin_on::spin_on(super::parse_source(
19011913
vec![],
19021914
std::collections::HashMap::new(),
@@ -1905,6 +1917,7 @@ pub mod test {
19051917
source_code.to_string(),
19061918
style.to_string(),
19071919
None,
1920+
debug_hook_random_state,
19081921
move |path| {
19091922
let code = code.clone();
19101923
let path = PathBuf::from(&path);

0 commit comments

Comments
 (0)