Sat. Jan 21st, 2023

Event Driven Programming – Structure

Event driven programming, like object oriented programming, combines paradigms. It still uses the principles of procedural programming, but the key principle of event driven programming is the idea that blocks of code are defined, and executed only in response to a specific event being raised.

Understand that you can combine all three styles of programming in a single project!

Event driven programming is a good candidate for any system where a lot of time is spent waiting for input, or for time-sensitive systems (that is, a system such as an alarm clock or calendar).

Code is written in named blocks, just as with procedural programming. However, in procedural programming, you may end up doing this:

C#

string Input = Console.ReadLine();
if (Input == "1") { RunOptionOne(); }
if (Input == "2") { RunOptionTwo(); }
//etc

void RunOptionOne() {
  //Some code here
}

void RunOptionTwo() {
  //Some code here
}

There is nothing ‘wrong’ with this – when using the console to read keyboard input, the program is paused until the user presses the Enter key. At this point, the code looks to see what was pressed and performs the corresponding task.

What would happen if the input wasn’t coming from the console – perhaps it is in a game, and we need to do something as soon as the user presses a key? Well, we could (that means it’s a bad idea) do this…

C#

while (true) {
  if (Input.GetKeyDown("1")) { RunOptionOne(); }
  if (Input.GetKeyDown("2")) { RunOptionTwo(); }
  //etc
}

void RunOptionOne() {
//Some code here
}

void RunOptionTwo() {
//Some code here
}

What’s changed? We are now using a routine to ask if a key is being pressed, and if it is, then we perform our tasks as before. The difference is that we are not waiting for the user to press Enter to submit their choice. This is great for responsiveness, but it means that if they aren’t pressing the key at the exact moment that the line of code checks to see if the key is being pressed, then nothing happens. So, we have to repeatedly ask whether the key is being pressed or not, which we have done by wrapping a while(true) block around the code.

Now it works as expected, but there’s a catch: a while(true) block will repeat indefinitely, and as with all programs, as quickly as possible. You’ll find a CPU core gets pushed to near 100% with that code, as it just checks as quickly and often as it can to see whether the key has been pressed. Not a good use of resources.

Another issue is the legibility of the code. With only two keys to worry about, it’s not that hard to read. But imagine an average program, with hundreds of different inputs, and having to write code that checks for each condition as often as possible, in a constant loop. Without even introducing complexity like disabling inputs, it’s going to be messy.

C#

//Register that we would like to know when a key is pressed
this.OnKeyDown += new EventHandler(KeyPressed);


//This code will run only when a key has been pressed
void KeyPressed(object sender, EventArgs e)
{
  if (e.Key == "1") {
    RunOptionOne(); }
  if (e.Key == "2") {
    RunOptionTwo(); }
}

See how the code above avoids using any while loops to keep checking for input? Yet, it is still responsive. This is the core of event driven programming: you register the events that you are interested in (for example, the mouse moving, a button being pressed, a file being received, a period of time elapsing), and you say what block of code should run when that event does occur. That’s it. You now have the advantage that if, for example you are consuming the click event on a button, if the button is disabled, it automatically ceases to raise click events, so you don’t have to do any state validation.