forked from enlightenment/efl
ecore/event_handler - Improve documentation and add an example.
SVN revision: 60740
This commit is contained in:
parent
0198df7fd5
commit
89fa0bee81
|
@ -5,6 +5,8 @@
|
||||||
*
|
*
|
||||||
* @li @ref ecore_time_example_c
|
* @li @ref ecore_time_example_c
|
||||||
* @li @ref ecore_idler_example_c
|
* @li @ref ecore_idler_example_c
|
||||||
|
* @li @ref ecore_job_example_c
|
||||||
|
* @li @ref ecore_event_example_c
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -113,6 +115,108 @@
|
||||||
* @include ecore_job_example.c
|
* @include ecore_job_example.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page ecore_event_example_c ecore events and handlers - Setup and use
|
||||||
|
* This example shows how to create a new type of event, setup some event
|
||||||
|
* handlers to it, fire the event and have the callbacks called. After
|
||||||
|
* finishing, we delete the event handlers so no memory will leak.
|
||||||
|
*
|
||||||
|
* See the full source code for this example @ref ecore_event_example.c "here".
|
||||||
|
*
|
||||||
|
* Let's start the example from the beginning:
|
||||||
|
*
|
||||||
|
* @dontinclude ecore_event_example.c
|
||||||
|
* @until _event_type
|
||||||
|
*
|
||||||
|
* First thing is to declare a struct that will be passed as context to the
|
||||||
|
* event handlers. In this structure we will store the event handler pointers,
|
||||||
|
* and two strings that will be used by the first event handler. We also will
|
||||||
|
* use a global integer to store the event type used for our event. It is
|
||||||
|
* initialized with 0 in the beginning because the event wasn't created yet.
|
||||||
|
* Later, in the main function we will use ecore_event_type_new() to associate
|
||||||
|
* another value to it. Now the event handler callbacks:
|
||||||
|
*
|
||||||
|
* @until }
|
||||||
|
*
|
||||||
|
* This is the first event handler callback. It prints the event data received
|
||||||
|
* by the event, and the data passed to this handler when it was added. Notice
|
||||||
|
* that this callback already knows that the event data is an integer pointer,
|
||||||
|
* and that the handler data is a string. It knows about the first one because
|
||||||
|
* this is based on the type of event that is going to be handled, and the
|
||||||
|
* second because it was passed to the ecore_event_handler_add() function when
|
||||||
|
* registering the event handler.
|
||||||
|
*
|
||||||
|
* Another interesting point about this callback is that it returns @ref
|
||||||
|
* ECORE_CALLBACK_DONE (0) if the event data is even, swallowing the event and
|
||||||
|
* don't allowing any other callback to be called after this one for this event.
|
||||||
|
* Otherwise it returns @ref ECORE_CALLBACK_PASS_ON, allowing the event to be
|
||||||
|
* handled by other event handlers registered for this event. This makes the
|
||||||
|
* second event handler be called just for "odd" events.
|
||||||
|
*
|
||||||
|
* @until ECORE_CALLBACK_DONE
|
||||||
|
* @until }
|
||||||
|
*
|
||||||
|
* The second event handler will check if the event data is equal to 5, and if
|
||||||
|
* that's the case, it will change the event handler data of the first event
|
||||||
|
* handler to another string. Then it checks if the event data is higher than
|
||||||
|
* 10, and if so, it will request the main loop to quit.
|
||||||
|
*
|
||||||
|
* An interesting point of this example is that although the second event
|
||||||
|
* handler requests the main loop to finish after the 11th event being received,
|
||||||
|
* it will process all the events that were already fired, and call their
|
||||||
|
* respective event handlers, before the main loop stops. If we didn't want
|
||||||
|
* these event handlers to be called after the 11th event, we would need to
|
||||||
|
* unregister them with ecore_event_handler_del() at this point.
|
||||||
|
*
|
||||||
|
* Now some basic initialization of the context, and the Ecore library itself:
|
||||||
|
*
|
||||||
|
* @until type_new
|
||||||
|
*
|
||||||
|
* This last line is interesting. It creates a new type of event and returns a
|
||||||
|
* unique ID for this event inside Ecore. This ID can be used anywhere else in
|
||||||
|
* your program to reference this specific type of event, and to add callbacks
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* It's common if you are implementing a library that declares new types of
|
||||||
|
* events to export their respective types as extern in the header files. This
|
||||||
|
* way, when the library is initialized and the new type is created, it will be
|
||||||
|
* available through the header file to an application using it add some
|
||||||
|
* callbacks to it. Since our example is self-contained, we are just putting it
|
||||||
|
* as a global variable.
|
||||||
|
*
|
||||||
|
* Now we add some callbacks:
|
||||||
|
*
|
||||||
|
* @until ctxt);
|
||||||
|
*
|
||||||
|
* This is very simple. Just need to call ecore_event_handler_add() with the
|
||||||
|
* respective event type, the callback function to be called, and a data pointer
|
||||||
|
* that will be passed to the callback when it is called by the event.
|
||||||
|
*
|
||||||
|
* Then we start firing events:
|
||||||
|
*
|
||||||
|
* @until }
|
||||||
|
*
|
||||||
|
* This @c for will fire 16 events of this type. Notice that the events will be
|
||||||
|
* fired consecutively, but any callback will be called yet. They are just
|
||||||
|
* called by the main loop, and since it wasn't even started, nothing happens
|
||||||
|
* yet. For each event fired, we allocate an integer that will hold the number
|
||||||
|
* of the event (we are arbitrarily creating these numbers just for
|
||||||
|
* demonstration purposes). It's up to the event creator to decide which type of
|
||||||
|
* information it wants to give to the event handler, and the event handler must
|
||||||
|
* know what is the event info structure for that type of event.
|
||||||
|
*
|
||||||
|
* Since we are not allocating any complex structure, just a simple integer, we
|
||||||
|
* don't need to pass any special free function to ecore_event_add(), and it
|
||||||
|
* will use a simple @c free on our data. That's the default behavior.
|
||||||
|
*
|
||||||
|
* Now finishing our example:
|
||||||
|
*
|
||||||
|
* @until }
|
||||||
|
*
|
||||||
|
* We just start the main loop and watch things happen, waiting to shutdown
|
||||||
|
* Ecore when the main loop exits and return.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @example ecore_idler_example.c
|
* @example ecore_idler_example.c
|
||||||
* This example shows when @ref Ecore_Idler, @ref Ecore_Idle_Enterer and @ref
|
* This example shows when @ref Ecore_Idler, @ref Ecore_Idle_Enterer and @ref
|
||||||
|
@ -132,6 +236,12 @@
|
||||||
* ecore_time_example_c "the example explained".
|
* ecore_time_example_c "the example explained".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @example ecore_event_example.c
|
||||||
|
* This example shows how to setup, change, and delete event handlers. See
|
||||||
|
* @ref ecore_event_example_c "the explanation here".
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @example ecore_fd_handler_example.c
|
* @example ecore_fd_handler_example.c
|
||||||
* Shows how to use fd handlers.
|
* Shows how to use fd handlers.
|
||||||
|
|
|
@ -12,6 +12,7 @@ LDADD = \
|
||||||
@dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm
|
@dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm
|
||||||
|
|
||||||
SRCS = \
|
SRCS = \
|
||||||
|
ecore_event_example.c \
|
||||||
ecore_idler_example.c \
|
ecore_idler_example.c \
|
||||||
ecore_time_example.c \
|
ecore_time_example.c \
|
||||||
ecore_job_example.c \
|
ecore_job_example.c \
|
||||||
|
@ -33,6 +34,7 @@ endif
|
||||||
|
|
||||||
if EFL_BUILD_EXAMPLES
|
if EFL_BUILD_EXAMPLES
|
||||||
pkglib_PROGRAMS += \
|
pkglib_PROGRAMS += \
|
||||||
|
ecore_event_example \
|
||||||
ecore_idler_example \
|
ecore_idler_example \
|
||||||
ecore_job_example \
|
ecore_job_example \
|
||||||
ecore_time_example
|
ecore_time_example
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include <Ecore.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct context { // helper struct to give some context to the callbacks
|
||||||
|
const char *str1, *str2;
|
||||||
|
Ecore_Event_Handler *handler1;
|
||||||
|
Ecore_Event_Handler *handler2;
|
||||||
|
};
|
||||||
|
|
||||||
|
static _event_type = 0; // a new type of event will be defined and stored here
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_event_handler1_cb(void *data, int type, void *event)
|
||||||
|
{
|
||||||
|
int *number = event;
|
||||||
|
const char *str = data;
|
||||||
|
|
||||||
|
printf("event_handler1: number=%d, data=\"%s\".\n", *number, str);
|
||||||
|
|
||||||
|
if ((*number % 2) == 0)
|
||||||
|
return ECORE_CALLBACK_DONE;
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_event_handler2_cb(void *data, int type, void *event) // event callback
|
||||||
|
{
|
||||||
|
struct context *ctxt = data;
|
||||||
|
int *number = event;
|
||||||
|
|
||||||
|
printf("event_handler2: number=%d.\n", *number);
|
||||||
|
|
||||||
|
if (*number == 5)
|
||||||
|
{
|
||||||
|
const char *old = NULL;
|
||||||
|
old = ecore_event_handler_data_set(ctxt->handler1, (void *)ctxt->str2);
|
||||||
|
printf("changed handler1 data from \"%s\" to \"%s\".\n",
|
||||||
|
old, ctxt->str2);
|
||||||
|
}
|
||||||
|
else if (*number >= 10)
|
||||||
|
{
|
||||||
|
printf("finish main loop.\n");
|
||||||
|
ecore_main_loop_quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_DONE; // same as EINA_FALSE
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct context ctxt = {0};
|
||||||
|
int i;
|
||||||
|
ctxt.str1 = "dataone";
|
||||||
|
ctxt.str2 = "datatwo";
|
||||||
|
|
||||||
|
if (!ecore_init())
|
||||||
|
{
|
||||||
|
printf("ERROR: Cannot init Ecore!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_event_type = ecore_event_type_new();
|
||||||
|
|
||||||
|
ctxt.handler1 = ecore_event_handler_add(_event_type,
|
||||||
|
_event_handler1_cb,
|
||||||
|
ctxt.str1);
|
||||||
|
ctxt.handler2 = ecore_event_handler_add(_event_type,
|
||||||
|
_event_handler2_cb,
|
||||||
|
&ctxt);
|
||||||
|
|
||||||
|
for (i = 0; i <= 15; i++)
|
||||||
|
{
|
||||||
|
int *event_data = malloc(sizeof(*event_data));
|
||||||
|
*event_data = i;
|
||||||
|
ecore_event_add(_event_type, event_data, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("start the main loop.\n");
|
||||||
|
|
||||||
|
ecore_main_loop_begin();
|
||||||
|
|
||||||
|
ecore_shutdown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -101,9 +101,9 @@ static void *_ecore_event_del(Ecore_Event *event);
|
||||||
* provided in this call as the @p data parameter.
|
* provided in this call as the @p data parameter.
|
||||||
*
|
*
|
||||||
* When the callback @p func is called, it must return 1 or 0. If it returns
|
* When the callback @p func is called, it must return 1 or 0. If it returns
|
||||||
* 1 (or ECORE_CALLBACK_RENEW), It will keep being called as per normal, for
|
* 1 (or ECORE_CALLBACK_PASS_ON), It will keep being called as per normal, for
|
||||||
* each handler set up for that event type. If it returns 0 (or
|
* each handler set up for that event type. If it returns 0 (or
|
||||||
* ECORE_CALLBACK_CANCEL), it will cease processing handlers for that particular
|
* ECORE_CALLBACK_DONE), it will cease processing handlers for that particular
|
||||||
* event, so all handler set to handle that event type that have not already
|
* event, so all handler set to handle that event type that have not already
|
||||||
* been called, will not be.
|
* been called, will not be.
|
||||||
*/
|
*/
|
||||||
|
@ -179,7 +179,9 @@ ecore_event_handler_del(Ecore_Event_Handler *event_handler)
|
||||||
* @brief Get the data associated with an #Ecore_Event_Handler
|
* @brief Get the data associated with an #Ecore_Event_Handler
|
||||||
* @param eh The event handler
|
* @param eh The event handler
|
||||||
* @return The data
|
* @return The data
|
||||||
* This function returns the data previously associated with @p eh.
|
*
|
||||||
|
* This function returns the data previously associated with @p eh by
|
||||||
|
* ecore_event_handler_add().
|
||||||
*/
|
*/
|
||||||
EAPI void *
|
EAPI void *
|
||||||
ecore_event_handler_data_get(Ecore_Event_Handler *eh)
|
ecore_event_handler_data_get(Ecore_Event_Handler *eh)
|
||||||
|
@ -197,8 +199,9 @@ ecore_event_handler_data_get(Ecore_Event_Handler *eh)
|
||||||
* @param eh The event handler
|
* @param eh The event handler
|
||||||
* @param data The data to associate
|
* @param data The data to associate
|
||||||
* @return The previous data
|
* @return The previous data
|
||||||
|
*
|
||||||
* This function sets @p data to @p eh and returns the old data pointer
|
* This function sets @p data to @p eh and returns the old data pointer
|
||||||
* which was previously associated with @p eh.
|
* which was previously associated with @p eh by ecore_event_handler_add().
|
||||||
*/
|
*/
|
||||||
EAPI void *
|
EAPI void *
|
||||||
ecore_event_handler_data_set(Ecore_Event_Handler *eh, void *data)
|
ecore_event_handler_data_set(Ecore_Event_Handler *eh, void *data)
|
||||||
|
|
Loading…
Reference in New Issue