michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsISupports.idl" michael@0: michael@0: interface nsIObserver; michael@0: interface nsIEventTarget; michael@0: michael@0: %{C++ michael@0: /** michael@0: * The signature of the timer callback function passed to initWithFuncCallback. michael@0: * This is the function that will get called when the timer expires if the michael@0: * timer is initialized via initWithFuncCallback. michael@0: * michael@0: * @param aTimer the timer which has expired michael@0: * @param aClosure opaque parameter passed to initWithFuncCallback michael@0: */ michael@0: class nsITimer; michael@0: typedef void (*nsTimerCallbackFunc) (nsITimer *aTimer, void *aClosure); michael@0: %} michael@0: michael@0: native nsTimerCallbackFunc(nsTimerCallbackFunc); michael@0: michael@0: /** michael@0: * The callback interface for timers. michael@0: */ michael@0: interface nsITimer; michael@0: michael@0: [function, scriptable, uuid(a796816d-7d47-4348-9ab8-c7aeb3216a7d)] michael@0: interface nsITimerCallback : nsISupports michael@0: { michael@0: /** michael@0: * @param aTimer the timer which has expired michael@0: */ michael@0: void notify(in nsITimer timer); michael@0: }; michael@0: michael@0: %{C++ michael@0: // Two timer deadlines must differ by less than half the PRIntervalTime domain. michael@0: #define DELAY_INTERVAL_LIMIT PR_BIT(8 * sizeof(PRIntervalTime) - 1) michael@0: %} michael@0: michael@0: /** michael@0: * nsITimer instances must be initialized by calling one of the "init" methods michael@0: * documented below. You may also re-initialize (using one of the init() michael@0: * methods) an existing instance to avoid the overhead of destroying and michael@0: * creating a timer. It is not necessary to cancel the timer in that case. michael@0: * michael@0: * By default a timer will fire on the thread that created it. Set the .target michael@0: * attribute to fire on a different thread. Once you have set a timer's .target michael@0: * and called one of its init functions, any further interactions with the timer michael@0: * (calling cancel(), changing member fields, etc) should only be done by the michael@0: * target thread, or races may occur with bad results like timers firing after michael@0: * they've been canceled, and/or not firing after re-initiatization. michael@0: */ michael@0: [scriptable, uuid(193fc37a-8aa4-4d29-aa57-1acd87c26b66)] michael@0: interface nsITimer : nsISupports michael@0: { michael@0: /* Timer types */ michael@0: michael@0: /** michael@0: * Type of a timer that fires once only. michael@0: */ michael@0: const short TYPE_ONE_SHOT = 0; michael@0: michael@0: /** michael@0: * After firing, a TYPE_REPEATING_SLACK timer is stopped and not restarted michael@0: * until its callback completes. Specified timer period will be at least michael@0: * the time between when processing for last firing the callback completes michael@0: * and when the next firing occurs. michael@0: * michael@0: * This is the preferable repeating type for most situations. michael@0: */ michael@0: const short TYPE_REPEATING_SLACK = 1; michael@0: michael@0: /** michael@0: * An TYPE_REPEATING_PRECISE repeating timer aims to have constant period michael@0: * between firings. The processing time for each timer callback should not michael@0: * influence the timer period. However, if the processing for the last michael@0: * timer firing could not be completed until just before the next firing michael@0: * occurs, then you could have two timer notification routines being michael@0: * executed in quick succession. Furthermore, if your callback processing michael@0: * time is longer than the timer period, then the timer will post more michael@0: * notifications while your callback is running. For example, if a michael@0: * REPEATING_PRECISE timer has a 10ms period and a callback takes 50ms, michael@0: * then by the time the callback is done there will be 5 events to run the michael@0: * timer callback in the event queue. Furthermore, the next scheduled time michael@0: * will always advance by exactly the delay every time the timer fires. michael@0: * This means that if the clock increments without the timer thread running michael@0: * (e.g. the computer is asleep) when the timer thread gets to run again it michael@0: * will post all the events that it "missed" while it wasn't running. Use michael@0: * this timer type with extreme caution. Chances are, this is not what you michael@0: * want. michael@0: */ michael@0: const short TYPE_REPEATING_PRECISE = 2; michael@0: michael@0: /** michael@0: * A TYPE_REPEATING_PRECISE_CAN_SKIP repeating timer aims to have constant michael@0: * period between firings. The processing time for each timer callback michael@0: * should not influence the timer period. However this timer type michael@0: * guarantees that it will not queue up new events to fire the callback michael@0: * until the previous callback event finishes firing. If the callback michael@0: * takes a long time, then the next callback will be scheduled immediately michael@0: * afterward, but only once, unlike TYPE_REPEATING_PRECISE. If you want a michael@0: * non-slack timer, you probably want this one. michael@0: */ michael@0: const short TYPE_REPEATING_PRECISE_CAN_SKIP = 3; michael@0: michael@0: /** michael@0: * Initialize a timer that will fire after the said delay. michael@0: * A user must keep a reference to this timer till it is michael@0: * is no longer needed or has been cancelled. michael@0: * michael@0: * @param aObserver the callback object that observes the michael@0: * ``timer-callback'' topic with the subject being michael@0: * the timer itself when the timer fires: michael@0: * michael@0: * observe(nsISupports aSubject, => nsITimer michael@0: * string aTopic, => ``timer-callback'' michael@0: * wstring data => null michael@0: * michael@0: * @param aDelay delay in milliseconds for timer to fire michael@0: * @param aType timer type per TYPE* consts defined above michael@0: */ michael@0: void init(in nsIObserver aObserver, in unsigned long aDelay, michael@0: in unsigned long aType); michael@0: michael@0: michael@0: /** michael@0: * Initialize a timer to fire after the given millisecond interval. michael@0: * This version takes a function to call and a closure to pass to michael@0: * that function. michael@0: * michael@0: * @param aFunc The function to invoke michael@0: * @param aClosure An opaque pointer to pass to that function michael@0: * @param aDelay The millisecond interval michael@0: * @param aType Timer type per TYPE* consts defined above michael@0: */ michael@0: [noscript] void initWithFuncCallback(in nsTimerCallbackFunc aCallback, michael@0: in voidPtr aClosure, michael@0: in unsigned long aDelay, michael@0: in unsigned long aType); michael@0: michael@0: /** michael@0: * Initialize a timer to fire after the given millisecond interval. michael@0: * This version takes a function to call. michael@0: * michael@0: * @param aFunc nsITimerCallback interface to call when timer expires michael@0: * @param aDelay The millisecond interval michael@0: * @param aType Timer type per TYPE* consts defined above michael@0: */ michael@0: void initWithCallback(in nsITimerCallback aCallback, michael@0: in unsigned long aDelay, michael@0: in unsigned long aType); michael@0: michael@0: /** michael@0: * Cancel the timer. This method works on all types, not just on repeating michael@0: * timers -- you might want to cancel a TYPE_ONE_SHOT timer, and even reuse michael@0: * it by re-initializing it (to avoid object destruction and creation costs michael@0: * by conserving one timer instance). michael@0: */ michael@0: void cancel(); michael@0: michael@0: /** michael@0: * The millisecond delay of the timeout. michael@0: * michael@0: * NOTE: Re-setting the delay on a one-shot timer that has already fired michael@0: * doesn't restart the timer. Call one of the init() methods to restart michael@0: * a one-shot timer. michael@0: */ michael@0: attribute unsigned long delay; michael@0: michael@0: /** michael@0: * The timer type - one of the above TYPE_* constants. michael@0: */ michael@0: attribute unsigned long type; michael@0: michael@0: /** michael@0: * The opaque pointer pass to initWithFuncCallback. michael@0: */ michael@0: [noscript] readonly attribute voidPtr closure; michael@0: michael@0: /** michael@0: * The nsITimerCallback object passed to initWithCallback. michael@0: */ michael@0: readonly attribute nsITimerCallback callback; michael@0: michael@0: /** michael@0: * The nsIEventTarget where the callback will be dispatched. Note that this michael@0: * target may only be set before the call to one of the init methods above. michael@0: * michael@0: * By default the target is the thread that created the timer. michael@0: */ michael@0: attribute nsIEventTarget target; michael@0: }; michael@0: michael@0: %{C++ michael@0: #define NS_TIMER_CONTRACTID "@mozilla.org/timer;1" michael@0: #define NS_TIMER_CALLBACK_TOPIC "timer-callback" michael@0: %} michael@0: