|
|

|
|
Listing 2a
hsm.c-C
implementation
|
static Msg const startMsg = { START_EVT };
static Msg const entryMsg = { ENTRY_EVT };
static Msg const exitMsg = { EXIT_EVT };
#define MAX_STATE_NESTING 8
/* Hsm ctor */
void HsmCtor(Hsm *me, char const *name, EvtHndlr topHndlr) {
StateCtor(&me->top, "top", 0, topHndlr);
me->name = name;
}
/* enter and start the top state */
void HsmOnStart(Hsm *me) {
State *entryPath[MAX_STATE_NESTING];
register State **trace;
register State *s;
me->curr = &me->top;
me->next = 0;
StateOnEvent(me->curr, me, &entryMsg);
while (StateOnEvent(me->curr, me, &startMsg), me->next) {
for (s = me->next, trace = entryPath, *trace = 0;
s != me->curr; s = s->super)
*(++trace) = s; /* trace path to target */
while (s = *trace-) /* retrace entry from source */
StateOnEvent(s, me, &entryMsg);
me->curr = me->next;
me->next = 0;
}
}
/* state machine "engine" */
void HsmOnEvent(Hsm *me, Msg const *msg) {
State *entryPath[MAX_STATE_NESTING];
register State **trace;
register State *s;
for (s = me->curr; s; s = s->super) {
if ((msg = StateOnEvent(s, me, msg)) == 0) {;
if (me->next) { /* state transition taken? */
for (s = me->next, trace = entryPath, *trace = 0;
s != me->curr; s
= s->super)
*(++trace) = s; /* trace path to target */
while (s = *trace-) /* retrace entry from LCA */
StateOnEvent(s, me, &entryMsg);
me->curr = me->next;
me->next = 0;
while (StateOnEvent(me->curr, me, &startMsg),
me->next) {
for (s = me->next->super, trace = entryPath,
*trace = 0; s != me->curr; s = s->super)
*(++trace) = s; /* record path to target */
while (s =
*trace-) /* retrace the entry */
StateOnEvent(s, me, &entryMsg);
me->curr = me->next;
me->next = 0;
}
}
break; /* event processed */
}
}
}
/* exit current states and all superstates up to LCA */
void HsmExit_(Hsm *me, unsigned char toLca) {
register State *s;
for (s = me->curr; toLca > 0; -toLca, s = s->super)
StateOnEvent(s, me, &exitMsg);
me->curr = s;
}
/* find # of levels to Least
Common Ancestor */
unsigned char HsmToLCA_(Hsm *me, State *target) {
State *s, *t;
unsigned char toLca = 1;
for (s = me->curr->super; s != 0; ++toLca, s = s->super)
for (t = target; t != 0; t = t->super)
if (s == t)
return toLca;
return 0;
}
|
|
Listing 2b hsm.cpp-C++ implementation
|
static Msg const startMsg = { START_EVT };
static Msg const entryMsg = { ENTRY_EVT };
static Msg const exitMsg = { EXIT_EVT };
#define MAX_STATE_NESTING 8
/* Hsm ctor */
Hsm::Hsm(char const *name, EvtHndlr topHndlr)
: top("top", 0, topHndlr) { this->name = name; }
/* enter and start the top state */
void Hsm::onStart() {
State *entryPath[MAX_STATE_NESTING];
register State **trace;
register State *s;
curr = ⊤
next = 0;
curr->onEvent(this, &entryMsg);
while (curr->onEvent(this, &startMsg), next) {
for (s = next, trace = entryPath, *trace = 0;
s != curr; s = s->super)
*(++trace) = s; /* trace path to target */
while (s = *trace-) /* retrace entry from source */
s->onEvent(this, &entryMsg);
curr = next;
next = 0;
}
}
/* state machine "engine" */
void Hsm::onEvent(Msg const *msg) {
State *entryPath[MAX_STATE_NESTING];
register State **trace;
register State *s;
for (s = curr; s; s = s->super) {
if ((msg = s->onEvent(this, msg)) == 0) { /*processed?*/
if (next) { /* state transition taken? */
for (s = next, trace = entryPath, *trace = 0;
s != curr; s = s->super)
*(++trace) = s; /* trace path to target */
while (s = *trace-) /* retrace entry from LCA */
s->onEvent(this, &entryMsg);
curr =
next;
next = 0;
while (curr->onEvent(this, &startMsg), next) {
for (s = next->super, trace = entryPath, *trace=0;
s != curr; s = s->super)
*(++trace) = s; /* record path to target */
while (s = *trace-) /* retrace the entry */
s->onEvent(this, &entryMsg);
curr = next;
next = 0;
}
}
Listing 2b, cont'd. hsm.cpp-C++ implementation
break; /* event
processed */
}
}
}
/* exit current states and all superstates up to LCA */
void Hsm::exit_(unsigned char toLca) {
register State *s;
for (s = curr; toLca > 0; -toLca, s = s->super)
s->onEvent(this, &exitMsg);
curr = s;
}
/* find # of levels to Least Common Ancestor */
unsigned char Hsm::toLCA_(State *target) {
State *s, *t;
unsigned char toLca = 1;
for (s = curr->super; s != 0; ++toLca, s = s->super)
for (t = target; t != 0; t = t->super)
if (s == t)
return toLca;
return 0;
}
|
|
Back
|
|
|
|
Ready to take that job and shove it?
|
|