1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use *;
/// Returns the current wall-clock time, in milliseconds.
///
/// On `wasm32` targets this is a thin wrapper around
/// [`js_sys::Date::now`] (which itself doubles as
/// `performance.now()`-based input if the browser exposes one).
/// Returns a `f64` because the upstream JavaScript value is also
/// `f64` and rounding to integer milliseconds throws away the
/// sub-millisecond precision the profiler relies on.
///
/// On native targets (`std::time::SystemTime` is available) we
/// fall back to system wall-clock time so the profiler's
/// `measure` / `begin` / `end` code paths — and the host-side
/// unit tests that exercise them — never invoke `js_sys::*`,
/// which would `SIGABRT` with "cannot call wasm-bindgen imported
/// functions on non-wasm targets". The two return values are not
/// bit-identical (the wasm path is monotonic since the JS context
/// was created; the native path uses UNIX epoch ms and may go
/// backwards if the system clock is adjusted), but every test
/// assertion on the native path is `>=`/`>`, which both
/// implementations satisfy in steady state.
///
/// The function is `pub(crate)` because the only intended consumer
/// lives in the same crate (the profiler's `measure` / `begin` /
/// `end` paths); downstream code does not need to call it directly.
///
/// # Returns
///
/// - `f64` - The current wall-clock time, in milliseconds.
/// Obtains a `ProfilerHandle` registered against the current hook context slot.
///
/// Behaves like `HookContext::use_hook`: the same `ProfilerHandle`
/// is returned on every render at the same hook index, so
/// measurements pushed onto its entries signal remain visible
/// across renders.
///
/// Use [`ProfilerHandle::measure`] for a single-shot
/// "label + closure" form or [`ProfilerHandle::begin`] /
/// [`ProfilerHandle::end`] for the split-timer form. Reads of
/// [`ProfilerHandle::entries`] inside a render closure subscribe
/// the render to new entries.
///
/// # Returns
///
/// - `ProfilerHandle` - The profiler handle.
/// Returns the factory result directly when no hook context is
/// active (e.g. when called outside a render cycle).
/// Runs `body` and records the elapsed time under `label`.
///
/// Convenience helper that pairs with `App::use_interval`-style
/// re-renders: any render closure can call `profiler_measure(label, ...)`
/// on its hot path and the result lands in the same `ProfilerHandle`'s
/// entries signal.
///
/// # Arguments
///
/// - `&str` - The free-form label that identifies this measurement.
/// - `F: FnOnce() -> R` - The closure whose execution time is
/// measured.
///
/// # Returns
///
/// - `R` - The closure's return value, unchanged.