Hi, On Tue, Feb 24, 2009 at 9:03 PM, Havoc Pennington <h...@pobox.com> wrote: > eggdbusnametracker
Another thing I just noticed in here, it looks like when the initial GetNameOwner returns then you aren't emitting the bus-name-gained-owner signal. I'd suggest that bus-name-gained-owner reflect state changes in the *client* knowledge of the owner, not changes in the bus state. When the first GetNameOwner reply arrives, you could emit this. One of the ways the binding can help people write solid async code, instead of driving them to give up and use sync APIs, is strong invariants. An important one is that when you watch a bus name, it's guaranteed that if the name exists your "bus name appeared" callback will be invoked; and that it's guaranteed the appeared/disappeared callbacks alternate. This allows you to write: DBus.session.watch_name("org.gnome.Foo", function (owner) { createProxiesAndStuff(owner); }, function(oldOwner) { proxies = null; }); Rather than: owner = get_name_owner("org.gnome.Foo"); // blocking, yuck if (owner) createProxiesAndStuff(owner); DBus.session.watch_name("org.gnome.Foo"), function (owner) { if (!owner) createProxiesAndStuff(); } }, function (oldOwner) { }); Requiring the synchronous call in front just adds code; if the async API guarantees it will be called, then there's no need for the synchronous init on startup; init is the same as handling of restart. It's the same principle as my suggested unique application API, which has a mostly empty main() and the usual contents of main() go only in the "got unique instance" callback. The same is true of the other async APIs I suggested. The key is the invariant that the callbacks will be called, and that they always alternate, so apps can just put setup and teardown code in those callbacks unconditionally and not have any separate first-time initialization code. With the acquire_name (monitor name ownership) callbacks, if you guarantee that *either* the "got name" or "lost name" callback will be called, and that they will then alternate, there's no need to separately handle never getting the name vs. losing the name at some later point. With strong invariants the only difference from doing things synchronously should be wrapping the init code in a callback, rather than putting it in main(). Other than those extra 4 or 5 lines, there's no penalty to doing the whole initially-create-a-proxy song and dance asynchronously. You could even auto-create / auto-destroy the proxy, like: DBus.session.watch_name_creating_proxy("org.gnome.Foo", function (proxy) { // proxy arrives here with object properties already asynchronously // filled in and unique name owner known }); which is just as easy as the blocking code. Anyway a lot of this thorny stuff can be done for people and gotten right in a shared layer used by all bindings. A key win is to be sure people *only* have to write callbacks, never 1-time initialization code. Callbacks / change monitoring only feel like a burden when they are *extra* code, if they are the *only* code then all they're adding is another level of indentation, and they actually get tested since they run on normal initialization. Havoc _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list