When you wanted to listen for events in a system in the old days, you’d attach yourself to an interrupt. Sometimes you might get to poke at code that still does this, but it’s normally reserved for old or microcontroller scale hardware. The idea was simple, the processor wasn’t really fast enough to poll all the possible sources of information and do something about the data, but it was fast enough to be told about events and process the information as and when it arrived. Event handling in games has often been like this, register yourself as interested in an event, then get told about it when it happens. The publish and subscribe model has been around for many years, but there’s not been a standard interface built for it as it often requires from problem domain knowledge to implement effectively. Some systems want to be told about every event in the system and decide for themselves, such as windows event handling. Some systems subscribe to very particular events but want to react to them as soon as they happen, such as handlers for the BIOS events like the keyboard interrupt.
Using your existence in a table as the registration technique makes this simpler than before and lets you register and de-register with great pace. You can register an entity as being interested in events, and choose to fire off the transform immediately, or queue up new events until the next loop round. As the model becomes simpler and more usable, the opportunity for more common use leads us to new ways of implementing code traditionally done via polling.
For example: unless the player character is within the distance to activate a door, the event handler for the player’s action button wont be attached to anything door related. When the character comes within range, the character registers into the has_pressed_action event table with the open_door_(X) event result. This reduces the amount of time the CPU wastes figuring out what thing the player was trying to activate, and also helps provide state information such as on-screen displays saying that pressing Green will Open the door. It may even do this by hooking into low level tables generated by default such as a character registers into the has_pressed_action event table event.
This coding style is somewhat reminiscent of aspect oriented programming where it is easy to allow for cross-cutting concerns in the code. In aspect oriented programming, the core code for any activities is kept clean, and any side effects or vetoes of actions are handled by other concerns hooking into the activity from outside. This keeps the core code clean at the expense of not knowing what is really going to be called when you write a line of code. How using registration tables differs is in where the reactions come from and how they are determined. As we shall see in chapter [chap:condition], when you use conditions for logical reactions, debugging can become significantly simpler as the barriers between cause and effect normally implicit in aspect oriented programming are significantly diminished or removed, and the hard to adjust nature of object oriented decision making can be softened to allow your code to become more dynamic without the normal associated cost of data driven control flow.