Add parameter to ChangeBroadcaster, ChangeListener

If I didn’t miss something, ChangeBroadcaster currently sends a message with itself as the only parameter. I do have a case where I need to tell listeners about which aspect of an object has changed, rather than just “anything with the object has changed”.

Would it be possible to add a parameter (enum) that could be passed with the change message? Should be pretty simple and not break existing apps.

What’s your use case? If you have subclassed ChangeBroadcaster for just this purpose, why not create your own type of broadcaster/listener? It’s fairly straightforward - you just keep a ListenerList member variable in your broadcaster and use this to dispatch function calls to any registered listeners. This way you get much more fine grained control over what information you can pass around.

Use case is a Synthesizer (embedded in an AudioProcessor) that needs to tell its AudioProcessor about MIDI control messages being received that are supposed to load a different patch, or forward CC (volume, pan) to the appropriate node in an AudioProcessorGraph.

Intercepting these MIDI messages at the AudioProcessorGraph level is not a good option. This would require a redundant deep look into the midi buffer, despite all midi messages already nicely dispatched to the graph nodes and Synthesizers therein, where they can be best filtered by channel and purpose.

I see how creating a subclass would work. Just thought how adding a simple parameter to ChangeBroadcaster would be very helpful for most general use cases.

Another reason why ChangeBroadcaster may be required is that (last time I checked) its notification can be triggered by any thread and always received by the message thread (i.e. it’s asynchronous), whereas the ListenerList only supports synchronous notifications.

@ans, don’t know if that could work for you, but if you need asynchronous notifications then maybe check ActionListener / ActionBroadcaster, you can pass a String along with the notification. Maybe you can convey your notification details there? (not the cleanest solution, but if that works…)

Sorry for my extremely late reply and thanks for your suggestions. Sure, doing your own class is always an option, but isn’t it the main purpose of a framework to minimize these efforts in the first place?

IMO there are already too many broadcasters/listeners for different purposes, which can be confusing. Possibly all of them could be consolidated into a single class, if there was a more general way of passing parameters along with the message. Even a simple bit-masked integer would help a lot.

On a side note, for another project, I implemented a notifier that receives and dispatches messages to any object that expressed interest in notifications of a certain type and origin, synchronously or asynchronously, message thread or directly. This decouples senders from receivers and allows for receivers to express interest in objects that don’t belong to them in any way, or don’t even exist (yet). There’s only one messaging system for all purposes, not only GUI.

The biggest advantage however is that all dependencies of various kinds are expressed in a declarative fashion at a single place. This has been a live saver in a project with 3,000+ classes. No idea how this would translate to C++, though, but maybe a direction worth thinking about.


Also ran into this: whish, too, that ChangeBroadcaster would have a second parameter. That lets you say, what part of your class changed.

Simply use ActionBroadcaster and ActionListener. You can pass a string and then parse it in your listener.

We use it all the time for all kinds of things.

1 Like

I should note that in the meanwhile I came up with a solution that uses Model, Dependent and Aspect for this purpose.

Aspects identify the things that may change with a Model. Aspects are string-like Symbols, which resolve to unique integers at application startup. This effectively makes Symbols an automatically managed global enum.

DEFINE_SYMBOL (Something);
DEFINE_SYMBOL (SomethingElse);
DEFINE_SYMBOL (YetAnotherThing);
model.changed (Something);
model.changed ( { Something, SomethingElse, YetAnotherThing } );

Dependents of a Model implement an update() method which responds to changes selectively by looking into the Aspects.

Symbols are very useful for many other purposes, too (not unlike juce::Identifier).