- extended evcontroller
- remote objects - new ev drivers for oxford IPS,ITC,ILM and LC M.Z.
This commit is contained in:
117
fsm.c
Normal file
117
fsm.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
fsm.c
|
||||
|
||||
a finite state machine within sics
|
||||
|
||||
M. Zolliker, Aug 2004
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include "fsm.h"
|
||||
|
||||
#define MAXSTACK 8
|
||||
|
||||
typedef struct {
|
||||
long pc;
|
||||
FsmFunc func;
|
||||
} StackItem;
|
||||
|
||||
struct Fsm {
|
||||
void *obj;
|
||||
FsmHandler handler;
|
||||
long pc;
|
||||
FsmFunc func;
|
||||
time_t till;
|
||||
int pause;
|
||||
int sp;
|
||||
StackItem stack[MAXSTACK];
|
||||
};
|
||||
|
||||
|
||||
static Fsm *fsm = NULL;
|
||||
|
||||
void FsmWait(long delay) {
|
||||
assert(fsm);
|
||||
fsm->till = time(NULL) + delay;
|
||||
}
|
||||
|
||||
int FsmTaskHandler(Fsm *this) {
|
||||
long line;
|
||||
|
||||
if (this->pause) {
|
||||
this->handler(this->obj);
|
||||
return 1;
|
||||
}
|
||||
if (this->pc >= 0) { /* this->pc < 0 means stop current function */
|
||||
if (this->till != 0) {
|
||||
if (time(NULL) < this->till) return 1; /* wait */
|
||||
this->till = 0;
|
||||
}
|
||||
if (this->handler(this->obj) == 0) {
|
||||
return 1; /* wait for answer */
|
||||
}
|
||||
fsm = this;
|
||||
this->pc = this->func(this->pc, this->obj);
|
||||
fsm = NULL;
|
||||
}
|
||||
if (this->pc <= 0) {
|
||||
if (this->sp == 0) return 0;
|
||||
this->sp--;
|
||||
this->pc = this->stack[this->sp].pc;
|
||||
this->func = this->stack[this->sp].func;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FsmKill(void *data) {
|
||||
free(data);
|
||||
}
|
||||
|
||||
Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func) {
|
||||
Fsm *new;
|
||||
|
||||
new=malloc(sizeof *new);
|
||||
new->obj = obj;
|
||||
new->pc = 0;
|
||||
new->func = func;
|
||||
new->handler = handler;
|
||||
new->sp = 0;
|
||||
new->till = 0;
|
||||
return new;
|
||||
}
|
||||
|
||||
int FsmStop(Fsm *this, FsmFunc func) {
|
||||
int i;
|
||||
|
||||
if (this == NULL) this = fsm;
|
||||
assert(this);
|
||||
for (i=0; i < this->sp; i++) {
|
||||
if (func == this->stack[i].func) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == this->sp) {
|
||||
if (func != this->func) return 0;
|
||||
} else {
|
||||
this->sp = i;
|
||||
}
|
||||
this->pc = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FsmPause(Fsm *this, int pause) {
|
||||
this->pause = pause;
|
||||
}
|
||||
|
||||
long FsmCall(long pc, FsmFunc func) {
|
||||
assert(fsm);
|
||||
assert(fsm->sp < MAXSTACK);
|
||||
fsm->stack[fsm->sp].pc = pc;
|
||||
fsm->stack[fsm->sp].func = fsm->func;
|
||||
fsm->sp++;
|
||||
fsm->func = func;
|
||||
fsm->pc = 0;
|
||||
return fsm->func(fsm->pc, fsm->obj);
|
||||
}
|
||||
Reference in New Issue
Block a user