EventMachine

A state machine with simplified transitions - a wrapper around a state collection. State-dependent transitions should be implemented using beforeEach/afterEach hooks. A transition can be canceled by returning false from the any beforeEach listeners. The machine has an initial state and a set of alternative states (loops are permitted). Any state can transition to any other state (the initial state is unreachable after transitioning away from it).

Members

Aliases

EventType
alias EventType = Event!T

The events' type.

State
alias State = State_

An alias to the $(DDOC_PSYMBOL State_) parameter.

Functions

go
void go(EventType.ParamTypes params)

Calls all the registered listeners in order. Can also be called using the alias go!#{stateName}, where the state name is a string.

off
void off(EventType.ListenerType[] listeners)

A function for removing listeners from the state event.

on
void on(EventType.ListenerType[] listeners)

A function for appending listeners to the state event. Can also be called using the alias on!#{stateName}, where the state name is a string.

state
State state()

The active state.

Mixins

__anonymous
mixin bindStateTransitions!s
Undocumented in source.

Variables

afterEach
Event!(void delegate(State, State)) afterEach;

The hook to be executed after a successful transition.

beforeEach
Event!(bool delegate(State, State)) beforeEach;

The hook to be executed before any transition. If false is returned, no transition occurs.

Mixed In Members

From mixin bindStateTransitions!s

on
void on(EventType.ListenerType[] listeners)
Undocumented in source. Be warned that the author may not have intended to support it.
off
void off(EventType.ListenerType[] listeners)
Undocumented in source. Be warned that the author may not have intended to support it.
go
void go(EventType.ParamTypes params)
Undocumented in source. Be warned that the author may not have intended to support it.

Parameters

State_

An enum of available states.

T

The listener type this event contains. Default is void delegate().

Examples

An event machine stores it's state.

enum State { stateA, stateB }
alias Machine = EventMachine!State;
Machine machine;

assert(machine.state == State.stateA, "The machine is not initially in it's default state");
machine.go!(State.stateB)();
assert(machine.state == State.stateB, "The machine does not navigate to other states");
machine.go!(State.stateB)();
assert(machine.state == State.stateB, "The machine does not permit loops");
machine.go!(State.stateA)();
assert(machine.state == State.stateA, "The machine does not navigate to other states");

An event machine supports enums with negative values.

enum State { stateA = -21, stateB = 3 }
alias Machine = EventMachine!State;
Machine machine;

assert(machine.state == State.stateA, "The machine is not initially in it's default state");
machine.go!(State.stateB)();
assert(machine.state == State.stateB, "The machine does not navigate to other states");

beforeEach and afterEach run appropriately.

enum State { stateA, stateB }
alias Machine = EventMachine!(State, void delegate());
Machine machine;

bool beforeEachRan, afterEachRan;

machine.beforeEach ~= (oldState, newState) {
    assert(oldState == State.stateA, "The machine doesn't move from it's initial state");
    assert(newState == State.stateB, "The machine doesn't move to a non-initial state");
    beforeEachRan = true;
    return true;
};

machine.afterEach ~= (oldState, newState) {
    afterEachRan = true;
    assert(oldState == State.stateA, "The machine doesn't move from it's initial state");
    assert(newState == State.stateB, "The machine doesn't move to a non-initial state");
};

machine.go!(State.stateB)();
assert(beforeEachRan, "The beforeEach hook has been ran");
assert(afterEachRan, "The afterEach hook has been ran");

beforeEach can cancel subsequent events.

enum State { stateA, stateB }
alias Machine = EventMachine!(State, void delegate());
Machine machine;

machine.beforeEach ~= (oldState, newState) {
    return false;
};

machine.on!(State.stateA)(() {
    assert(false, "The machine moves to stateA despite the failing beforeEach check");
});

machine.go!(State.stateA)();

Meta