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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! Subscription API for the player.
//!
//! A [`PlayerObserver`] is notified every time the player crosses a song-side
//! event boundary: a new row is loaded, a sustained tick fires, the pattern
//! cursor moves to a new entry in the pattern order, or playback ends.
//!
//! The voices engine (the default audio renderer) is registered as an
//! observer internally; any additional observer plugs in next to it via
//! [`crate::xmrsplayer::XmrsPlayer::add_observer`].
//!
//! Observers are called **synchronously** on the thread that drives sample
//! generation. Long-running work or I/O must be deferred (push to a channel
//! drained elsewhere) — otherwise it will stall audio. See `OBSERVERS.md`
//! for the detailed threading contract and recipes.
//!
//! [`PlayerObserver`]: crate::observer::PlayerObserver
use Box;
use Vec;
use ;
use *;
/// Internal wrapper around `Vec<Box<T>>` for boxed-trait-object
/// observer lists. Centralises the four facade quadruplets
/// (`add_X / clear_X / X_count / Vec<Box<dyn _ + Send>>`).
/// Deref/DerefMut expose slice methods (`iter`, `iter_mut`,
/// `is_empty`, `len`) without re-exporting `push` / `clear` —
/// callers go through [`Self::add`] / [`Self::clear`].
pub ;
/// Context passed to [`PlayerObserver::on_row`] when a new row is loaded.
///
/// `cells` is borrowed directly from the module — no allocation, no copy —
/// so observers can inspect per-channel notes/instruments/effects at zero
/// cost.
/// Context passed to [`PlayerObserver::on_tick`] for sustained (non-row-start)
/// ticks. Row-start ticks fire `on_row` instead; they never fire `on_tick`.
/// Context passed to [`PlayerObserver::on_pattern_change`].
///
/// Fired when the pattern-order cursor moves to a new entry — either
/// naturally at end-of-pattern or via a jump effect (`Bxx`, `Dxx`, or a call
/// to [`crate::xmrsplayer::XmrsPlayer::goto`]).
/// A subscriber to player events.
///
/// Implement this trait for anything that wants to react to song progress —
/// a UI highlighting the current note, a MIDI bridge, a recording probe…
///
/// ## `Send` requirement
///
/// Observers are stored as `Box<dyn PlayerObserver + Send>` because the
/// typical deployment pattern — `Arc<Mutex<XmrsPlayer>>` handed to a cpal /
/// rodio audio callback — requires the player (and everything it owns) to
/// be sendable between threads. If your observer holds a `!Send` type
/// (raw pointer, `Rc<_>`, etc.), wrap it in `Arc`/`Mutex` or restructure.
/// `Sync` is not required: callbacks are delivered through `&mut self`
/// from a single thread at a time (the one holding the mutex).
///
/// ## Required vs. optional methods
///
/// [`on_row`](Self::on_row) is the only mandatory callback; all others have
/// defaulted no-op bodies, so a typical observer only needs to implement
/// `on_row`.
///
/// ## Opting into ticks
///
/// `on_tick` fires roughly 50 times per second — pointless for most UI use
/// cases. Observers that only care about row changes must leave
/// [`subscribes_to_ticks`](Self::subscribes_to_ticks) at its default `false`
/// value; the player gates `on_tick` delivery on that flag.
///
/// Observers that legitimately need tick-level granularity (per-tick visual
/// effects, vibrato visualisers, etc.) override it to return `true`.
///
/// ## Threading
///
/// Every method runs on the thread that pulls samples from the player. Do
/// not block, allocate on hot paths, or do I/O — push events to a queue
/// drained elsewhere. See `OBSERVERS.md` for concrete patterns.