1
/* Copyright 2011 Yorba Foundation
3
* This software is licensed under the GNU Lesser General Public License
4
* (version 2.1 or later). See the COPYING file in this distribution.
7
public class Geary.State.Machine {
8
private Geary.State.MachineDescriptor descriptor;
10
private Mapping[,] transitions;
11
private Transition? default_transition;
12
private bool locked = false;
13
private bool abort_on_no_transition = true;
14
private bool logging = false;
16
public Machine(MachineDescriptor descriptor, Mapping[] mappings, Transition? default_transition) {
17
this.descriptor = descriptor;
18
this.default_transition = default_transition;
20
// verify that each state and event in the mappings are valid
21
foreach (Mapping mapping in mappings) {
22
assert(mapping.state < descriptor.state_count);
23
assert(mapping.event < descriptor.event_count);
26
state = descriptor.start_state;
28
// build a transition map with state/event IDs (i.e. offsets) pointing directly into the
30
transitions = new Mapping[descriptor.state_count, descriptor.event_count];
31
for (int ctr = 0; ctr < mappings.length; ctr++) {
32
Mapping mapping = mappings[ctr];
33
assert(transitions[mapping.state, mapping.event] == null);
34
transitions[mapping.state, mapping.event] = mapping;
38
public uint get_state() {
42
public bool get_abort_on_no_transition() {
43
return abort_on_no_transition;
46
public void set_abort_on_no_transition(bool abort) {
47
abort_on_no_transition = abort;
50
public void set_logging(bool logging) {
51
this.logging = logging;
54
public bool get_logging() {
58
public uint issue(uint event, void *user = null) {
59
assert(event < descriptor.event_count);
60
assert(state < descriptor.state_count);
62
Mapping? mapping = transitions[state, event];
64
Transition transition = (mapping != null) ? mapping.transition : default_transition;
65
if (transition == null) {
66
string msg = "%s: No transition defined at %s for %s".printf(to_string(),
67
descriptor.get_state_string(state), descriptor.get_event_string(event));
69
if (get_abort_on_no_transition())
77
// guard against reentrancy ... don't want to use a non-reentrant lock because then
78
// the machine will simply hang; assertion is better to ferret out design flaws
82
uint old_state = state;
83
state = transition(state, event, user);
84
assert(state < descriptor.state_count);
90
message("%s: State transition from %s to %s due to event %s", to_string(),
91
descriptor.get_state_string(old_state), descriptor.get_state_string(state),
92
descriptor.get_event_string(event));
98
public string to_string() {
99
return "Machine %s".printf(descriptor.name);