From 3622ff86afc6db992224ae16a7eecd5190cf43b8 Mon Sep 17 00:00:00 2001 From: C Anthony Risinger Date: Thu, 16 Aug 2012 05:39:35 -0500 Subject: [PATCH] giwebkit: Timer impl feature complete --- library/pyjamas/Timer.giwebkit.py | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 library/pyjamas/Timer.giwebkit.py diff --git a/library/pyjamas/Timer.giwebkit.py b/library/pyjamas/Timer.giwebkit.py new file mode 100644 index 000000000..eb0a1a2d1 --- /dev/null +++ b/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
[TextNode]
-- 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)