Tizen Native API  7.0
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:

prog_flow.png

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_init();
    ecore_app_args_set(argc, argv);
    ecore_main_loop_begin();
    ecore_shutdown();
    return 0;
 }

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);
    return ECORE_CALLBACK_RENEW;
 }

 int
 exit_func(void *data, int ev_type, void *ev)
 {
    Ecore_Event_Signal_Exit *e;

    e = (Ecore_Event_Signal_Exit *)ev;
    if (e->interrupt)      printf("Exit: interrupt\n");
    else if (e->quit)      printf("Exit: quit\n");
    else if (e->terminate) printf("Exit: terminate\n");
    ecore_main_loop_quit();
    return 1;
 }

 int
 main(int argc, const char **argv)
 {
    ecore_init();
    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);
    ecore_main_loop_begin();
    ecore_shutdown();
    return 0;
 }

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.