54 lines
1.2 KiB
C
54 lines
1.2 KiB
C
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
#include "sm.h"
|
|
|
|
static int sm_try_transitions(struct sm_transition *table, struct sm_context *machine, sm_event_id event);
|
|
|
|
void sm_put_event(struct sm_context *machine, sm_event_id event)
|
|
{
|
|
struct sm_state *st;
|
|
|
|
assert(machine != NULL);
|
|
assert(machine->current_state != NULL);
|
|
|
|
st = machine->current_state;
|
|
|
|
if (!sm_try_transitions(machine->global_transitions, machine, event)) {
|
|
sm_try_transitions(st->transitions, machine, event);
|
|
}
|
|
}
|
|
|
|
static int sm_try_transitions(struct sm_transition *table, struct sm_context *machine, sm_event_id event)
|
|
{
|
|
struct sm_state *st = machine->current_state;
|
|
struct sm_transition *tr;
|
|
int matched = 0;
|
|
|
|
for (tr = table; tr->event_matcher != NULL; tr++) {
|
|
if (tr->event_matcher(event)) {
|
|
|
|
if (tr->transition_target && st->exit_action) {
|
|
st->exit_action(machine, event);
|
|
}
|
|
|
|
if (tr->transition_action) {
|
|
tr->transition_action(machine, event);
|
|
}
|
|
|
|
if (tr->transition_target) {
|
|
st = tr->transition_target;
|
|
if (tr->transition_target->entry_action) {
|
|
st->entry_action(machine, event);
|
|
}
|
|
machine->current_state = st;
|
|
}
|
|
|
|
matched = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return matched;
|
|
}
|