Some snips from my diff:
+ self.connect('destroy', setattr, self.controller, 'addBuddy', None)
Silly one. I learnt this with the one-line version of eval (before the multiline version replaced it, i had some fun with setattr, __import__, and/or to chain expressions, etc)
+ def safeADL(chunk, next):
+ self.socket.sendPayloadCommand( "ADL", '', chunk )
+ gobject.timeout_add(1000, gobject.idle_add, safeADL, \
+ next.pop(0), next)
+
+ ADLChunks = self.contactManager.getADL()
+ safeADL(ADLChunks.pop(0), ADLChunks)
I thought
"ok, i have to implement yet another «delayed idle priority loop over glib», and i'll have to write a function that does the actual work and then a function that calls idle_add to call that function after a timeout, and then have the first function to call the second one with a timeout but don't forget to call the second one initially blah blah".
Then realised that it sucks, and wrote the snippet above.
+ gobject.idle_add(self.emit, 'initial-status-change', command, tid, params)
This one is simpler, of course. Remember that when a idle source is run, the next source runs after the mainloop is idle. So if you add lots of idle sources when the mainloop is busy, when it's idle again you see CPU at 100% for a few seconds, but GUI is almost completely responsive.
Logger connects itself to initial-status-change. Did I mention that a slow callback function connected to a signal makes the emit() call slower? And that those emit() work over the mainloop of course. And makes the mainloop unresponsive for an extra (time_to_add_a_contact_event * amount_of_contacts) seconds? Here it reached 2 minutes i think. And, yes, we have to reply a CHL message quickly, otherwise the server disconnects us.