Skip to content

Commit

Permalink
giwebkit: Timer impl feature complete
Browse files Browse the repository at this point in the history
  • Loading branch information
C Anthony Risinger committed Aug 23, 2012
1 parent 5def547 commit 3622ff8
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions library/pyjamas/Timer.giwebkit.py
@@ -0,0 +1,57 @@
class Timer(object):

def __setTimeout(self, periodMillis, impl='Timeout'):
'''
Coordinate with JavaScript and realize a new Timer.
A private communication channel is established by both sides
acquiring a ref to the same TextNode; once linked, the node is
removed from the DOM tree, but can still recieve all events.
It also serves as a nucleus for adding more nodes to the link -- eg.
wrapping in <div>[TextNode]</div> -- for whatever reason, and
without limit.
Here we just use the private node to trigger Python callbacks;
Python registers listeners and JavaScript synthesizes events.
PyGObject is capable of clearing Timers, but is unable to create
new ones (upstream bug?).
'''
# TODO: Timers/Intervals in JS will not queue for safety reasons;
# if we're unable to process the first event before another
# fires, we end up with an unbounded backlog of Timer events.
# For this reason, JS will only queue one event of this type
# at-a-time ... we MUST ensure this same behaviour!
code = r'''
(function(buf, ms){
var wnd = window;
var doc = wnd.document;
var evt = doc.createEvent('UIEvent');
var run = function(){buf.dispatchEvent(evt)};
var tid = wnd.set%s(run, ms);
doc.head.removeChild(buf);
tid = buf.data = Number(tid);
evt.initUIEvent('Timer', true, true, wnd, tid);
}(document.head.lastChild, %s));
''' % (impl, int(periodMillis))
mf = get_main_frame()
vw = mf._view
doc = mf.getDomDocument()
run = lambda *a: self.__fire()
buf = doc.createTextNode('')
doc.head.appendChild(buf)
mf.addEventListener(buf, 'Timer', run)
vw.execute_script(code)
return int(buf.data)

def __clearTimeout(self, tid, impl='Timeout'):
'''Cancel a running Timer.'''
wnd = get_main_frame().getDomWindow()
return getattr(wnd, 'clear%s' % impl)(int(tid))

def __setInterval(self, periodMillis, impl='Interval'):
'''Passthru to setTimeout(), but call setInterval().'''
return self.__setTimeout(periodMillis, impl=impl)

def __clearInterval(self, tid, impl='Interval'):
'''Passthru to clearTimeout(), but call clearInterval().'''
return self.__clearTimeout(tid, impl=impl)

0 comments on commit 3622ff8

Please sign in to comment.