last mod: 13-jan-08 sciss
This class is somewhat similar to Updater from the Crucial-library, but with a few extras. It implements the update
method needed to register dependants with objects, so it acts as an observer in the observer software-design pattern, and can also be used in model-view-controller (mvc) design.
When the observed object is issued a changed
message (after its state has been changed in some way) all of its dependants – including the UpdateListener
– are sent the update
message. The UpdateListener
forwards this call to the Function that was passed in its constructor:
UpdateListener.new( <(Function) update>, [ <(Symbol) what> ])
where update
is a Function that will get invoked with the first argument being the UpdateListener
itself, followed by all arguments of the update
call. The optional what
argument is a filter to limit update
forwarding to a specific type of update-message (see below).
When you use this plain constructor, the listener needs to be added as dependant to some object / model, using the addTo( <(Object) object> )
method. As a shorthand, the contructor method
UpdateListener.newFor( <(Object) object>, <(Function) update>, [ <(Symbol) what> ])
can be used. Examples:
s.boot; x = Synth( \default, [ \amp, 0.2 ]); x.register; // now a NodeWatcher will call 'changed' on x // create and add a new UpdateListener that tracks changes of x by printing them // to the post-window: u = UpdateListener.newFor( x, { arg upd, obj ... info; ([ obj ] ++ info).postln }); // isListening reports whether the UpdateListener is still a dependant u.isListening; // --> true x.run( false ); // --> [ Synth("default" : 1000), n_off ] x.run( true ); // --> [ Synth("default" : 1000), n_on ] x.release; // --> [ Synth("default" : 1000), n_end ] u.remove; // removes the dependant from all observed objects u.isListening; // --> false x = Synth( \default, [ \freq, 441, \pan, -1, \amp, 0.2 ]).register; y = Synth( \default, [ \freq, 662, \pan, 1, \amp, 0.2 ]).register; z = Synth( \default, [ \freq, 332, \pan, 0, \amp, 0.2 ]).register; u = UpdateListener({ "update!".postln }); // it is allowed to add the listener to several objects u.addTo( x ); u.addTo( y ); u.addTo( z ); x.free; u.removeFrom( y ); // remove dependant only from y u.isListeningTo( y ); // --> false u.isListeningTo( z ); // --> true y.free; // ... so this will not notify u anymore u.verbose = true; // prints out invocations the post-window (independent of the update function) z.free; u.removeFromAll; // synonym with 'remove'
x = Synth.basicNew( \default ).register; // now a listener that only registers changes of type \n_go: u = UpdateListener.newFor( x, { arg ... args; args.postln }, \n_go ); x.server.listSendMsg( x.newMsg( args: [ \amp, 0.2 ])); x.run( false ); x.run( true ); x.free; u.remove;