130 lines
6.4 KiB
Plaintext
130 lines
6.4 KiB
Plaintext
---
|
|
~~Title: Events Programming Guide~~
|
|
~~NOCACHE~~
|
|
---
|
|
|
|
# Events Programming Guide #
|
|
|
|
EFL is event-driven. This means that execution usually takes place within an internal EFL *Main Loop*. The application receives notifications through function callbacks. These can apply to virtually any event which occurs on a computer.
|
|
|
|
Events play a central role in EFL. In this guide, you'll learn more about the required methods to handle them.
|
|
|
|
You can also find usage examples in the EFL examples repository: [reference/c/core/src/core_event.c](https://git.enlightenment.org/enlightenment/examples/src/branch/master/reference/c/core/src/core_event.c)
|
|
|
|
## Prerequisites ##
|
|
|
|
* Read the [Introduction to Eo](/develop/tutorials/c/eo-intro.md) to understand how Eo objects are created and destroyed.
|
|
|
|
## Listening to Events from Objects ##
|
|
|
|
All Eo objects can emit events. You can discover more about this in the Events sections of their respective [API Reference documentation](/develop/api/).
|
|
|
|
To register a callback method to be called when an object emits a given event use ``efl_event_callback_add()``:
|
|
|
|
```c
|
|
efl_event_callback_add(object, event, callback, data);
|
|
```
|
|
|
|
Substitute *object* for any ``Eo *`` or derived object and *event* for the identifier of the event (such as ``EFL_LOOP_EVENT_POLL_HIGH`` or ``EFL_LOOP_TIMER_EVENT_TIMER_TICK``). Set *callback* to the method to be called when the event occurs and *data* to any data you want to pass to your callback (if you have no need of this use ``NULL``).
|
|
|
|
The method signature for the callback is:
|
|
|
|
```c
|
|
void callback(void *data, const Efl_Event *event);
|
|
```
|
|
|
|
In the above example *data* is the last parameter you used when registering the callback with ``efl_event_callback_add()``. *event* contains information about the event itself:
|
|
|
|
| Attribute | Type | Content |
|
|
| --------------------- | ---------------- | --------------------------------- |
|
|
| ``event->object`` | ``Eo *`` | The Object that emitted the event |
|
|
| ``event->info`` | ``void *`` | Used by some events to provide additional information. Must be cast to the appropriate type (see below). |
|
|
| ``event->desc->name`` | ``const char *`` | Name of the event |
|
|
|
|
The [API Reference documentation](/develop/api/) for each event tells you how to use ``event->info``. See [EFL_EVENT_POINTER_DOWN](/develop/api/efl/input/interface/event/pointer_down) for more examples.
|
|
|
|
To stop receiving notifications for a particular event (unregister a callback) use ``efl_event_callback_del()``:
|
|
|
|
```c
|
|
efl_event_callback_del(object, event, callback, data);
|
|
```
|
|
|
|
The parameters here have the same meaning as for ``efl_event_callback_add()``. Note that in order to unregister the callback you have to provide **the same parameters** you used to register it. This is because you can register different callbacks to the same event or even the same callback with different *data*.
|
|
|
|
> **NOTE:**
|
|
> Registering and unregistering callbacks is an resource-intensive process. If you perform these operations continuously on several callbacks at the same time do so in a batch as this is more efficient. You can use ``efl_event_callback_array_add()`` and ``efl_event_callback_array_del()`` to accomplish this. Remember however that you can't unregister an individual callback which has been registered in a batch. They must all be unregistered together.
|
|
|
|
Below is an example code snippet based on [reference/c/core/src/core_event.c](https://git.enlightenment.org/enlightenment/examples/src/branch/master/reference/c/core/src/core_event.c):
|
|
|
|
```c
|
|
static void
|
|
callback(void *data, const Efl_Event *event)
|
|
{
|
|
Efl_Loop *polled = data;
|
|
printf(" Polled %s from %s\n", efl_name_get(polled), efl_name_get(event->object));
|
|
}
|
|
|
|
void
|
|
setup()
|
|
{
|
|
[...]
|
|
efl_add(EFL_LOOP_TIMER_CLASS, mainloop,
|
|
efl_name_set(efl_added, "timer2"),
|
|
efl_loop_timer_interval_set(efl_added, .1),
|
|
efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, callback, mainloop));
|
|
[...]
|
|
}
|
|
```
|
|
|
|
Here a new timer object is created and added to ``mainloop``. The configuration of this timer takes place entirely inside the ``efl_add()`` call, as explained in the [Introduction to Eo](/develop/tutorials/c/eo-intro.md) tutorial.
|
|
|
|
Note how the ``polled`` object is passed as the *data* parameter to ``efl_event_callback_add()`` and recovered from the callback. The object that emitted the event (the timer) is also recovered from the callback through the ``event`` parameter.
|
|
|
|
## Pausing and Resuming Event Notifications ##
|
|
|
|
All event emissions from a given object can be paused (*frozen*) using ``efl_event_freeze()`` and resumed with ``efl_event_thaw()``:
|
|
|
|
```c
|
|
efl_event_freeze(object);
|
|
efl_event_thaw(object);
|
|
```
|
|
|
|
While an object is frozen only high-priority events (marked as *hot*) will be emitted. Hot events cannot be stopped.
|
|
|
|
Remember that ALL events emitting from a object are stopped if its frozen, except for hot events. If you need to stop individual events you can unregister their callback temporarily and then re-register later.
|
|
|
|
## Defining Custom Events ##
|
|
|
|
You can define any number of custom events and emit them from any Eo object. You can then register callbacks to be activated by these events.
|
|
|
|
First create a ``Efl_Event_Description`` variable. Next, initialize it with ``EFL_EVENT_DESCRIPTION()`` and make it available everywhere you want to use this new event:
|
|
|
|
```c
|
|
Efl_Event_Description CUSTOM_EVENT = EFL_EVENT_DESCRIPTION("custom-event");
|
|
```
|
|
|
|
Register to this event as you would normally do for EFL events with ``efl_event_callback_add()``:
|
|
|
|
```c
|
|
efl_event_callback_add(object, &CUSTOM_EVENT, callback, data);
|
|
```
|
|
|
|
*data* works as usual and can be recovered from the callback through the ``data`` parameter.
|
|
|
|
Now emit the event using ``efl_event_callback_call()``:
|
|
|
|
```c
|
|
efl_event_callback_call(object, &CUSTOM_EVENT, event_info);
|
|
```
|
|
|
|
*event_info* will be passed to the callback through the ``event->info`` parameter. Its meaning is completely up to you as the event creator.
|
|
|
|
## Further Reading ##
|
|
[reference/c/core/src/core_event.c](https://git.enlightenment.org/enlightenment/examples/src/branch/master/reference/c/core/src/core_event.c)
|
|
: EFL examples repository
|
|
|
|
[``Efl.Object`` API Reference](/develop/api/efl/object)
|
|
: Detailed documentation for the EFL object, which implements the events mechanism
|
|
|
|
[Introduction to Eo](/develop/tutorials/c/eo-intro.md)
|
|
: Tutorial on instantiating and configuring Eo objects |