modifications for ease/pardef

This commit is contained in:
zolliker
2005-09-05 08:02:08 +00:00
parent e23dfd8097
commit 5b25f75fc9
2 changed files with 93 additions and 43 deletions

114
fsm.c
View File

@ -31,36 +31,56 @@ struct Fsm {
static Fsm *fsm = NULL; static Fsm *fsm = NULL;
static FsmFunc callFunc = NULL;
void FsmWait(long delay) { void FsmWait(long delay) {
assert(fsm); assert(fsm);
fsm->till = time(NULL) + delay; fsm->till = time(NULL) + delay;
} }
int FsmTaskHandler(Fsm *this) { void FsmSpeed(Fsm *task) {
assert(task);
if (task->till != 0) task->till = time(NULL);
}
int FsmTaskHandler(Fsm *task) {
long line; long line;
if (this->pause) { if (task->pause) {
this->handler(this->obj); task->handler(task->obj);
return 1; return 1;
} }
if (this->pc >= 0) { /* this->pc < 0 means stop current function */ if (task->pc >= 0) { /* task->pc < 0 means stop current function */
if (this->till != 0) { if (task->till != 0) {
if (time(NULL) < this->till) return 1; /* wait */ if (time(NULL) < task->till) return 1; /* wait */
this->till = 0; task->till = 0;
} }
if (this->handler(this->obj) == 0) { if (task->handler(task->obj) == 0) {
return 1; /* wait for answer */ return 1; /* wait for answer */
} }
fsm = this; fsm = task;
this->pc = this->func(this->pc, this->obj); task->pc = task->func(task->pc, task->obj);
while (callFunc) {
assert(fsm->sp < MAXSTACK);
fsm->stack[fsm->sp].pc = task->pc;
fsm->stack[fsm->sp].func = fsm->func;
fsm->sp++;
fsm->pc = 0;
fsm->func = callFunc;
callFunc = NULL;
task->pc = fsm->func(fsm->pc, fsm->obj);
}
fsm = NULL; fsm = NULL;
} }
if (this->pc <= 0) { if (task->pc <= 0) {
if (this->sp == 0) return 0; if (task->sp == 0) {
this->sp--; return (task->obj != NULL); /* finish task only when explicitely stopped */
this->pc = this->stack[this->sp].pc; }
this->func = this->stack[this->sp].func; if (task->sp > 0) {
task->sp--;
task->pc = task->stack[task->sp].pc;
task->func = task->stack[task->sp].func;
}
} }
return 1; return 1;
} }
@ -69,44 +89,55 @@ void FsmKill(void *data) {
free(data); free(data);
} }
Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func) { void FsmRestartTask(Fsm *task, FsmFunc func) {
Fsm *new; task->pc = 0;
task->func = func;
new=malloc(sizeof *new); task->sp = 0;
new->obj = obj; task->pause = 0;
new->pc = 0; task->till = 0;
new->func = func;
new->handler = handler;
new->sp = 0;
new->pause = 0;
new->till = 0;
return new;
} }
int FsmStop(Fsm *this, FsmFunc func) { Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func) {
Fsm *task;
task=malloc(sizeof *task);
task->obj = obj;
task->handler = handler;
FsmRestartTask(task, func);
return task;
}
int FsmStop(Fsm *task, FsmFunc func) {
int i; int i;
if (this == NULL) this = fsm; if (task == NULL) task = fsm;
assert(this); assert(task);
for (i=0; i < this->sp; i++) { for (i=0; i < task->sp; i++) {
if (func == this->stack[i].func) { if (func == task->stack[i].func) {
break; break;
} }
} }
if (i == this->sp) { if (i == task->sp) { /* not found on stack */
if (func != this->func) return 0; if (func != task->func) return 0; /* is also not running function */
} else { } else {
this->sp = i; task->sp = i; /* unwind stack to level i */
} }
this->pc = -1; task->pc = -1; /* leave function */
return 1; return 1;
} }
void FsmPause(Fsm *this, int pause) { void FsmStopTask(Fsm *task) {
this->pause = pause; assert(task);
task->sp = 0;
task->pc = -1;
task->obj = NULL;
} }
long FsmCall(long pc, FsmFunc func) { void FsmPause(Fsm *task, int pause) {
task->pause = pause;
}
long FsmCallOld(long pc, FsmFunc func) {
assert(fsm); assert(fsm);
assert(fsm->sp < MAXSTACK); assert(fsm->sp < MAXSTACK);
fsm->stack[fsm->sp].pc = pc; fsm->stack[fsm->sp].pc = pc;
@ -116,3 +147,8 @@ long FsmCall(long pc, FsmFunc func) {
fsm->pc = 0; fsm->pc = 0;
return fsm->func(fsm->pc, fsm->obj); return fsm->func(fsm->pc, fsm->obj);
} }
void FsmCall(FsmFunc func) {
assert(fsm);
callFunc = func;
}

22
fsm.h
View File

@ -38,7 +38,7 @@ typedef long (*FsmFunc)(long pc, void *obj);
#define FSM_WAIT(DELTA) FsmWait(DELTA); return __LINE__; case __LINE__: #define FSM_WAIT(DELTA) FsmWait(DELTA); return __LINE__; case __LINE__:
/* waiting DELTA seconds */ /* waiting DELTA seconds */
#define FSM_CALL(FUNC) return FsmCall(__LINE__, (FsmFunc)FUNC); case __LINE__: #define FSM_CALL(FUNC) return FsmCallOld(__LINE__, (FsmFunc)FUNC); case __LINE__:
/* call a task subfunction */ /* call a task subfunction */
typedef int (*FsmHandler)(void *obj); typedef int (*FsmHandler)(void *obj);
@ -48,6 +48,9 @@ typedef int (*FsmHandler)(void *obj);
Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func); Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func);
/* start a task and return a pointer to it */ /* start a task and return a pointer to it */
void FsmRestartTask(Fsm *task, FsmFunc func);
/* restart a stopped task */
int FsmTaskHandler(Fsm *task); int FsmTaskHandler(Fsm *task);
/* this is the task handler. /* this is the task handler.
the argument should be the pointer obtained from FsmStartTask the argument should be the pointer obtained from FsmStartTask
@ -56,11 +59,22 @@ int FsmTaskHandler(Fsm *task);
int FsmStop(Fsm *task, FsmFunc func); int FsmStop(Fsm *task, FsmFunc func);
/* stop a function. returns to the caller next time */ /* stop a function. returns to the caller next time */
void FsmPause(Fsm *this, int pause); void FsmStopTask(Fsm *task);
/* stops the task, it will be killed after next execution */
void FsmKill(void *task);
/* kill the task */
void FsmPause(Fsm *task, int pause);
/* pause=1: pause task, pause=0: continue task */ /* pause=1: pause task, pause=0: continue task */
long FsmCall(long pc, FsmFunc func); long FsmCallOld(long pc, FsmFunc func);
void FsmWait(long delay);
/* these functions are used in fsm macros and must not be called directly */ /* these functions are used in fsm macros and must not be called directly */
void FsmCall(FsmFunc func);
void FsmWait(long delay);
void FsmSpeed(Fsm *task);
#endif #endif