Sunday, February 6, 2011

Preparing for the Event

Having buttons and other GUI elements is nice, but before they are useful, your program need to be able to react to them. There are actually a large number of ways of dealing with this problem with the different solutions having their advantages. The most basic way of dealing with events is to use polling. This is essentially what is happening beneath the hood at the OS or BIOS level. Essentially, you loop through the objects that can cause an event to see if an event has been triggered. When an event is triggered, a handler is called. This works, is relatively simple to implement, very efficient, and is probably not appropriate to use in a scripting language.

Scripting languages are meant to respond to events. However, as the user interface elements that are being created are latching on to the events that the browser is passing to it, the mouse event handler could poll the current set of active UI objects to see if their state has changed and handle the changes. This fits into the scripting event model, is fairly quick and simple to do, and for the simple games like those being created under the Dozen Days project is more than adequate. One of the concepts of the extreme programming methodology is to not over-engineer problems as one common killer of projects is to make the code complex enough to deal with features that may be needed in the future but in reality never come. If at a later date you need the features after all, refactoring can be done. Still, if the extra functionality comes without the cost of more complex code, then it is worth doing so let us continue to look at the options.

The next level up is to simply have a callback function that gets called when an event gets triggered. This makes the events much easier to handle as they no longer have to be crammed into a single event handling function but can be spread out to as many functions as are desired. Again, this is very simple to implement and it adds a huge amount of flexibility. The only downside is that only one function can be tied to each UI item. This is rarely a problem.

To get around the problem of only having one callback function is to have functions register with the component as a listener. This requires a lot more complexity as you need to be able to add and remove listeners as well as call all the listeners when events happen. If implemented in a primitive object that you know the UI components are going to inherit from then this may make sense as the code can be written easily enough. Still, this is more work with very little extra value.

A similar approach to  the above would be to have some type of global event manager. Any code could call the event manager to register itself as a listener to any event. When a component has an event to send, it just tells the global event manager. It would not need to worry about anything else. While it would be a fair bit of work creating an efficient event manager, it would make events a pleasure to deal with. While way to complex for my needs, it would be a technique that could easily be refactored into most the other approaches so is an approach to keep in the back of your mind.

No comments: