Multiple Observers of an Event

Hi, I’m new to Xojo and I am impressed so far!

Coming from an object-oriented background I was please to see classes, class methods (shared methods), class properties (shared properties), instance methods, instance properties, subclassing, polymorphism, etc.

However, when it comes to events I am pulling my hair out, and I don’t have much to spare :slight_smile:

I have created a class (not a subclass of anything) and I want to trigger events and have multiple observers listen in on those events.

My class defines the events and uses RaiseEvent to trigger them. So far so good.

My first observer worked OK, using AddHandler to handle the events… doing well.

Unfortunately my second observer can’t handle the events as it seems you cannot have more than one AddHandler on an event. If I try this I get the following RuntimeException…

Attempting to add a handler for an event that was already handled.

I spent a long time reading and it seems that Xojo events are not like OO events, so I am puzzled what to do.

I started writing my own event system with an EventDispatcher but stopped half way - surely it is easier than this and my lack of knowledge and failure to find the right solution while researching had made me miss it - right?

Any pointers would be very welcome. Many thanks.

Did you have a look at the Observer pattern example which is included? I think your solution might be interfaces but then I’m not an OOP specialist …

You could also have a look at the Design Pattern webinar

http://www.xojo.com/support/webinar.php#archives

Instead of using AddHandler, you could subclass the control to store an array of an interface that you iterate through in the event.

[quote=111014:@Chris Copleston]Hi, I’m new to Xojo and I am impressed so far!

Coming from an object-oriented background I was please to see classes, class methods (shared methods), class properties (shared properties), instance methods, instance properties, subclassing, polymorphism, etc.

However, when it comes to events I am pulling my hair out, and I don’t have much to spare :slight_smile:

I have created a class (not a subclass of anything) and I want to trigger events and have multiple observers listen in on those events.

My class defines the events and uses RaiseEvent to trigger them. So far so good.

My first observer worked OK, using AddHandler to handle the events… doing well.

Unfortunately my second observer can’t handle the events as it seems you cannot have more than one AddHandler on an event. If I try this I get the following RuntimeException…

Attempting to add a handler for an event that was already handled.

I spent a long time reading and it seems that Xojo events are not like OO events, so I am puzzled what to do.

I started writing my own event system with an EventDispatcher but stopped half way - surely it is easier than this and my lack of knowledge and failure to find the right solution while researching had made me miss it - right?

Any pointers would be very welcome. Many thanks.[/quote]

Events are basically a way to implement “chain of responsibility” not observers

If you look in the example projects you’ll find a sample that shows the Observer pattern in Xojo

You could use Delegates for this. With a for loop and array of delegates you could invoke the methods you want called by the event. A quick example of delegate use:

Wow, I think I have just found the best thing about Xojo - the community!!! Many thanks for your thoughts, links and ideas. I’ve spent today going through your posts, examples and reading / watching the links.

Hi Markus and Norman
I can see how an Observer Pattern would work but as far as I can see you have to effectively write your own event dispatcher for every object you want to trigger events from. I would really like a generic solution that anything can use (“write once, use many” being the mantra of OO).

Hi Karen
Subclassing a control is not an option here because these are not controls, they are my own non-GUI classes. Sorry if I didn’t make that clear enough.

Hi Jason
Delegates really got me thinking. I actually think they should play a part in my solution below, but currently aren’t. Your suggestion got me on the right track though…

I’ve created an EventManager to add to the mix (project link below).

I would love it if you could give me some feedback on this before I go any further. Be ruthless, I am new at this and it is bound to be wrong, inefficient, cause garbage collection issues, etc.

To keep the syntax simple, you drive it with two class methods, one to observe and one to trigger events…

[h]To observe…[/h]

EventManager.when(anObject, "eventname", self, "methodname")

[h]To trigger…[/h]

EventManager.trigger(self, "eventname")

It works by recording handlers as Introspection.MethodInfo’s and invoking them when a subject triggers an event.

There is a TestWindow in the project. App.guy is a single instance of class Person. Each TestWindow displays App.guy’s age. The “Have a Birthday” button in each window causes App.guy to increment his age which triggers an “ageChanged” event. Since all the TestWindows are observing this event, they update their displayed age - no matter what window you click the “Have a Birthday” button within.

[h]What’s missing[/h]

  1. If you experts think this is going in the right direction, I would like to work out how arguments could be passed when triggering events and how these can be forwarded to handlers.

  2. A way to un-observe events

  3. A way to suspend events

  4. A way to check if an Object is being observed

  5. A way to check if an Object is observing

  6. Add a “handle once” option when registering an observer. This can be useful if events fire quickly and you are only interested in one.

  7. A way for a handler to veto any default action in the subject

[h]Project with Example[/h]
Needless to say if anyone finds anything remotely useful in here they are welcome to use or modify it as they see fit.

https://app.box.com/s/nru9hsabgykhkg6jtkh7

[quote=111342:@Chris Copleston]Wow, I think I have just found the best thing about Xojo - the community!!! Many thanks for your thoughts, links and ideas. I’ve spent today going through your posts, examples and reading / watching the links.

Hi Markus and Norman
I can see how an Observer Pattern would work but as far as I can see you have to effectively write your own event dispatcher for every object you want to trigger events from. I would really like a generic solution that anything can use (“write once, use many” being the mantra of OO).
[/quote]
Quite possible
But events & add handler are the wrong Xojo mechanism for this
Really

[quote=111342:@Chris Copleston]Wow, I think I have just found the best thing about Xojo - the community!!! Many thanks for your thoughts, links and ideas. I’ve spent today going through your posts, examples and reading / watching the links.

Hi Markus and Norman
I can see how an Observer Pattern would work but as far as I can see you have to effectively write your own event dispatcher for every object you want to trigger events from. I would really like a generic solution that anything can use (“write once, use many” being the mantra of OO).
[/quote]
No but the example is kept deliberately simpler to make the example code clearer.
You could have a single dispatcher that holds on to lists of what is being observed by whom and anything being observed then just tells the dispatcher to notify all observers. That way each observed object doesn’t really have to notify or hold on to lists of what is observing it.
It’s definitely not set up so observers can register for single “events” but for a notification on any change which is apparently quite different from how you’re approaching this.

You could set up something like that with whats there BUT now every object that wants to observe another has to know what events might be sent by the object being observed, what method signature it needs in order to receive the event and the level of internal knowledge has gone way up and you’ll be far more tightly coupled than I think you really want.

And don’t get hung up on the term “events” - as Xojo’s are definitely NOT like anything you’ve used elsewhere

Thanks Norman - I really appreciate your feedback.

My EventManager is kind of doing this - but segmented by “eventname”. I get that “Xojo Events” are not events that I am familiar with. Perhaps my EventManager should be renamed to avoid confusion - Notifier perhaps.

A fair point, but the observer is typically more intelligent than the subject. It will know what the subject is, what events it is interested in and how to handle them. An object might trigger events at different times and frequencies. Having a single “update” Dispatcher doesn’t allow an observer to control the granularity of the “events” it needs to observe. This might mean too many notifications and unnecessary processing.

I agree though that eventnames as I have them are too loose, there is no formal definition that observers can review and the EventManager can police.

An OO paradigm would solve this by implementing a method: Object class > supportedEvents. In Object it might only return a changed event. Subclasses could extend or override the supportedEvents. The EventManager would then only let you observe or trigger supported events. Observers could observe the generic “changed” event if they didn’t want to be closely coupled to the subject (your point). I have no idea if you can do this kind of thing in Xojo, but if you can’t add methods to Object class, an interface could ensure a subject (something that triggers events) implements suportedEvents.

The supportedEvents method could not only define the supported events, but their signature as well (or perhaps Introspection can reveal this). I’m too new to Xojo to know how to map this through to Introspection.MethodInfo.invoke though.

Perhaps

If a subject has a means of telling any observers what changed then a “changed” notification is possibly sufficient.
Then the observer can determine if the change is / is not one that it cares about - which is where you probably want the knowledge instead of in the subject.

[quote=111381:@Chris Copleston]I agree though that eventnames as I have them are too loose, there is no formal definition that observers can review and the EventManager can police.
[/quote]
I’d use interfaces so there is some level of enforceable contract

If subjects implement an interface then you can enforce that there is at least the method (empty or not)
It can be called although its not required to DO anything (there may be no code in the method)
Thats roughly how the example I pointed out uses interfaces.
Not sure what language you’re coming from - but in C++ an interface is roughly a pure abstract base class.
It’s a new type that you can be sure that any implementer has those methods - although they are not required to provide any body to the implementation.

You can add methods to classes - but you can’t add methods to a base class since you don’t have the source code to do that.
However you MIGHT want to look into “Extends”
Syntactically these look like new methods on already existing classes

[/quote]
Personally I’d use an interface, or several, and skip introspection entirely.
I think you’d find it a lot less frustrating trying to figure out how to marshall any parameters to methods to be invoked.
And overall you’d be less tightly coupled.

Thanks Norman, I will look into extends.

I completely agree that a subject should have no knowledge of its observers (encapsulation).

However, for me my notification system should be scaleable and that means not sending notifications to objects that don’t want them. It’s a good idea to take a model to extremes and stress test it at design time to evaluate scalability…

Lets say we have a Clock class. Its instances notify observers every time a minute has passed. It also has a property of timezone. Then we create a view that displays the hours:minutes of a clock. It does this for every timezone (about 25 of them), so there are 25 instances of Clock.

Now we create a subclass of Clock called AccurateClock. Its fundamentally the same but its accuracy goes down to milliseconds.

We also enhance our view so the user can opt to see milliseconds and/or seconds for each timezone. The user opts to make one timezone display seconds and another timezone to display both seconds and milliseconds. The remaining 23 continue to display hours:minutes.

If our clock simply broadcasts an update notification, all the clocks in our view would receive millisecond updates, when only one of them needed this level of notification granularity. When timezones receive all these notifications they either have to refresh the view regardless or work out if it is interested in the update - perhaps by holding state between updates for comparison. Thats a lot of processing to handle unwanted notifications.

With 25 timezones * (1000 milliseconds per second * 60 seconds per minute) that’s 1,500,000 notification per minute.

It would be far better and more scaleable if observers were only notified about things they are interested in. In our example, 23 timezones are only interested when the minute changes, 1 is interested when the seconds change and 1 is interested when the milliseconds change.

To get this event granularity, our AccurateClock would need to trigger separate notifications for minutesChanged, secondsChanged and millisecondsChanged.

This would dramatically reduce the unnecessary notifications and their subsequent processing…

(23 timezones with minute accuracy: 231 = 23 per minute) + (1 timezone with second accuracy: 60 per minute) + (1 timezone with millisecond accuracy: 100060= 60,000 minute) = 60,083 notifications per minute. That’s a saving of 14,939,917 notifications per minute.

You could argue this is an extreme or impractical example, but I can’t see the point of having one notification system then another when it has to be scaleable. Simple code today might have to be scalable tomorrow, patricianly in code reuse.

[quote]Personally I’d use an interface, or several, and skip introspection entirely.
I think you’d find it a lot less frustrating trying to figure out how to marshall any parameters to methods to be invoked.
And overall you’d be less tightly coupled.[/quote]

Unless I am missing something (quite possible), it seems interfaces can only declare instance methods and not class (shared) methods. “suportedNotifications” feels more like a class thing. I think I will look into using inheritance and polymorphism instead. If extends works out, Object could define a single supportedNotifications declaration of “changed”. That way all classes will respond to supportedNotifications without having to implement it. Of course they don’t need to trigger any notifications, but they could if they wanted to. Classes could extend or override supportedEvents for more notification granularity, subclasses will inherit their super classes supportedNotifications and notification would all flow though one, scalable solution.

Along the way I will drop references to event and use notification instead, to avoid confusion.

Thanks for all your help!

I will post whatever I produce here in case someone else finds it useful.

Sorry, I hit post before proof reading by mistake. I don’t think I can edit posts.

The message saving would be 1,439,917 not 14,939,917.

I have now developed Notifier - a system for subjects to define and trigger notifications that multiple observers can handle.

In the end I used an Interface for subjects which ensures that supported notifications, their arguments and default values are defined.

Already it is proving invaluable in my projects. If anyone else thinks it might be useful you can download it here. The project contains notes and an example.

Is it OK to share this kind of free Add-On in the Add-Ons section of the forum? I don’t want to step on any toes or break any rules.

I might be wrong but: isn’t an interface basically just a method definition? You inform the observer that an event has occured and the observer does something, but what it does is up to the observer? Like taking time zone into account or not?

As for milliseconds: wouldn’t you be able just to use different interfaces, like InterfaceDateTime and InterfaceDateTimeMilliseconds? Or two implementations of the same interface but with different parameters?

I’m a little late in seeing this discussion, but sometime ago I created a very simple synchronous event bus that might be of use to those interested in this area. It’s not a perfect fit for the discussed problem because you have to use a very specific method (implemented as an “Extends” on Object) to raise events rather than use the built in RaiseEvent, but for simple projects it works quite well.

https://github.com/ianmjones/EventBusIJ

There are a couple of example projects too…

https://github.com/ianmjones/EventBusIJ_DesktopExample
https://github.com/ianmjones/EventBusIJ_WebExample

Hi Markus,
Yes an interface is just a way to check at compile time you have implemented the methods you should. My clock example was just a way to illustrate that “spamming” observers with a generic update message and have them filter the wheat from the chaff is not very scaleable.

As you say, you could have multiple interfaces and send different messages but what I am trying to address is the issue of who should manage the observers and dispatch the messages. Coming from a pure OO background, in my view it shouldn’t be a clock, which is a small class with a simple purpose. Equally it is quite a chore and prolific replication of code if you have to write a purpose built dispatcher and interface for everything that just wants to send notifications in case some code in the future might be interested (in my view a key part of maximising code reuse).

My notifier is a generic observer manager and message dispatcher. Observers can subscribe to an object’s supported notifications with one line of code and unsubscribe with another. They can also unsubscribe from everything (great for Deconstructors or when widows close). Subjects can define in one easily readable place what notifications it supports with a single method and trigger events with a single line of code. They don’t have to care if anyone is listening and they don’t have to manage observers and dispatch notifications.

This was born from Xojo events not supporting multiple handlers.

Hi Ian,
This looks really interesting and I can see you were solving the same problem. Is there a single place an object can define its supported events? I felt this was quite important based on one of Norman’s comments above, mainly so notifications can be policed and can be easily seen when writing observers.

If I am reading the code correctly, you also have a single handleEvent method that observers implement. My notifier lets you handle notifications with different methods and signatures so they can receive different arguments sent by different notifications. However you are not using invoke and I am. I don’t know if there is much of a performance hit with this, but my tests seem to perform well.

[quote=112345:@Chris Copleston]Hi Ian,
This looks really interesting and I can see you were solving the same problem. Is there a single place an object can define its supported events? I felt this was quite important based on one of Norman’s comments above, mainly so notifications can be policed and can be easily seen when writing observers. [/quote]

For me it was important that any object could raise an event as and when something interesting happened, and to not have to pre-define the events that were to be raised. If no one is listening then then that is fine, it makes it very quick to to just chuck out debug messages or other notifications without having to worry about the format of the message, which leads to …

… it’s very intentional that there is the requirement to have a HandleEventIJ method on any object that registers itself as a handler of an event with AddEventHandlerIJ. As it is also very intentional that RaiseEventIJ can only have 2 params, the required event name string and an optional variant that can contain anything that might be relevant to the event.

You can accomplish a lot with that kind of setup, and won’t be tempted to keep changing the signature of the event type or proxy method, you raise an event with or with some attached data, and handle all events you subscribe to from one consistently named method, less thinking and reviewing of code required.

Once in HandleEventIJ with your lump of data you can of course branch off to any other method with any signature you like.

In EventBusIJ I’m using weak references when using AddHandler to ensure that an object going out of scope without de-registering doesn’t cause any memory leaks, and there’s a mechanism in place to pro-actively remove those references in the event bus every now and then and when an event is raised but a registered listener has gone away.

It’s an attempt to make it as loosely coupled as possible.

Haven’t done any performance analysis on EventBusIJ myself, but never had any noticeable problems with it.

Thanks Ian. It’s a shame this isn’t built into Xojo, but I think both our approaches have their merits. I still like the idea that subjects register their supported notifications for four reasons…

  1. If I am developing an observer I think it is better to have a definitive list of supported notifications to review rather than looking through the subject’s code to see what it triggers.

  2. It catches typos in notification names when triggering and observing. If they don’t tie up, the handler will not run and that’s a nasty runtime bug to find

  3. Subclasses can inherit their super class supported notifications

  4. I can get a list of supported notifications at runtime - nice for developing a profiler or notification logger or for observing on the fly

I would like to make improvements though. I don’t yet know how to make weak references and I would like the syntax to be cleaner. For example, it is possible to build a constructor like Dictionary has so I don’t have to wrap args in a dictionary?

I would prefer:

new Notification("age" : 0)

Rather than:

new Notification(new Dictionary("age" : 0))

All 4 of your points are perfectly valid, if you’re building something with any meat to it they are all handy for reducing the chances of mistakes.

EventBusIJ is very much for simple apps.

I certainly considered using EventTypes to define what could and couldn’t be raised, helps reduce mistakes and speeds development with auto-complete etc (used them a lot when developing with Adobe Flex), but decided to just keep things as simple and flexible as possible. Your solution sounds a lot more robust.

[quote=112394:@Chris Copleston]I would like to make improvements though. I don’t yet know how to make weak references and I would like the syntax to be cleaner. For example, it is possible to build a constructor like Dictionary has so I don’t have to wrap args in a dictionary?

I would prefer:

new Notification(“age” : 0)
Rather than:

new Notification(new Dictionary(“age” : 0))
[/quote]
Have you looked at the Pair type?