reprint an analysis of someone else
GLib Create a custom event source
GLIB implements a powerful event-looping distribution processing mechanism that is abstracted into gmainloop for looping through events on event sources. Each gmainloop is working on the specified gmaincontext. The event source is abstracted into gsource in the GLib. There is a gsource list in the Gmaincontext. The GLIB internal definition implements three types of event sources, namely, Idle, Timeout, and I/O. The creation of custom event sources is also supported. (Four types of event sources : Custom event sources ,Idle,Timeout,I/O)
The basic role of custom event sources
A custom event source can be used to hook an external signal (event) to a specified main loop in the program, thus responding to these events in G_main_loop_run. (For example: can be used as a timer)
How to create a custom event source
GLib provides a series of interfaces for creating custom event sources, let's first explain the basic functions and data structures that create event sources, and finally give some examples.
A custom event source is a structure that inherits Gsource, that is, the first member of the structure of the custom event source is the Gsource structure, and then the data required by the program can be placed, for example:
typedef struct _MYSOURCE MySource;
struct _mysource
{
gsource _source;
Gchar text[256];
}
Once you have implemented the definition of the event source data structure, you need
implements the interface specified by the event source, mainly for prepare, check, dispatch, Finalizesuch as event-handling functions (callback functions), which are contained in the GSOURCEFUNCS structure body. The GSOURCEFUNCS structure and the storage space width of the event source structure are passed to the g_source_new as parameters to construct a new event source, which can then be used to add the new event source to the main loop context using the G_source_attach function. The following example creates a "Hello world!" that can only be spoken Event source and adds it to the default gmaincontext of the main event loop.
#include <glib.h> #include <glib/gprintf.h> typedef struct _MYSOURCE mysource;
struct _mysource {gsource source;
Gchar text[256];
};
Static Gboolean Prepare (Gsource *source, Gint *timeout) {*timeout = 0;
return TRUE;
Static Gboolean Check (Gsource *source) {return TRUE;} Static Gboolean Dispatch (Gsource *source, Gsourcefunc callback, Gpointer user_data) {MySource *mysource = (MySource *
) source; G_print ("%s\ n", Mysource->text);
return TRUE;
} int main (void) {Gmainloop *loop = g_main_loop_new (NULL, TRUE);
Gmaincontext *context = G_main_loop_get_context (loop);
Gsourcefuncs Source_funcs = {prepare, check, dispatch, NULL};
Gsource *source = g_source_new (&source_funcs, sizeof (MySource));
G_SPRINTF ((MySource *) source)->text, "Hello world!");
G_source_attach (source, context);
G_source_unref (source);
G_main_loop_run (loop);
G_main_context_unref (context);
G_main_loop_unref (loop);
return 0; } |
When the G_main_loop_run function of the above program runs, it iterates through the list of event sources for the Gmaincontext, which is roughly as follows:
A. G_main_loop_run determines whether the event source is ready by calling the prepare interface of the event source and judging its return value. If the return value of the prepare interface for each event source is TRUE ( direct adjustment with dispatch )
B. If an event source is not ready, the event source is queried for preparation, which is accomplished by invoking the check interface of the event source, if the event source is still not ready, that is, the check interface returns FALSE, then G_ Main_loop_run will let the main event loop into the sleep state. The sleep time of the primary event loop is the minimum time interval (timeout time, in milliseconds ) that is counted in step a to traverse the time source, for example, in the prepare interface, to set the time interval as follows. After a certain time, G_main_loop_run will wake up the main event loop and ask again ( adjust in order prepare,1 first. Returns true, direct dispatch, 2. After returning false,timeout, call check, return True, Direct Dispatch,false, direct call prepare, so loop ).
Static Gboolean Prepare (Gsource *source, Gint *timeout)
{
*timeout = 1000;/* Set time interval one second */
return
TRUE;
} |
The response function of the event source is a callback function that can be set using the G_source_set_callback function. In the previous example, we did not provide a response function for the custom event source.
The custom event source above is actually a Idle type, such as an event source that is processed only if the main event loop has no other event source processing. GLIB provides a predefined set of idle event source types, as shown in the following example.
#include <glib.h>
static Gboolean idle_func (Gpointer data)
{
g_print ("%s"), (Gchar *) data);
return
TRUE;
}
int main (void)
{
Gmainloop *loop = g_main_loop_new (NULL, TRUE);
Gmaincontext *context = G_main_loop_get_context (loop);
G_idle_add (Idle_func, "Hello world!");
G_main_loop_run (loop);
G_main_context_unref (context |