forked from enlightenment/efl
ecore/idler - Improve documentation and add an example.
SVN revision: 60602
This commit is contained in:
parent
def2382a91
commit
d83f174929
|
@ -4,6 +4,7 @@
|
|||
* Here is a page with some Ecore examples explained:
|
||||
*
|
||||
* @li @ref ecore_time_example_c
|
||||
* @li @ref ecore_idler_example_c
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -37,6 +38,72 @@
|
|||
* @include ecore_time_example.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page ecore_idler_example_c ecore idle state - Idlers, enterers and exiters
|
||||
*
|
||||
* This example demonstrates how to manage the idle state of the main loop. Once
|
||||
* a program knows that the main loop is going to enter in idle state, it could
|
||||
* start doing some processing until getting out of this state.
|
||||
*
|
||||
* To exemplify this, we also add events and a timer to this program, so we can
|
||||
* see the idle exiter callback being called before processing the event and/or
|
||||
* timer, the event/timer callback being called (processed), then the idle
|
||||
* enterer being called before entering in idle state again. Once in idle, the
|
||||
* main loop keeps calling the idler callback continuously until a new event or
|
||||
* timer is received.
|
||||
*
|
||||
* First, we declare a struct that will be used as context to be passed to
|
||||
* every callback. It's not useful everywhere, since this example is very
|
||||
* simple and doesn't do anything other than printing messages, but using this
|
||||
* context will make it a little bit more real. Our context will be used to
|
||||
* delete the timer, idler, idle enterer and exiter, and the event handler, and
|
||||
* also to count how many times the idler was called.
|
||||
*
|
||||
* Then we start declaring callbacks for the idle enterer, idle exiter and the
|
||||
* idler itself. Idle enterer and exiter callbacks just print a message saying
|
||||
* that they were called, while the idler, in addition to printing a message
|
||||
* too, also sends an event every 10 times that it is called, incrementing the
|
||||
* context count variable. This event will be used to make the main loop exit
|
||||
* the idle state and call the event callback.
|
||||
*
|
||||
* These callbacks return @ref ECORE_CALLBACK_RENEW, since we want them to keep
|
||||
* being called every time the main loop changes to/from idle state. Otherwise,
|
||||
* if we didn't want them to be called again, they should return @ref
|
||||
* ECORE_CALLBACK_CANCEL.
|
||||
*
|
||||
* The next function declared is the event callback @c _event_handler_cb. It
|
||||
* will check if the idler was called more than 100 times already @c
|
||||
* (ctxt->count > 100), and will delete the idler, idle enterer and exiter, the
|
||||
* timer (if it still exists), and request that the main loop stop running. Then
|
||||
* it returns @ref ECORE_CALLBACK_CANCEL to indicate that the event handler
|
||||
* shouldn't be called anymore (this will delete it). If the @c count is still
|
||||
* smaller than 100, the event callback just returns @ref ECORE_CALLBACK_RENEW
|
||||
* and will keep being called every time that this event type is called.
|
||||
*
|
||||
* Finally, we add a callback to the timer, that will just print a message when
|
||||
* it is called, and this will happen only once (@ref ECORE_CALLBACK_CANCEL is
|
||||
* being returned). This timer callback is just here to show that the main loop
|
||||
* gets out of idle state when processing timers too.
|
||||
*
|
||||
* The @b main function is simple, just creates a new type of event that we will
|
||||
* use to demonstrate the event handling together with the idle state, adds the
|
||||
* callbacks that we declared so far, fill the context struct, and starts
|
||||
* running the main loop.
|
||||
*
|
||||
* @note We use timer and event callbacks to demonstrate the idle state
|
||||
* changing, but it also happens for file descriptor handlers, pipe handlers,
|
||||
* etc.
|
||||
*
|
||||
* @include ecore_idler_example.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example ecore_idler_example.c
|
||||
* This example shows when @ref Ecore_Idler, @ref Ecore_Idle_Enterer and @ref
|
||||
* Ecore_Idle_Exiter are called. See
|
||||
* @ref ecore_idler_example_c "the explanation here".
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example ecore_time_example.c
|
||||
* Shows the difference between the three time functions. See @ref
|
||||
|
|
|
@ -12,6 +12,7 @@ LDADD = \
|
|||
@dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm
|
||||
|
||||
SRCS = \
|
||||
ecore_idler_example.c \
|
||||
ecore_time_example.c \
|
||||
client_bench.c \
|
||||
server_bench.c \
|
||||
|
@ -31,6 +32,7 @@ endif
|
|||
|
||||
if EFL_BUILD_EXAMPLES
|
||||
pkglib_PROGRAMS += \
|
||||
ecore_idler_example \
|
||||
ecore_time_example
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
#include <Ecore.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct context { // helper struct to give some context to the callbacks
|
||||
int count;
|
||||
Ecore_Idle_Enterer *enterer;
|
||||
Ecore_Idler *idler;
|
||||
Ecore_Idle_Exiter *exiter;
|
||||
Ecore_Event_Handler *handler;
|
||||
Ecore_Timer *timer;
|
||||
};
|
||||
|
||||
static _event_type = 0; // a new type of event will be defined and stored here
|
||||
|
||||
static Eina_Bool
|
||||
_enterer_cb(void *data) // the idle enterer callback
|
||||
{
|
||||
printf("IDLE ENTERER: Ecore entering in idle state.\n");
|
||||
|
||||
return ECORE_CALLBACK_RENEW; // same as EINA_TRUE
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_exiter_cb(void *data) // the idle exiter callback
|
||||
{
|
||||
printf("IDLE EXITER: Ecore exiting idle state.\n");
|
||||
|
||||
return ECORE_CALLBACK_RENEW; // same as EINA_TRUE
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_idler_cb(void *data) // the idler callback - ran while the mainloop is idle
|
||||
{
|
||||
struct context *ctxt = data;
|
||||
printf("IDLER: executing idler callback while in idle state.\n");
|
||||
|
||||
ctxt->count++;
|
||||
|
||||
/* each 10 times that the callback gets called, generate an event that
|
||||
* will wake up the main loop, triggering idle enterers, exiters, etc. */
|
||||
if ((ctxt->count % 10) == 0)
|
||||
ecore_event_add(_event_type, NULL, NULL, NULL);
|
||||
|
||||
return ECORE_CALLBACK_RENEW; // same as EINA_TRUE
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_event_handler_cb(void *data, int type, void *event) // event callback
|
||||
{
|
||||
struct context *ctxt = data;
|
||||
|
||||
printf("EVENT: processing callback for the event received.\n");
|
||||
|
||||
if (ctxt->count > 100)
|
||||
{
|
||||
ecore_idle_enterer_del(ctxt->enterer);
|
||||
ecore_idle_exiter_del(ctxt->exiter);
|
||||
ecore_idler_del(ctxt->idler);
|
||||
|
||||
ctxt->enterer = NULL;
|
||||
ctxt->exiter = NULL;
|
||||
ctxt->idler = NULL;
|
||||
|
||||
if (ctxt->timer)
|
||||
{
|
||||
ecore_timer_del(ctxt->timer);
|
||||
ctxt->timer = NULL;
|
||||
}
|
||||
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_CANCEL; // same as EINA_FALSE
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW; // same as EINA_TRUE
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_timer_cb(void *data)
|
||||
{
|
||||
struct context *ctxt = data;
|
||||
printf("TIMER: timer callback called.\n");
|
||||
|
||||
if (ctxt->timer)
|
||||
ctxt->timer = NULL;
|
||||
|
||||
return ECORE_CALLBACK_CANCEL; // same as EINA_TRUE
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct context ctxt = {0};
|
||||
|
||||
if (!ecore_init())
|
||||
{
|
||||
printf("ERROR: Cannot init Ecore!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
_event_type = ecore_event_type_new();
|
||||
|
||||
ctxt.enterer = ecore_idle_enterer_add(_enterer_cb, &ctxt);
|
||||
ctxt.exiter = ecore_idle_exiter_add(_exiter_cb, &ctxt);
|
||||
ctxt.idler = ecore_idler_add(_idler_cb, &ctxt);
|
||||
ctxt.handler = ecore_event_handler_add(_event_type,
|
||||
_event_handler_cb,
|
||||
&ctxt);
|
||||
ctxt.timer = ecore_timer_add(0.0005, _timer_cb, &ctxt);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
ecore_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -41,6 +41,9 @@ static int idle_enterers_delete_me = 0;
|
|||
* @param data The data to be passed to the @p func call
|
||||
* @return A handle to the idle enterer callback if successful. Otherwise,
|
||||
* NULL is returned.
|
||||
* @note The function func will be called every time the main loop is entering
|
||||
* idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0
|
||||
* (or ECORE_CALLBACK_CANCEL) deletes the idle enterer.
|
||||
*/
|
||||
EAPI Ecore_Idle_Enterer *
|
||||
ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data)
|
||||
|
@ -63,6 +66,9 @@ ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data)
|
|||
* @param data The data to be passed to the @p func call
|
||||
* @return A handle to the idle enterer callback if successful. Otherwise,
|
||||
* NULL is returned.
|
||||
* @note The function func will be called every time the main loop is entering
|
||||
* idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0
|
||||
* (or ECORE_CALLBACK_CANCEL) deletes the idle enterer.
|
||||
*/
|
||||
EAPI Ecore_Idle_Enterer *
|
||||
ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data)
|
||||
|
|
|
@ -40,6 +40,9 @@ static int idle_exiters_delete_me = 0;
|
|||
* @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)
|
||||
|
|
|
@ -55,6 +55,13 @@ process.
|
|||
|
||||
Exiter callbacks are called when the main loop wakes up from an idle
|
||||
state.
|
||||
|
||||
@note Idle state doesn't mean that the @b program is idle, but that the <b>main
|
||||
loop</b> is idle. It doesn't have any timers, events, fd handlers or anything
|
||||
else to process (which in most <em>event driven</em> programs also means that the @b
|
||||
program is idle too, but it's not a rule). The program itself may be doing a lot of
|
||||
processing in the idler, or in another thread, for example.
|
||||
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue