/** * Pauses a running timer. * * @param timer The timer to be paused. * * The timer callback won't be called while the timer is paused. The remaining * time until the timer expires will be saved, so the timer can be resumed with * that same remaining time to expire, instead of expiring instantly. Use * ecore_timer_thaw() to resume it. * * @note Nothing happens if the timer was already paused. * * @see ecore_timer_thaw() */ EAPI void ecore_timer_freeze(Ecore_Timer *timer) { double now; _ecore_lock(); if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, "ecore_timer_freeze"); goto unlock; } /* Timer already frozen */ if (timer->frozen) goto unlock; timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); suspended = (Ecore_Timer *)eina_inlist_prepend(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); now = ecore_time_get(); timer->pending = timer->at - now; timer->at = 0.0; timer->frozen = 1; unlock: _ecore_unlock(); }
EAPI void * ecore_animator_del(Ecore_Animator *animator) { void *data = NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR)) { ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR, "ecore_animator_del"); goto unlock; } if (animator->delete_me) { data = animator->data; goto unlock; } animator->delete_me = EINA_TRUE; animators_delete_me++; if (animator->run_func) data = animator->run_data; else data = animator->data; unlock: _ecore_unlock(); return data; }
/** * Resumes a frozen (paused) timer. * * @param timer The timer to be resumed. * * The timer will be resumed from its previous relative position in time. That * means, if it had X seconds remaining until expire when it was paused, it will * be started now with those same X seconds remaining to expire again. But * notice that the interval time won't be touched by this call or by * ecore_timer_freeze(). * * @see ecore_timer_freeze() */ EAPI void ecore_timer_thaw(Ecore_Timer *timer) { double now; _ecore_lock(); if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, "ecore_timer_thaw"); goto unlock; } /* Timer not frozen */ if (!timer->frozen) goto unlock; suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); now = ecore_time_get(); _ecore_timer_set(timer, timer->pending + now, timer->in, timer->func, timer->data); unlock: _ecore_unlock(); }
/** * Creates a timer to call the given function in the given period of time. * @param in The interval in seconds. * @param func The given function. If @p func returns 1, the timer is * rescheduled for the next interval @p in. * @param data Data to pass to @p func when it is called. * @return A timer object on success. @c NULL on failure. * * This function adds a timer and returns its handle on success and NULL on * failure. The function @p func will be called every @p in seconds. The * function will be passed the @p data pointer as its parameter. * * When the timer @p func is called, it must return a value of either 1 * (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL). * If it returns 1, it will be called again at the next tick, or if it returns * 0 it will be deleted automatically making any references/handles for it * invalid. */ EAPI Ecore_Timer * ecore_timer_add(double in, Ecore_Task_Cb func, const void *data) { double now; Ecore_Timer *timer = NULL; _ecore_lock(); if (!func) goto unlock; if (in < 0.0) in = 0.0; timer = ecore_timer_calloc(1); if (!timer) goto unlock; ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER); now = ecore_time_get(); #ifdef WANT_ECORE_TIMER_DUMP timer->timer_bt_num = backtrace((void **)(timer->timer_bt), ECORE_TIMER_DEBUG_BT_NUM); #endif _ecore_timer_set(timer, now + in, in, func, (void *)data); unlock: _ecore_unlock(); return timer; }
/** * Get the pending time regarding a timer. * * @param timer The timer to learn from. * @ingroup Ecore_Time_Group */ EAPI double ecore_timer_pending_get(Ecore_Timer *timer) { double now; double ret = 0.0; _ecore_lock(); if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, "ecore_timer_pending_get"); goto unlock; } now = ecore_time_get(); if (timer->frozen) ret = timer->pending; else ret = timer->at - now; unlock: _ecore_unlock(); return ret; }
EAPI void ecore_animator_custom_tick(void) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); if (src == ECORE_ANIMATOR_SOURCE_CUSTOM) _do_tick(); _ecore_unlock(); }
/** * Free an Ecore_Pipe object created with ecore_pipe_add(). * * @param p The Ecore_Pipe object to be freed. * @return The pointer to the private data */ EAPI void * ecore_pipe_del(Ecore_Pipe *p) { void *r; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); r = _ecore_pipe_del(p); _ecore_unlock(); return r; }
EAPI void ecore_animator_source_set(Ecore_Animator_Source source) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); src = source; _end_tick(); if (animators) _begin_tick(); _ecore_unlock(); }
/** * @brief Wait from another thread on the read side of a pipe. * * @param p The pipe to watch on. * @param message_count The minimal number of message to wait before exiting. * @param wait The amount of time in second to wait before exiting. * @return the number of message catched during that wait call. * @since 1.1 * * Negative value for @p wait means infite wait. */ EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait) { int r; _ecore_lock(); r = _ecore_pipe_wait(p, message_count, wait); _ecore_unlock(); return r; }
EOLIAN static void _ecore_idle_enterer_after_constructor(Eo *obj, Ecore_Idle_Enterer_Data *ie, Ecore_Task_Cb func, const void *data) { _ecore_lock(); if (!_ecore_idle_enterer_add(obj, ie, func, data)) goto unlock; idle_enterers = (Ecore_Idle_Enterer_Data *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); unlock: _ecore_unlock(); }
/** * Create two file descriptors (sockets on Windows). Add * a callback that will be called when the file descriptor that * is listened receives data. An event is also put in the event * queue when data is received. * * @param handler The handler called when data is received. * @param data Data to pass to @p handler when it is called. * @return A newly created Ecore_Pipe object if successful. * @c NULL otherwise. */ EAPI Ecore_Pipe * ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data) { Ecore_Pipe *p; _ecore_lock(); p = _ecore_pipe_add(handler, data); _ecore_unlock(); return p; }
EAPI void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); end_tick_cb = func; end_tick_data = data; _end_tick(); if (animators) _begin_tick(); _ecore_unlock(); }
EAPI Ecore_Idler * ecore_idler_add(Ecore_Task_Cb func, const void *data) { Ecore_Idler *ie = NULL; _ecore_lock(); ie = eo_add(MY_CLASS, _ecore_parent, ecore_idler_constructor(func, data)); _ecore_unlock(); return ie; }
static void _ecore_pipe_handler_call(Ecore_Pipe *p, unsigned char *buf, size_t len) { void *data = (void*) p->data; if (!p->delete_me) { _ecore_unlock(); p->handler(data, buf, len); _ecore_lock(); } }
EAPI void ecore_animator_frametime_set(double frametime) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); if (frametime < 0.0) frametime = 0.0; if (animators_frametime == frametime) goto unlock; animators_frametime = frametime; _end_tick(); if (animators) _begin_tick(); unlock: _ecore_unlock(); }
/** * Creates a timer to call the given function in the given period of time. * @param in The interval in seconds from current loop time. * @param func The given function. If @p func returns 1, the timer is * rescheduled for the next interval @p in. * @param data Data to pass to @p func when it is called. * @return A timer object on success. @c NULL on failure. * * This is the same as ecore_timer_add(), but "now" is the time from * ecore_loop_time_get() not ecore_time_get() as ecore_timer_add() uses. See * ecore_timer_add() for more details. */ EAPI Ecore_Timer * ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data) { Ecore_Timer *timer; _ecore_lock(); timer = _ecore_timer_loop_add(in, func, data); _ecore_unlock(); return timer; }
EAPI void * ecore_idler_del(Ecore_Idler *idler) { void *data = NULL; if (!idler) return NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); data = _ecore_idler_del(idler); _ecore_unlock(); return data; }
EAPI Ecore_Animator * ecore_animator_add(Ecore_Task_Cb func, const void *data) { Ecore_Animator *animator; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); animator = _ecore_animator_add(func, data); _ecore_unlock(); return animator; }
/** * Sets the precision to be used by timer infrastructure. * * When system calculates time to expire the next timer we'll be able * to delay the timer by the given amount so more timers will fit in * the same dispatch, waking up the system less often and thus being * able to save power. * * Be aware that kernel may delay delivery even further, these delays * are always possible due other tasks having higher priorities or * other scheduler policies. * * Example: * We have 2 timers, one that expires in a 2.0s and another that * expires in 2.1s, if precision is 0.1s, then the Ecore will request * for the next expire to happen in 2.1s and not 2.0s and another one * of 0.1 as it would before. * * @note Ecore is smart enough to see if there are timers in the * precision range, if it does not, in our example if no second timer * in (T + precision) existed, then it would use the minimum timeout. * * @param value allowed introduced timeout delay, in seconds. */ EAPI void ecore_timer_precision_set(double value) { _ecore_lock(); if (value < 0.0) { ERR("Precision %f less than zero, ignored", value); goto unlock; } precision = value; unlock: _ecore_unlock(); }
static void _timer_constructor(Eo *obj, void *_pd, va_list *list) { double in = va_arg(*list, double); Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); const void *data = va_arg(*list, const void *); double now; _ecore_lock(); now = ecore_time_get(); Ecore_Timer_Private_Data *timer = _pd; _ecore_timer_add(obj, timer, now, in, func, data); _ecore_unlock(); }
/** * Add some delay for the next occurrence of a timer. * This doesn't affect the interval of a timer. * * @param timer The timer to change. * @param add The dalay to add to the next iteration. */ EAPI void ecore_timer_delay(Ecore_Timer *timer, double add) { if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, "ecore_timer_delay"); return; } _ecore_lock(); _ecore_timer_delay(timer, add); _ecore_unlock(); }
EAPI void ecore_animator_thaw(Ecore_Animator *animator) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR)) { ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR, "ecore_animator_del"); goto unlock; } if (animator->delete_me) goto unlock; animator->suspended = EINA_FALSE; unlock: _ecore_unlock(); }
/** * @brief Sets the precision to be used by timer infrastructure. * * @param value allowed introduced timeout delay, in seconds. * * This sets the precision for @b all timers. The precision determines how much * of an difference from the requested interval is acceptable. One common reason * to use this function is to @b increase the allowed timeout and thus @b * decrease precision of the timers, this is because less precise the timers * result in the system waking up less often and thus consuming less resources. * * Be aware that kernel may delay delivery even further, these delays * are always possible due other tasks having higher priorities or * other scheduler policies. * * Example: * We have 2 timers, one that expires in a 2.0s and another that * expires in 2.1s, if precision is 0.1s, then the Ecore will request * for the next expire to happen in 2.1s and not 2.0s and another one * of 0.1 as it would before. * * @note Ecore is smart enough to see if there are timers in the * precision range, if it does not, in our example if no second timer * in (T + precision) existed, then it would use the minimum timeout. */ EAPI void ecore_timer_precision_set(double value) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); if (value < 0.0) { ERR("Precision %f less than zero, ignored", value); goto unlock; } precision = value; unlock: _ecore_unlock(); }
/** * Delete an idle enterer callback. * @param idle_enterer The idle enterer to delete * @return The data pointer passed to the idler enterer callback on success. * NULL otherwise. */ EAPI void * ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer) { void *data; if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER)) { ECORE_MAGIC_FAIL(idle_enterer, ECORE_MAGIC_IDLE_ENTERER, "ecore_idle_enterer_del"); return NULL; } _ecore_lock(); data = _ecore_idle_enterer_del(idle_enterer); _ecore_unlock(); return data; }
/** * Change the interval the timer ticks of. If set during * a timer call, this will affect the next interval. * * @param timer The timer to change. * @param in The interval in seconds. */ EAPI void ecore_timer_interval_set(Ecore_Timer *timer, double in) { _ecore_lock(); if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) { ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, "ecore_timer_interval_set"); goto unlock; } timer->in = in; unlock: _ecore_unlock(); }
/** * Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). * * @param p The Ecore_Pipe object. */ EAPI void ecore_pipe_write_close(Ecore_Pipe *p) { _ecore_lock(); if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) { ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close"); goto out; } if (p->fd_write != PIPE_FD_INVALID) { pipe_close(p->fd_write); p->fd_write = PIPE_FD_INVALID; } out: _ecore_unlock(); }
/** * Delete an idle exiter handler from the list to be run on exiting idle state. * @param idle_exiter The idle exiter to delete * @return The data pointer that was being being passed to the handler if * successful. NULL otherwise. */ EAPI void * ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter) { void *data; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER)) { ECORE_MAGIC_FAIL(idle_exiter, ECORE_MAGIC_IDLE_EXITER, "ecore_idle_exiter_del"); return NULL; } _ecore_lock(); data = _ecore_idle_exiter_del(idle_exiter); _ecore_unlock(); return data; }
/** * Stop monitoring if necessary the pipe for reading. See ecore_pipe_thaw() * for monitoring it again. * * @param p The Ecore_Pipe object. * @since 1.1 */ EAPI void ecore_pipe_freeze(Ecore_Pipe *p) { EINA_MAIN_LOOP_CHECK_RETURN; _ecore_lock(); if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) { ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze"); goto out; } if (p->fd_handler) { _ecore_main_fd_handler_del(p->fd_handler); p->fd_handler = NULL; } out: _ecore_unlock(); }
/** * Add an idle exiter handler. * @param func The function to call when exiting an idle state. * @param data The data to be passed to the @p func call * @return A handle to the idle exiter callback on success. NULL otherwise. * @note The function func will be called every time the main loop is exiting * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 * (or ECORE_CALLBACK_CANCEL) deletes the idle exiter. */ EAPI Ecore_Idle_Exiter * ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data) { Ecore_Idle_Exiter *ie = NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); if (!func) goto unlock; ie = ecore_idle_exiter_calloc(1); if (!ie) goto unlock; ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER); ie->func = func; ie->data = (void *)data; idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie)); unlock: _ecore_unlock(); return ie; }
EAPI Ecore_Animator * ecore_animator_timeline_add(double runtime, Ecore_Timeline_Cb func, const void *data) { Ecore_Animator *animator; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); _ecore_lock(); if (runtime <= 0.0) runtime = 0.0; animator = _ecore_animator_add(_ecore_animator_run, NULL); animator->data = animator; animator->run_func = func; animator->run_data = (void *)data; animator->start = ecore_loop_time_get(); animator->run = runtime; _ecore_unlock(); return animator; }