Class: Musa::Sequencer::BaseSequencer::PlayControl
- Inherits:
-
EventHandler
- Object
- EventHandler
- Musa::Sequencer::BaseSequencer::PlayControl
- Defined in:
- lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb
Overview
Control object for play operations.
Manages play lifecycle including pause/continue and after callbacks. Extends EventHandler to support custom events and hierarchical control.
Pause/Continue
When paused:
- Stores continuation parameters (series state, evaluator, etc.)
- Stops processing series
- Awaits continue call
When continued:
- Restores continuation parameters
- Resumes play from stored position
After Callbacks
Executed after play completes, with optional delay in bars.
This is what #play RETURNS, so stop, after, on_stop,
pause and continue are the caller's handle on a running serie. Only its
construction is internal.
Instance Attribute Summary collapse
-
#do_after ⇒ Array<Hash>
readonly
After callbacks with delays (only on natural termination).
-
#do_on_stop ⇒ Array<Proc>
readonly
Callbacks when play stops (any reason, including manual stop).
Instance Method Summary collapse
-
#_finished!(sequencer, position) ⇒ void
private
Records that the play has ended, and where.
-
#after(bars = nil) { ... } ⇒ void
private
Registers callback to execute after play completes naturally (series exhausted).
-
#continue ⇒ void
Resumes a paused serie from where it stopped.
-
#initialize(parent, on_stop: nil, after_bars: nil, after: nil) ⇒ PlayControl
constructor
private
Creates play control with optional callbacks.
-
#on_stop { ... } ⇒ void
private
Registers callback for when play stops (any reason, including manual stop).
-
#pause ⇒ void
Suspends the serie where it is, keeping its place.
-
#store_continuation(sequencer:, serie:, neumalang_context:, mode:, decoder:, play_eval:, mode_args:) ⇒ void
private
Stores state for continue operation.
Constructor Details
#initialize(parent, on_stop: nil, after_bars: nil, after: nil) ⇒ PlayControl
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creates play control with optional callbacks.
301 302 303 304 305 306 307 308 309 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 301 def initialize(parent, on_stop: nil, after_bars: nil, after: nil) super parent @do_on_stop = [] @do_after = [] @do_on_stop << on_stop if on_stop after(, &after) if after end |
Instance Attribute Details
#do_after ⇒ Array<Hash> (readonly)
Returns after callbacks with delays (only on natural termination).
291 292 293 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 291 def do_after @do_after end |
#do_on_stop ⇒ Array<Proc> (readonly)
Returns callbacks when play stops (any reason, including manual stop).
289 290 291 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 289 def do_on_stop @do_on_stop end |
Instance Method Details
#_finished!(sequencer, position) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Records that the play has ended, and where.
Only the termination branch of _play calls this. It exists because the
control can reach the caller already dead -- see #after.
406 407 408 409 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 406 def _finished!(sequencer, position) @finished_sequencer = sequencer @finished_at = position end |
#after(bars = nil) { ... } ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Registers callback to execute after play completes naturally (series exhausted). Not called on manual stop.
424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 424 def after( = nil, &block) ||= 0 # Already over: `after(2)` means "two bars after it ends", and it ended # at @finished_at, so that is where this goes. Registering it in the # list would be registering it after the only moment anything reads the # list, which is what used to happen to every play that resolved within # one instant -- a chord written as a serie of `forward_duration: 0` # elements, a lone event with no duration -- and the callback simply # never ran (issue #84). return @finished_sequencer.at(@finished_at + .rationalize, &block) if @finished_at @do_after << { bars: .rationalize, block: block } end |
#continue ⇒ void
This method returns an undefined value.
Resumes a paused serie from where it stopped.
375 376 377 378 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 375 def continue super @continuation_sequencer&.continuation_play(@continuation_parameters) end |
#on_stop { ... } ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Registers callback for when play stops (any reason, including manual stop).
387 388 389 390 391 392 393 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 387 def on_stop(&block) # Already over: on_stop means "when it terminates", and it has. The # normal path calls these directly too, rather than scheduling them. return block.call if @finished_at @do_on_stop << block end |
#pause ⇒ void
This method returns an undefined value.
Suspends the serie where it is, keeping its place.
Unlike EventHandler#stop, nothing is torn down: the continuation is kept, so
#continue resumes from the next element rather than from the start.
Neither on_stop nor after fires -- a pause is not a termination.
336 337 338 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 336 def pause @paused = true end |
#store_continuation(sequencer:, serie:, neumalang_context:, mode:, decoder:, play_eval:, mode_args:) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Stores state for continue operation.
Saves all parameters needed to resume play from current position. Called automatically by _play when paused.
356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/musa-dsl/sequencer/base-sequencer-implementation-play.rb', line 356 def store_continuation(sequencer:, serie:, neumalang_context:, mode:, decoder:, play_eval:, mode_args:) @continuation_sequencer = sequencer @continuation_parameters = { serie: serie, control: self, neumalang_context: neumalang_context, mode: mode, decoder: decoder, play_eval: play_eval, mode_args: mode_args } end |