File: event-driven.dox

package info (click to toggle)
ola 0.10.7.nojsmin-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 16,252 kB
  • sloc: cpp: 131,729; python: 13,127; sh: 4,590; ansic: 2,179; java: 518; xml: 253; makefile: 142
file content (131 lines) | stat: -rw-r--r-- 5,022 bytes parent folder | download | duplicates (6)
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
/**
 * @page event_driven OLA & Event Driven Programming
 *
 * [TOC]
 *
 * @section event_Overview Overview
 *
 * This page describes event driven programming and how OLA uses it. It also
 * provides pointers on how OLA's event driven model can be used with other
 * event driven frameworks.
 *
 * @section event_Background Background
 *
 * [Event Driven
 * Programming](http://en.wikipedia.org/wiki/Event-driven_programming) is a
 * programming style where actions within the program are triggered by various
 * events. Event driven programs typically have a main event loop which then
 * executes the required handlers when events occur.
 *
 * The simplest event loop may look something like:
  ~~~~~~~~~~~~~~~~~~~~~
  while ((c = getchar()) != EOF) {
    switch (c) {
      case 'q':
        printf("'q' was pressed\n");
        break;
      default:
        printf("Something other than 'q' was pressed\n");
      }
  }
  ~~~~~~~~~~~~~~~~~~~~~
 *
 * While this works for key-presses, it doesn't support any other type of I/O
 * event. To support more generic types of events, the
 * [select()](http://linux.die.net/man/2/select) call (or a variant thereof) is
 * often used.
 *
 * Event driven frameworks allow the programmer to register to
 * receive notifications of certain events. Notifications are usually delivered
 * by executing a callback function. For example, for a timer event, the code
 * may look like:
  ~~~~~~~~~~~~~~~~~~~~~
  app.RunAfter(1000, TimerFunction);
  ~~~~~~~~~~~~~~~~~~~~~
 *
 * Usually after any initialization is performed, the application gives up
 * control to the main event loop. This is usually done with a call to Run():
  ~~~~~~~~~~~~~~~~~~~~~
  app.Run();
  ~~~~~~~~~~~~~~~~~~~~~
 *
 * The Run() call will only return when the application shuts down.
 *
 * While this appears limiting at first, the method is in fact very powerful.
 * Event driven programming allows the programmer to focus on writing code to
 * handle the events, rather than determining what action to take next.
 *
 * A caveat however that is that callbacks triggered by events can't block.
 * Doing so prevents control returning to the main event loop and will starve
 * other event notifications. Typical approaches are to either use
 * non-blocking I/O or perform blocking I/O in a separate thread.
 *
 * @section event_OLA OLA Event Management
 *
 * In OLA, there are two main types of events:
 *  - Timer events, which trigger after a certain time interval.
 *  - I/O events, which trigger when a network packet arrives, a device has new
 *    data or some other I/O occurs.
 *
 * @subsection event_CPlusPlus C++
 *
 * The ola::io::SelectServer is the core of OLA's event driven system. It
 * invokes \ref callbacks when events occur.
 *
 * For the OLA Client, the ola::OlaClientWrapper class encapsulates the
 * SelectServer behind an easy to use interface. This is described in the @ref
 * dmx_cpp_client_tutorial.
 *
 * @subsection event_Python Python
 *
 * The Python classes are similar to the C++ ones. The ola.ClientWrapper module
 * provides a basic SelectServer class.
 *
 * As the in C++ clase, the ola.ClientWrapper.ClientWrapper class encapsulates
 * this all so in the basic case you can just call:
  ~~~~~~~~~~~~~~~~~~~~~
    from ola.ClientWrapper import ClientWrapper

    wrapper = ClientWrapper()
    wrapper.Run()  # event loop is running
  ~~~~~~~~~~~~~~~~~~~~~
 *
 * @section event_Integration Integration with other frameworks
 *
 * This section is for those who want to use the OLA client within another
 * event management framework. The OLA client code does not use timers so the
 * only events you need to handle are socket I/O.
 *
 * There are two main approaches. For frameworks that allow file descriptors to
 * be added to the main event loop, one can simply add the file descriptor for
 * the OLA server and call the appropriate read/write methods when the event
 * triggers.
 *
 * For frameworks that do not support raw file descriptor access the best
 * solution is to run the OLA client in a \ref cpp_client_Thread
 * "separate thread" and use a callback queue to pass control between the
 * threads.
 *
 * The OLA clients are not thread safe, and must only be accessed from the
 * thread in which the event loop is running.
 *
 * @subsection event_GLib Integration with GLib
 *
 * [GLib](https://developer.gnome.org/glib/stable/) has a
 * [g_source_add_unix_fd](https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-add-unix-fd)
 * function.
 *
 * @subsection event_QT Integration with QT
 *
 * [Qt](http://qt-project.org/) provides a
 * [QSocketNotifier](http://qt-project.org/doc/qt-4.8/qsocketnotifier.html)
 * which allows the OLA socket to be added to Qt's main loop.
 *
 * @subsection event_kivy Integration with Kivy
 *
 * See https://github.com/jesseanderson/ola-rpiui for an example.
 *
 * @subsection event_pygame Integration with PyGame
 *
 * See [Example](https://groups.google.com/d/msg/open-lighting/hBq00uYXioA/zpG88fjJFDAJ)
 */