SWEN20003 Object Oriented Software Development
Assess Yourself
Describe the Observer pattern and the general “class” of problems it can
be applied to.
Provide at least one real-world example where the Observer pattern could
be applied.
Games and Event Driven Programming SWEN20003 1 / 50
Assess Yourself
The Observer pattern (also known as the publish/subscribe model) is used
in situations where one or more classes (the observers) must observe and
react to another object’s (the subject) state.
Example: A robotic system has a number of sensors that are observed by
the robot’s central control system. When a sensor is activated, the central
system is notified so the appropriate response can be taken.
Games and Event Driven Programming SWEN20003 2 / 50
SWEN20003
Object Oriented Software Development
Games and Event Driven Programming
Games and Event Driven Programming SWEN20003 3 / 50
The Road So Far
Java Foundations
Classes and Objects
Abstraction
Advanced Java
I Exception Handling
I Generic Classes
I Generic Programming
I Design Patterns
I Software Testing and Design
Software Development Tools
Games and Event Driven Programming SWEN20003 4 / 50
Lecture Objectives
After this lecture you will be able to:
Describe the event-driven programming paradigm
Describe where it can be applied, and how
Implement basic event-driven programs in Java
Describe some basic techniques in game design
Games and Event Driven Programming SWEN20003 5 / 50
Event Programming
Games and Event Driven Programming SWEN20003 6 / 50
How do programs work?
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
String firstName = scanner.nextLine();
String lastName = scanner.nextLine();
String fullName = String.format(“%s %s”,
firstName, lastName);
System.out.format(“Welcome %s!\n”, fullName);
}
Games and Event Driven Programming SWEN20003 7 / 50
How do programs work?
Step 1: Create variable scanner
Step 2: Instantiate Scanner object and allocate to scanner variable
Step 3: Create variable firstName
Step 4: Call readLine method in scanner
Step 5: Allocate result to firstName
Step 6: …
Step 7: …
Games and Event Driven Programming SWEN20003 8 / 50
How do programs work?
Keyword
Sequential Programming: A program that is run (more or less) top to
bottom, starting at the beginning of the main method, and concluding at
its end.
Useful for “static” programs
Constant, unchangeable logic
Execution is the same (or very similar) each time
Let’s make our programs more “dynamic”…
Games and Event Driven Programming SWEN20003 9 / 50
Event-Driven Programming
Keyword
State: The properties that define an object or device; for example,
whether it is “active”.
Keyword
Event: Created when the state of an object/device/etc. is altered.
Keyword
Callback: A method triggered by an event.
Games and Event Driven Programming SWEN20003 10 / 50
Event-Driven Programming
Keyword
Event-Driven Programming: Using events and callbacks to control the
flow of a program’s execution.
Have we seen similar behaviour before?
Exception handling
Observer pattern
Games and Event Driven Programming SWEN20003 11 / 50
Event-Driven Programming
What makes this approach better?
Using an event-driven approach allows us to:
Better encapsulate classes by hiding their behaviour
Avoid having to explicitly send information about the input; instead it
is automatically passed as part of the callback
Easily add/remove behaviour to classes
Easily add/remove additional responses
Games and Event Driven Programming SWEN20003 12 / 50
Assess Yourself
When playing a game, what events might we respond to?
Mouse
Keyboard
Touch
Controller (e.g. XBox controller)
Time
Assuming we could respond to those events, what features could we add? Think
about games you may have played, and how they work.
Mouse: Menu buttons, GUI controls, click-to-move
Keyboard: movement, “shooting”, special powers
Touch/Controller: similar to keyboard
Time: time-based completion, do-x-every-second (recover health, generate
enemy)
Games and Event Driven Programming SWEN20003 13 / 50
The Event Loop
public class Robot {
public static void main(String args[]) {
while (true) {
if (isCommandSent()) {
respondToCommand();
} else if (isLowPower()) {
respondToLowPower();
} else if (isStuck()) {
respondToIsStuck();
} else if (hasCollided()) {
respondToCollision();
} else if (isSensorBroken()) {
respondToBrokenSensor();
} else if (…) {
…
}
}
}
}
What would you say is the “problem” in this code?
Games and Event Driven Programming SWEN20003 14 / 50
The Event Loop
Keyword
Polling: (also called sampling) relies on the program actively enquiring
about the state of an object/device/etc.
What are some disadvantages of this approach?
Lots of “waiting” for something to happen
Lots of time/effort wasted “asking”
Always responds in the same order
Can’t “escape” from one method to respond to something else
(potentially) urgent
Games and Event Driven Programming SWEN20003 15 / 50
Asynchronous Programming
Keyword
Interrupt: A signal generated by hardware or software indicating an event
that needs immediate CPU attention.
Keyword
Interrupt Service Routine: Event-handling code to respond to interrupt
signals.
Interrupts are used to control program flow at a very low level,
immediately taking control of the program, e.g.:
Exception/error handling
Activating a sleeping process/task
Device drivers (mouse, keyboard)
Games and Event Driven Programming SWEN20003 16 / 50
Robotics Case Study (Bad)
public class Robot {
public static void main(String args[]) {
while (true) {
if (isCommandSent()) {
respondToCommand();
} else if (isLowPower()) {
respondToLowPower();
} else if (isStuck()) {
respondToIsStuck();
} else if (hasCollided()) {
respondToCollision();
} else if (isSensorBroken()) {
respondToBrokenSensor();
} else if (…) {
…
}
}
}
}
Games and Event Driven Programming SWEN20003 17 / 50
Robotics Case Study (Good)
// Operates in a separate thread
public class DistanceSensor {
public void detectCollision() {
while (true) {
// If a collision is imminent,
// we should alert the main thread
if (destructionImminent()) {
mainThread.interrupt();
}
}
}
}
Note: No one builds robots in Java.
Games and Event Driven Programming SWEN20003 18 / 50
Event-Driven Programming
Real-world examples:
Graphical User Interfaces (GUIs)
Web development/Javascript
Embedded Systems/Hardware
Event-driven and asynchronous programming are very powerful techniques,
and good tools to have in your arsenal.
Games and Event Driven Programming SWEN20003 19 / 50
Game Design
Games and Event Driven Programming SWEN20003 20 / 50
Inheritance-based Game Design
The most obvious way to design a game in an object-oriented language is
to use inheritance. We could
create an Entity abstract base class to represent game objects
inherit from Entity to create new types of objects
take advantage of polymorphism
use the Factory design pattern
Games and Event Driven Programming SWEN20003 21 / 50
Inheritance
Many distinct Entitys may have similar behaviours.
All Pegs in Shadow Bounce have a behaviour when struck by a ball, so
one obvious approach is a design like this:
Games and Event Driven Programming SWEN20003 22 / 50
Zombies and bandits and bats, oh my!
You are designing a role-playing game, and you are told monsters come in
two varieties; aggressive monsters that chase and attack the player, and
passive monsters that simply try to run away.
You decide to implement this using inheritance.
Games and Event Driven Programming SWEN20003 23 / 50
UML diagram
Games and Event Driven Programming SWEN20003 24 / 50
Pitfall: Flexibility
What if we wanted a monster that was sometimes passive and sometimes
aggressive?
inherit from both – can’t do that…
use an interface? Doesn’t really fit…
Games and Event Driven Programming SWEN20003 25 / 50
An example game design
Games and Event Driven Programming SWEN20003 26 / 50
Pitfall: Complexity
This is a fairly small game, and that diagram is already looking pretty
terrifying.
It’s hard to tell from the small image, but there’s also lots of data
awkwardly passed around.
Games and Event Driven Programming SWEN20003 27 / 50
Solution: Composition over inheritance
Let’s try a different approach. What if we broke down functionality of each
object into its key Components? That is, those parts that describe it
completely?
An Entity then becomes a composition of its Components.
Games and Event Driven Programming SWEN20003 28 / 50
A monster as a group of components
class Monster {
private Position position;
private Image image;
private Aggressor aggressor;
public void update() {
image.update(position);
aggressor.update(position);
}
}
Games and Event Driven Programming SWEN20003 29 / 50
Fixing flexibility
Let’s return to the problem of a Monster that may sometimes be
aggressive, and sometimes not aggressive.
At the moment, the Monster is hard-coded to update its Aggressor
component. We would like to be able to switch this on and off.
Games and Event Driven Programming SWEN20003 30 / 50
Monster’s Components
Games and Event Driven Programming SWEN20003 31 / 50
Putting the pieces together
Let’s write the classes. We need an Entity class, which is just a list of
components.
class Entity {
private List
public void addComponent(Component component) {
components.add(component);
}
public void update() {
for (Component c : components) {
if (c.getEnabled()) c.update();
}
}
}
Games and Event Driven Programming SWEN20003 32 / 50
Continued…
Now we need an abstract Component that can be updated and rendered,
as well as switched on and off.
abstract class Component {
private boolean enabled = true;
public boolean getEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public abstract void update();
}
Games and Event Driven Programming SWEN20003 33 / 50
The road so far
Entity monster = new Entity();
monster.addComponent(new Position());
monster.addComponent(new Image());
monster.addComponent(new Aggressor());
By doing this, we have separated our complex inheritance diagram into
Entity objects which are compositions of Component objects. As a
bonus, we can easily reuse Components between different Entitys!
This is called composition over inheritance, and is an important tool to
have in your arsenal.
Games and Event Driven Programming SWEN20003 34 / 50
Monster’s Components
Games and Event Driven Programming SWEN20003 35 / 50
Components interacting with others
To implement an Image component, we need to look up the Position
component. We would like to have something like this:
class Image extends Component {
private ImageRender image;
@Override
public void update() {
Position position = something.getComponent(Position);
image.draw(position.getX(), position.getY());
}
}
What is this something? The most sensible choice is the Entity the
component is attached to. (Why?)
Games and Event Driven Programming SWEN20003 36 / 50
Implementing lookup
We need to add some code to our Component base class:
abstract class Component {
private Entity entity;
public Entity getEntity() { return entity; }
public Component(Entity entity) { this.entity = entity; }
}
Applying this in practice looks something like:
Entity monster = new Entity();
monster.addComponent(new Position(monster));
monster.addComponent(new Image(monster));
monster.addComponent(new Aggressor(monster));
Games and Event Driven Programming SWEN20003 37 / 50
Components interacting with others
To implement an Image component, we need to look up the Position
component. We would like to have something like this:
class Image extends Component {
private ImageRender image;
@Override
public void update() {
Position position = getEntity().getComponent(Position);
image.draw(position.getX(), position.getY());
}
}
Now, how do we implement getComponent? We need to somehow pass a
type as an argument.
Games and Event Driven Programming SWEN20003 38 / 50
Reflection
You might think to try using generics to solve this problem. Unfortunately,
Java generics don’t let us use e.g. instanceof.
However, Java lets us look up the class of an object!
class Entity {
public
for (Component c : components) {
if (c.getClass().equals(classObj)) {
return (T) c;
}
}
return null;
}
}
Games and Event Driven Programming SWEN20003 39 / 50
Implementing Image
This lets us do something like this:
class Image extends Component {
private ImageRender image;
@Override
public void update() {
Position position = getEntity()
.getComponent(Position.class);
image.draw(position.getX(), position.getY());
}
}
Note: reflection is not examinable.
Games and Event Driven Programming SWEN20003 40 / 50
Summary
The entity-component approach is an example of a principle called
composition over inheritance. This principle is a response to the
problems caused by large, complex inheritance hierarchies, and tries to
simplify things by using composition instead where possible.
Games and Event Driven Programming SWEN20003 41 / 50
Questions?
Feel free to ask us about embedded programming or composition over
inheritance.
Games and Event Driven Programming SWEN20003 42 / 50
MST Drawings
The highlight reel can be found on Google Drive!
Games and Event Driven Programming SWEN20003 43 / 50
https://drive.google.com/open?id=19qvIUr5WRiwV-LSdgeUQ10AfzWhihQ06
MST Drawings – The Cute
Games and Event Driven Programming SWEN20003 44 / 50
MST Drawings – The Good
Games and Event Driven Programming SWEN20003 45 / 50
MST Drawings – The Sad
Games and Event Driven Programming SWEN20003 46 / 50
MST Drawings – The Random
Games and Event Driven Programming SWEN20003 47 / 50
MST Drawings – The Tributes to Matt
Games and Event Driven Programming SWEN20003 48 / 50
MST Drawings – The Funny
Games and Event Driven Programming SWEN20003 49 / 50
Metrics
You should be able to explain the various keywords and concepts
introduced in this lecture, including:
Sequential, event-driven, and asynchronous programming
Examples of event-driven systems
Basic game design, such as the Entity Component approach
Given the appropriate tools/documentation in the exam, you should also
be able to:
Analyse an event-driven system, to determine its behaviour
Implement event-handling components in an event-driven system
Games and Event Driven Programming SWEN20003 50 / 50