modifications for ease/pardef
This commit is contained in:
114
fsm.c
114
fsm.c
@ -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
22
fsm.h
@ -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
|
||||||
|
Reference in New Issue
Block a user