From 5b25f75fc94d1e4dfc53d3960936f615e721326f Mon Sep 17 00:00:00 2001 From: zolliker Date: Mon, 5 Sep 2005 08:02:08 +0000 Subject: [PATCH] modifications for ease/pardef --- fsm.c | 114 ++++++++++++++++++++++++++++++++++++++-------------------- fsm.h | 22 +++++++++--- 2 files changed, 93 insertions(+), 43 deletions(-) diff --git a/fsm.c b/fsm.c index 4a06480..46cf878 100644 --- a/fsm.c +++ b/fsm.c @@ -31,36 +31,56 @@ struct Fsm { static Fsm *fsm = NULL; +static FsmFunc callFunc = NULL; void FsmWait(long delay) { assert(fsm); 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; - if (this->pause) { - this->handler(this->obj); + if (task->pause) { + task->handler(task->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 (task->pc >= 0) { /* task->pc < 0 means stop current function */ + if (task->till != 0) { + if (time(NULL) < task->till) return 1; /* wait */ + task->till = 0; } - if (this->handler(this->obj) == 0) { + if (task->handler(task->obj) == 0) { return 1; /* wait for answer */ } - fsm = this; - this->pc = this->func(this->pc, this->obj); + fsm = task; + 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; } - 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; + if (task->pc <= 0) { + if (task->sp == 0) { + return (task->obj != NULL); /* finish task only when explicitely stopped */ + } + if (task->sp > 0) { + task->sp--; + task->pc = task->stack[task->sp].pc; + task->func = task->stack[task->sp].func; + } } return 1; } @@ -69,44 +89,55 @@ 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->pause = 0; - new->till = 0; - return new; +void FsmRestartTask(Fsm *task, FsmFunc func) { + task->pc = 0; + task->func = func; + task->sp = 0; + task->pause = 0; + task->till = 0; } -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; - if (this == NULL) this = fsm; - assert(this); - for (i=0; i < this->sp; i++) { - if (func == this->stack[i].func) { + if (task == NULL) task = fsm; + assert(task); + for (i=0; i < task->sp; i++) { + if (func == task->stack[i].func) { break; } } - if (i == this->sp) { - if (func != this->func) return 0; + if (i == task->sp) { /* not found on stack */ + if (func != task->func) return 0; /* is also not running function */ } else { - this->sp = i; + task->sp = i; /* unwind stack to level i */ } - this->pc = -1; + task->pc = -1; /* leave function */ return 1; } -void FsmPause(Fsm *this, int pause) { - this->pause = pause; +void FsmStopTask(Fsm *task) { + 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->sp < MAXSTACK); fsm->stack[fsm->sp].pc = pc; @@ -116,3 +147,8 @@ long FsmCall(long pc, FsmFunc func) { fsm->pc = 0; return fsm->func(fsm->pc, fsm->obj); } + +void FsmCall(FsmFunc func) { + assert(fsm); + callFunc = func; +} diff --git a/fsm.h b/fsm.h index 5856211..f74abd3 100644 --- a/fsm.h +++ b/fsm.h @@ -38,7 +38,7 @@ typedef long (*FsmFunc)(long pc, void *obj); #define FSM_WAIT(DELTA) FsmWait(DELTA); return __LINE__; case __LINE__: /* 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 */ typedef int (*FsmHandler)(void *obj); @@ -48,6 +48,9 @@ typedef int (*FsmHandler)(void *obj); Fsm *FsmStartTask(void *obj, FsmHandler handler, FsmFunc func); /* start a task and return a pointer to it */ +void FsmRestartTask(Fsm *task, FsmFunc func); +/* restart a stopped task */ + int FsmTaskHandler(Fsm *task); /* this is the task handler. the argument should be the pointer obtained from FsmStartTask @@ -56,11 +59,22 @@ int FsmTaskHandler(Fsm *task); int FsmStop(Fsm *task, FsmFunc func); /* 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 */ -long FsmCall(long pc, FsmFunc func); -void FsmWait(long delay); +long FsmCallOld(long pc, FsmFunc func); /* 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