Prev: 10. Comparison to the Traditional Approach
If you've never done event-driven programming before, the internal structure of the "Fly 'n' Shoot" game must certainly represent a big paradigm shift for you. In fact, I hope that it actually blows your mind, because otherwise I'm not sure that you really appreciate the complete reversal of control of an event-driven program compared to the traditional sequential code. This reversal of control, known as the "Hollywood Principle" (don't call us, we'll call you), baffles many newcomers, who often find it "mind-boggling", "backwards", or "weird".
My main goal in this Tutorial was just to introduce you to the event-driven paradigm and the modern state machines to convince you that these powerful concepts aren't particularly hard to implement directly in C or C++. Indeed, I hope you noticed that the actual coding of the nontrivial "Fly 'n' Shoot" game wasn't a big deal at all. All you needed to know was just a few cookie-cutter rules for coding state machines and familiarity with a few framework services for implementing the actions.
Wile the coding turned out to be essentially a non-issue; the bulk of the programming effort was spent on the design of the application. At this point, I hope that the "Fly 'n' Shoot" example helps you to get the big picture of how the method works. Under the event driven model, the program structure is divided into two rough groups: events and state machine components (active objects). An event represents the occurrence of something interesting. A state machine codifies the reactions to the events, which generally depend both on the nature of the event and on the state of the component. While events often originate from the outside of your program, such as time ticks or button presses in the "Fly 'n' Shoot" game, events can also be generated internally by the program itself. For example the Mine components generate notification events when they detect a collision with the Missile or the Ship.
An event-driven program executes by constantly checking for possible events and, when an event is detected, dispatching the event to the appropriate state machine component (see Figure 10-1(b)). In order for this approach to work, the events must be checked continuously and frequently. This implies that the state machines must execute quickly, so that the program can get back to checking for events. In order to meet this requirement, a state machine cannot go into a condition where it is busy-waiting for some long or indeterminate time. The most common example of this would be a while loop inside a state-handler function, where the condition for termination was not under program control, for instance the button press. This kind of program structure, an indefinite loop, is referred to as "blocking" code6, and you saw examples of it in the "Quickstart" application (see Figure 10-1(a)). In order for the event driven programming model to work, you must only write "non-blocking" code.
Finally, the "Fly 'n' Shoot" example demonstrates the use of the event-driven platform called QP-nano, which is a collection of components for building event-driven application. The QF-nano real-time framework component framework embodies the "Hollywood principle", by calling the application code, not the other way around. Such arrangement is very typical for event-driven systems and application frameworks similar to QF-nano are at the heart of virtually every design automation tool on the market today.
The QP-nano event-driven platform scales down better and than any traditional RTOS or real-time kernel. In fact, you can view QP-nano as a high-level, event-driven, real-time operating system for tiny, low-end embedded systems.
Prev: 10. Comparison to the Traditional Approach
1.5.4