UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

334 lines (261 loc) 7.53 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Sebastian Werner (wpbasti) * Andreas Ecker (ecker) ************************************************************************ */ /** * Global timer support. * * This class can be used to periodically fire an event. This event can be * used to simulate e.g. a background task. The static method * {@link #once} is a special case. It will call a function deferred after a * given timeout. * * NOTE: Instances of this class must be disposed of after use * */ qx.Class.define("qx.event.Timer", { extend : qx.core.Object, implement : [ qx.core.IDisposable ], /* ***************************************************************************** CONSTRUCTOR ***************************************************************************** */ /** * @param interval {Number} initial interval in milliseconds of the timer. */ construct : function(interval) { this.base(arguments); if (interval != null) { this.setInterval(interval); } // don't use qx.lang.Function.bind because this function would add a // disposed check, which could break the functionality. In IE the handler // may get called after "clearInterval" (i.e. after the timer is disposed) // and we must be able to handle this. var self = this; this.__oninterval = function() { self._oninterval.call(self); }; }, /* ***************************************************************************** EVENTS ***************************************************************************** */ events : { /** This event if fired each time the interval time has elapsed */ "interval" : "qx.event.type.Event" }, /* ***************************************************************************** STATICS ***************************************************************************** */ statics : { /** * Start a function after a given timeout. * * @param func {Function} Function to call * @param obj {Object} context (this), the function is called with * @param timeout {Number} Number of milliseconds to wait before the * function is called. * @return {qx.event.Timer} The timer object used for the timeout. This * object can be used to cancel the timeout. Note that the timer is * only valid until the timer has been executed. */ once : function(func, obj, timeout) { if (qx.core.Environment.get("qx.debug")) { // check the given parameter qx.core.Assert.assertFunction(func, "func is not a function"); qx.core.Assert.assertNotUndefined(timeout, "No timeout given"); } // Create time instance var timer = new qx.event.Timer(timeout); // Bug #3481: append original function to timer instance so it can be // read by a debugger timer.__onceFunc = func; // Add event listener to interval timer.addListener("interval", function(e) { timer.stop(); func.call(obj, e); delete timer.__onceFunc; timer.dispose(); obj = null; }, obj); // Directly start timer timer.start(); return timer; } }, /* ***************************************************************************** PROPERTIES ***************************************************************************** */ properties : { /** * With the enabled property the Timer can be started and suspended. * Setting it to "true" is equivalent to {@link #start}, setting it * to "false" is equivalent to {@link #stop}. */ enabled : { init : false, check : "Boolean", apply : "_applyEnabled" }, /** * Time in milliseconds between two callback calls. * This property can be set to modify the interval of * a running timer. */ interval : { check : "Integer", init : 1000, apply : "_applyInterval" } }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members : { __intervalHandler : null, __oninterval : null, /* --------------------------------------------------------------------------- APPLY ROUTINES --------------------------------------------------------------------------- */ /** * Apply the interval of the timer. * * @param value {var} Current value * @param old {var} Previous value */ _applyInterval : function(value, old) { if (this.getEnabled()) { this.restart(); } }, /** * Apply the enabled state of the timer. * * @param value {var} Current value * @param old {var} Previous value */ _applyEnabled : function(value, old) { if (old) { window.clearInterval(this.__intervalHandler); this.__intervalHandler = null; } else if (value) { this.__intervalHandler = window.setInterval(this.__oninterval, this.getInterval()); } }, /* --------------------------------------------------------------------------- USER-ACCESS --------------------------------------------------------------------------- */ /** * Start the timer * */ start : function() { this.setEnabled(true); }, /** * Start the timer with a given interval * * @param interval {Integer} Time in milliseconds between two callback calls. */ startWith : function(interval) { this.setInterval(interval); this.start(); }, /** * Stop the timer. * */ stop : function() { this.setEnabled(false); }, /** * Restart the timer. * This makes it possible to change the interval of a running timer. * */ restart : function() { this.stop(); this.start(); }, /** * Restart the timer. with a given interval. * * @param interval {Integer} Time in milliseconds between two callback calls. */ restartWith : function(interval) { this.stop(); this.startWith(interval); }, /* --------------------------------------------------------------------------- EVENT-MAPPER --------------------------------------------------------------------------- */ /** * timer callback * * @signature function() */ _oninterval : qx.event.GlobalError.observeMethod(function() { if (this.$$disposed) { return; } if (this.getEnabled()) { this.fireEvent("interval"); } }) }, /* ***************************************************************************** DESTRUCTOR ***************************************************************************** */ destruct : function() { if (this.__intervalHandler) { window.clearInterval(this.__intervalHandler); } this.__intervalHandler = this.__oninterval = null; } });