Contents |
The Exclusively Active design pattern restricts active behaviour (the definition of which is different in different applications) to a single Exclusively Active instance.
When UpdateAll is called, the active instance has
UpdateActive() invoked, and all other instances have
UpdateInactive() invoked.
The only way to become active is to call Activate(), which
'steals' the active state from any currently active instance.
class ExclusivelyActive {
public:
ExclusivelyActive() -> if(instances == null)
instances = new List<ExclusivelyActive>
instances.Add(this)
Activate() -> if(Active != this)
if(Active != null)
Active.Deactivate
Active = this
Deactivate() -> if(Active == this)
Active = null
static UpdateAll() -> for each ExclusivelyActive ea in instances
if(Active == ea) ea.updateActive
else ea.updateInactive
Destroy() -> if(Active != null)
Active.Deactivate
if(instances != null) instances.Remove(this)
static ExclusivelyActive Active [get]
protected:
updateActive()
updateInactive()
static List<ExclusivelyActive> instances
}
Polymorphic version - inherit classes from this to make only one instance of the derived classes active at a time:
abstract class ExclusivelyActiveBase {
public:
ExclusivelyActiveBase() -> if(instances == null)
instances = new List<ExclusivelyActiveBase>
instances.Add(this)
Activate() -> if(Active != this)
if(Active != null)
Active.Deactivate
Active = this
activate()
Deactivate() -> if(Active == this)
Active = null
deactivate()
static UpdateAll() -> for each ExclusivelyActiveBase ea in instances
if(Active == ea) ea.updateActive
else ea.updateInactive
Destroy() -> if(Active != null)
Active.Deactivate
if(instances != null) instances.Remove(this)
static ExclusivelyActiveBase Active [get]
protected:
abstract updateActive() │ all these must be implemented by
abstract updateInactive() │ the derived classes
abstract activate() │
abstract deactivate() │
static List<ExclusivelyActiveBase> instances
}
/* This design ensures that only a single InputReceiver receives
* input from the InputController class; thus, no instance is able
* to 'steal' input from another without EnableInput being called.
*/
class InputReceiver {
public static InputReceiver ActiveReceiver = null;
static List<InputReceiver> instances;
public InputReceiver() {
if(instances == null) instances = new List<InputReceiver>();
instances.Add(this);
}
// Activate
public void EnableInput() {
if(ActiveReceiver != this) {
if(ActiveReceiver != null) ActiveReceiver.DisableInput();
ActiveReceiver = this;
}
}
// Deactivate
public void DisableInput() {
if(ActiveReceiver == this) ActiveReceiver = null;
}
/* The InputEvents are dequeued in the input controller which
* calls this method. The InputEvents can be private and thus
* access to them are locked to the active InputReceiver.
*/
public static UpdateAll(List<InputEvent> inputEvents) {
foreach(InputReceiver m in instances) {
if(ActiveReceiver == m) m.updateActive(inputEvents);
else m.updateInactive();
}
}
// Active behaviour: get input
protected void updateActive(List<InputEvent> inputEvents) {
// do stuff with inputEvents
}
// Inactive behaviour: do nothing
protected void updateInactive() { }
}
class InputController {
// ...
public void Update() {
List<InputEvent> inputEvents = dequeueEvents();
InputReceiver.UpdateAll(inputEvents);
}
}