aboutsummaryrefslogtreecommitdiffstats
path: root/pages/develop/guides/csharp/core/events.md.txt
blob: 4efec318995f5433b25ed6282ec53642337885d4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
---
~~Title: Events Programming Guide in C#~~
~~NOCACHE~~
---

# Events Programming Guide in C# #

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](https://git.enlightenment.org/tools/examples.git/tree/).

## Listening to Events from Objects ##

All EFL objects can emit events. You can discover more about them in the **Events** section of their respective [API Reference documentation](/develop/api/) (only in C, C# *coming soon*).

In C# you register a callback method to be called when an object emits a given event using the `+=` operator:

```csharp
object.event += callback;
```

Substitute *object* for any EFL object and *event* for the identifier of the event (such as ``PollHighEvt`` or ``TickEvt``). Set *callback* to the method to be called when the event occurs.

The method signature for the callback is:

```csharp
void callback(object sender, EventArgs e);
```

*sender* is the object that emitted the event and *e* contains any additional information that the event sent, after casting it to the required type (for example, `efl.input.Interface.KeyDownEvt_Args` when connecting to the `efl.input.Interface.KeyDownEvt` event).

> **NOTE:**
> The [API Reference documentation](/develop/api/) for each event tells you what type to cast *e* to (*Not available for C# yet*).
> See [EFL_EVENT_POINTER_DOWN](/develop/api/efl/input/interface/event/pointer_down) for example.

To stop receiving notifications for a particular event, unregister the callback using the `-=` operator:

```csharp
object.event -= callback;
```

Note that in order to unregister the callback you have to provide the callback method again. This is because you can register different callback methods to the same event.

## Pausing and Resuming Event Notifications ##

All event emissions from a given object can be paused (*frozen*) using `FreezeEvent()` and resumed with `ThawEvent()`:

```csharp
   object.FreezeEvent();
   object.ThawEvent();
```

While an object is frozen only high-priority events (marked as *hot* in the documentation) will be emitted. Hot events cannot be stopped.

Remember that ALL events emitting from a object are stopped if it's frozen, except for hot events. If you need to stop individual events you can unregister their callback temporarily and then re-register later.

## Example ##

Below is the `core_event.cs` example taken from [the examples repository](https://git.enlightenment.org/tools/examples.git/tree/reference/csharp/core/src/core_event.cs):

```csharp
public class Example
{
    // Polling callback
    private static void PollCb(object sender, EventArgs e)
    {
        Console.WriteLine("  Poll from {0}", ((efl.IObject)sender).GetName());
    }

    public static void Main()
    {
        // Initialize EFL and all UI components
        efl.All.Init();

        // Retrieve the application's main loop
        var mainloop = efl.App.GetLoopMain();
        mainloop.SetName("Mainloop");

        // This event gets triggered continuously
        mainloop.PollHighEvt += PollCb;

        // This timer will control events fired by the main loop
        new efl.Loop_Timer(mainloop, (efl.ILoop_Timer etimer) => {
            etimer.SetName("Timer");
            // Trigger every 100ms
            etimer.SetInterval(0.1);
            // To count number of timer triggers
            int tick_count = 0;
            etimer.TickEvt += (object sender, EventArgs e) => {
                string message = "Tick {0} from {1}: ";
                // Depending on the number of timer ticks, it does a different thing
                switch (tick_count) {
                    case 0:
                        message += "Freezing Mainloop events";
                        mainloop.FreezeEvent();
                        break;
                    case 1:
                        message += "Thawing Mainloop events";
                        mainloop.ThawEvent();
                        break;
                    default:
                        message += "Quitting";
                        mainloop.Quit(new eina.Value(0));
                        break;
                }
                Console.WriteLine(message, tick_count, ((efl.IObject)sender).GetName());
                tick_count++;
            };
        });

        Console.WriteLine("Waiting for Timer to call back...");

        // Start the EFL main loop (and the experiment)
        mainloop.Begin();

        // Shutdown EFL
        efl.All.Shutdown();

        Console.WriteLine("Application is over");
    }
}
```

A handler is connected to the `PollHighEvt` event of the application's main loop, which triggers continuously, at an undefined frequency of several shots per second (See the Main Loop Programming Guide, *coming soon*). At every shot, a line is printed on the console.

At the same time, a timer is instantiated, firing every 100ms, which does a different thing at every shot:

* First it freezes (pauses) all main loop events (except hot ones).
* Then it thaws (resumes) all main loop events.
* Finally, it quits the application.

When you run the application, it should produce something like this on the console:

```
Waiting for Timer to call back...
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
Tick 0 from Timer: Freezing Mainloop events
Tick 1 from Timer: Thawing Mainloop events
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
  Poll from Mainloop
Tick 2 from Timer: Quitting
```

As you can see, the line `Poll from Mainloop` is printed continuously except in the period between Tick 0 and Tick 1 of the Timer, where main loop events are frozen.

The exact amount of `Poll from Mainloop` messages you get depends on the frequency of the `PollHighEvt` event, which is chosen by EFL. The important thing is that there should be no such messages in between timer ticks 0 and 1, since main loop events are frozen,

## Further Reading ##

[`core_event.cs` example](https://git.enlightenment.org/tools/examples.git/tree/reference/csharp/core/src/core_event.cs)
:    C# Source code for this example.

[`Efl.Object` API Reference](https://www.enlightenment.org/develop/api/efl/object)
:    Detailed documentation for the EFL object, which implements the events mechanism.