The Ecore Main Loop

What is Ecore?

Ecore is a clean and tiny event loop library with many modules to do lots of convenient things for a programmer to save time and effort. It's small and lean, designed to work from embedded systems all the way up to large and powerful multi-cpu workstations. The main loop has a number of primitives to be used with its main loop. It serializes all the primitives and allows for great responsiveness without the need for threads(or any other concurrency).

Timers

Timers serve two main purposes: doing something at a specified time and repeatedly doing something with a set interval.

See also
Ecore Timer functions

Pollers

Pollers allow for polling to be centralized into a single place therefore alleviating the need for different parts of the program to wake up at different times to do polling, thereby making the code simpler and more efficient.

See also
Ecore Poll functions

Idlers

There are three types of idlers: enterers, idlers(proper) and exiters. They are called, respectively, when the program is about to enter an idle state, when the program is idle, and when the program is leaving an idle state. Idler enterers are usually a good place to update the program state. Proper idlers are the appropriate place to do heavy computational tasks thereby using what would otherwise be wasted CPU cycles. Exiters are the perfect place to do anything your program should do just before processing events (also timers, pollers, file descriptor handlers and animators)

See also
Ecore Idle functions

File descriptor handlers

File descriptor handlers allow you to monitor when there is data available to read on file descriptors, when writing will not block, or if there was an error. Any valid file descriptor can be used with this API, regardless of if was gotten with an OS specific API or from ecore.

See also
File Descriptor Handling Functions

Animators

Ecore provides a facility called animators, so named since the intended use was in animations, that facilitates knowing what percentage of a given interval has elapsed. This is perfect for performing animations, but is not limited to that use, it can, for example, also be used to create a progress bar.

See also
Ecore Animator functions

Event handlers

Event handlers are, arguably, the most important feature of the ecore main loop, they are what allows the programmer to easily handle user interaction. Events however are not only things the user does, events can represent anything for which a type is created.

See also
Ecore Event functions All of these primitives are discussed in more detail in their respective pages linked above.

Here is a diagram of the main loop flow of a simple program:

How does Ecore work?

Ecore is very easy to learn and use. All the function calls are designed to be easy to remember, explicit in describing what they do, and heavily name-spaced. Ecore programs can start and be very simple.

For example:

#include <Ecore.h>
int
main(int argc, const char **argv)
{
ecore_app_args_set(argc, argv);
return 0;
}
void ecore_app_args_set(int argc, const char **argv)
Sets up the programs command-line arguments.
Definition: ecore_app.c:15
EAPI int ecore_shutdown(void)
Shuts down connections, signal handlers sockets etc.
Definition: ecore.c:371
EAPI int ecore_init(void)
Sets up connections, signal handlers, sockets etc.
Definition: ecore.c:230
void ecore_main_loop_begin(void)
Runs the application main loop.
Definition: ecore_main.c:1311

This program is very simple and doesn't check for errors, but it does start up and begin a main loop waiting for events or timers to tick off. This program doesn't set up any, but now we can expand on this simple program a little more by adding some event handlers and timers.

#include <Ecore.h>
Ecore_Timer *timer1 = NULL;
Ecore_Event_Handler *handler1 = NULL;
double start_time = 0.0;
int
timer_func(void *data)
{
printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time);
}
int
exit_func(void *data, int ev_type, void *ev)
{
if (e->interrupt) printf("Exit: interrupt\n");
else if (e->quit) printf("Exit: quit\n");
else if (e->terminate) printf("Exit: terminate\n");
return 1;
}
int
main(int argc, const char **argv)
{
ecore_app_args_set(argc, argv);
start_time = ecore_time_get();
handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL);
timer1 = ecore_timer_add(0.5, timer_func, NULL);
return 0;
}
#define ECORE_EVENT_SIGNAL_EXIT
Exit signal event.
Definition: Ecore_Common.h:565
struct _Ecore_Event_Handler Ecore_Event_Handler
A handle for an event handler.
Definition: Ecore_Common.h:576
Ecore_Event_Handler * ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data)
Adds an event handler.
Definition: ecore_events.c:13
#define ECORE_CALLBACK_RENEW
Return value to keep a callback.
Definition: Ecore_Common.h:153
void ecore_main_loop_quit(void)
Quits the main loop once all the events currently on the queue have been processed.
Definition: ecore_main.c:1321
double ecore_time_get(void)
Retrieves the current system time as a floating point value in seconds.
Definition: ecore_time.c:33
Ecore_Timer * ecore_timer_add(double in, Ecore_Task_Cb func, const void *data)
Creates a timer to call the given function in the given period of time.
Definition: ecore_timer.c:189
Eo Ecore_Timer
A handle for timers.
Definition: Ecore_Common.h:3079
A structure that stores information of an Exit request event.
Definition: Ecore_Common.h:637
Eina_Bool interrupt
Set if the exit request was an interrupt signal.
Definition: Ecore_Common.h:638
Eina_Bool quit
set if the exit request was a quit signal
Definition: Ecore_Common.h:639
Eina_Bool terminate
Set if the exit request was a terminate signal.
Definition: Ecore_Common.h:640

In the previous example, we initialize our application and get the time at which our program has started so we can calculate an offset. We set up a timer to tick off in 0.5 seconds, and since it returns 1, will keep ticking off every 0.5 seconds until it returns 0, or is deleted by hand. An event handler is set up to call a function - exit_func(), whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C on the command line will cause such an event to happen). If this event occurs it tells you what kind of exit signal was received, and asks the main loop to quit when it is finished by calling ecore_main_loop_quit().

The handles returned by ecore_timer_add() and ecore_event_handler_add() are only stored here as an example. If you don't need to address the timer or event handler again you don't need to store the result, so just call the function, and don't assign the result to any variable.

This program looks slightly more complex than needed to do these simple things, but in principle, programs don't get any more complex. You add more event handlers, for more events, will have more timers and such, BUT it all follows the same principles as shown in this example.