Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

More on SigSlot

More about SigSlot:

I've been emailed by a couple of people pointing out to me that the DOM's addEventListener does pretty much the same thing, and this is in part true. If you are dealing only with DOM nodes and care only about pre-defined events that can be generated by them, then addEventListner is the clear winner.

Making the adoption of SigSlot in JS even more difficult, I haven't been able to figure out how to "intercept" the calls of functions in JS (and I'm beginning to think that it's really not possible), and so any SigSlot library in JS will require some alternate means of calling signal functions.

In the case of the NW SigSlot library, it's handled with the sig.emit() method. To emit the signal registered on object foo's bar method, you might have to do the following:


sig.emit(foo.bar, argument1, argument2);

It's not elegant, but it works. C++ implementations of SigSlot (of which there are a few) are able to side-step this problem by using functors (maleable function objects) and/or pre-compilers. Neither of which is available in JS.

So why would I ever choose this over addEventListner? Well, because it's not tied to DOM nodes or DOM events. For instance, consider the following situation:

You have a complex client-side app, multiple form fields depend on each other and you poll the server for updates to some peice of data. Some portions of your data display are derived from values in other portions of the client-side application. So how do you make sure the right objects get updated?

The answer that you'll get 9 times out of 10 includes some monolithic "update" function that knows about all the fields that need to be updated. This is all well and good, but it can turn into a maintenience nightmare very quickly, espcially if the client gets to choose which fields they care about (you know, a useful application). Using signals and slots, you can create an object for each field which has an "update" method that updates ONLY it's value and takes a single input (the value it derives from). Using signals and slots it's possible to chain these objects togeather without each of these object having to know how (or event that) it's value is connected to some other form element's. It simply receives an update signal from the slot that it got registered to.

This is an admittedly simple example, and the value of SigSlot here is marginal, but it's very simple to think up situations where providing dynamic updates to end users can be made a much saner thing to do because of the maintainability gained by decoupling the caller from the called.

Signal Ratio

Last night I checked in our first port of the NW codebase to use signals and slots for almost all event mechanisms. I'm sure someone is going to get rather annoyed that in 3 major releases, we will have changed the event mechanism twice, but I honestly beleive that it's a step and a half in the right direction.

Which begs the question "what in the hell are signals and slots?"

The CS-ish answer to that question is that signals and slots are a mechanism for anonymously connecting function calls. A better explination would be to illustrate signals and slots in terms of a mailing list system. A mailing list system lets people sign up for lists, and when something gets sent to a list everyone that has "subscribed" to the list gets "notified" of the event. Sig-slot works almost exactly the same way, in that I can "connect" to functions or object methods and when I "emit" an event (call the function) everything that's signed up to listen for that event gets told (called with the same arguments).

Ok, but what good is that? Well, for interface development it's very often the case that I want to create a generic widget, for instance a button. When I roll my own button widget and handle all events for the button internally in the button object, I can tie it's behaviours to it's programatic context very tightly, which is to say that when it gets clicked I can tell it to call function foo() without any ambiguity: the button instance keeps an internal table of function pointers that it needs to execute when it gets clicked on and the button instance manages adding and removing pointers from the table with a set of methods which may be specific to the button widget. That's ok, but it requires that the thing connecting to the button be very aware of the interface the the button widget exposes to do this. Whole (sucessful) toolkits have been built this way and there's nothing wrong with it. But it has some obvious drawbacks, not least of which is a lack of consistency.

One way of improving the situation is to provide a more abstract way for two things to connect to each other that's not dependent what two methods are being connected. So when, say the button's onClick() function gets called something else can get notified of that action without having to interface with the button instance directly. In essence, making the connection between the two functions/methods anonymous. Using anonymous connections spares the writers of widgets from writing entire function pointer registration and firing routines which consist of error prone code that may or may not provide a consistent interface. Using sig-slot to implement this anonymous connection provides a rather elegant subscribe-notify model that can be used across an entire class of software, making things consistent and managable for developers.

I'm sure I'll babble more about this soon.

Redeeming

Every now and again you find some redeeming value to the web. This is some of that.

netWindows 0.2.4 Released

0.2.4 is out!! Grab it while it's hot.

Mail App

so I've been spending a bit of quality time with the webmail sample app for netWindows. The big improvements so far have been moving to the new email module in python 2.2 which makes parsing of messages absolute cake. Attachments shouldn't even be that hard...I'm excited = )