# # PyGUI - Tasks - Cocoa # import sys from weakref import WeakValueDictionary from Foundation import NSTimer, NSRunLoop, NSDefaultRunLoopMode from AppKit import NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode from GUI import export from GUI import Globals from GUI.GTasks import Task as GTask #---------------------------------------------------------------------- # # Doing things this convoluted way to work around a memory # leak in PyObjC. Need to avoid having the NSTimer trigger # creation of a bound method each time it fires or the bound # methods leak. Also can't use the userInfo of the NSTimer as # it seems to leak too. ns_timer_to_task = WeakValueDictionary() class TaskTrigger(object): pass def fire_(ns_timer): ns_timer_to_task[ns_timer]._ns_fire() trigger = TaskTrigger() trigger.fire_ = fire_ #---------------------------------------------------------------------- class Task(GTask): def __init__(self, proc, interval, repeat = 0, start = 1): self._proc = proc self._interval = interval self._repeat = repeat self._ns_timer = None if start: self.start() def destroy(self): #print "Task.destroy:", self ### self.stop() def get_scheduled(self): return self._ns_timer is not None def get_interval(self): return self._interval def get_repeat(self): return self._repeat def start(self): self.stop() #ns_timer = \ # NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_( # self._interval, self._target, '_ns_fire', None, self._repeat) ns_timer = \ NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_( self._interval, trigger, 'fire:', None, self._repeat) self._ns_timer = ns_timer ns_timer_to_task[ns_timer] = self ns_run_loop = NSRunLoop.currentRunLoop() ns_run_loop.addTimer_forMode_( ns_timer, NSDefaultRunLoopMode) ns_run_loop.addTimer_forMode_( ns_timer, NSEventTrackingRunLoopMode) ns_run_loop.addTimer_forMode_( ns_timer, NSModalPanelRunLoopMode) def stop(self): ns_timer = self._ns_timer if ns_timer: ns_timer.invalidate() del ns_timer_to_task[ns_timer] self._ns_timer = None def _ns_fire(self): try: self._proc() except: Globals.pending_exception = sys.exc_info() self.stop() export(Task)