mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-14 09:50:05 +00:00
CPunch
9694ae67d8
- shell now has it's own task service, it's polled in shellC_poll() - default timeout for peers is 60 seconds, to change this edit the LAIKA_PEER_TIMEOUT in cnc.h
111 lines
3.4 KiB
C
111 lines
3.4 KiB
C
#include "lmem.h"
|
|
#include "ltask.h"
|
|
|
|
/* this is the only reason C11 support is needed, i cba to write windows/linux specific stuff to get the current time in ms
|
|
also side note: microsoft? more like micropenis */
|
|
long laikaT_getTime() {
|
|
struct timespec ts;
|
|
timespec_get(&ts, TIME_UTC);
|
|
return ts.tv_sec*1000 + ts.tv_nsec/1000000; /* convert time (seconds & nanoseconds) to milliseconds */
|
|
}
|
|
|
|
void laikaT_initTaskService(struct sLaika_taskService *service) {
|
|
service->headTask = NULL;
|
|
}
|
|
|
|
void laikaT_cleanTaskService(struct sLaika_taskService *service) {
|
|
struct sLaika_task *curr = service->headTask, *last;
|
|
|
|
/* walk though tasks, freeing all */
|
|
while (curr != NULL) {
|
|
last = curr;
|
|
curr = curr->next;
|
|
laikaM_free(last);
|
|
}
|
|
}
|
|
|
|
void scheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) {
|
|
struct sLaika_task *curr = service->headTask, *last = NULL;
|
|
|
|
task->scheduled = laikaT_getTime() + task->delta;
|
|
|
|
/* search list for task for which we're scheduled before */
|
|
while (curr != NULL && curr->scheduled < task->scheduled) {
|
|
last = curr;
|
|
curr = curr->next;
|
|
}
|
|
|
|
/* if we stopped at the first head item, set it */
|
|
if (curr == service->headTask) {
|
|
task->next = service->headTask;
|
|
service->headTask = task;
|
|
} else {
|
|
/* add to list */
|
|
task->next = curr;
|
|
if (last)
|
|
last->next = task;
|
|
}
|
|
}
|
|
|
|
void unscheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) {
|
|
struct sLaika_task *curr = service->headTask, *last = NULL;
|
|
|
|
if (task == service->headTask) { /* if task is root, set root to next */
|
|
service->headTask = task->next;
|
|
} else {
|
|
/* find in list */
|
|
while (curr != task) {
|
|
last = curr;
|
|
curr = curr->next;
|
|
}
|
|
|
|
/* unlink */
|
|
last->next = task->next;
|
|
task->next = NULL;
|
|
}
|
|
}
|
|
|
|
struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta, taskCallback callback, void *uData) {
|
|
struct sLaika_task *task = laikaM_malloc(sizeof(struct sLaika_task));
|
|
|
|
task->callback = callback;
|
|
task->uData = uData;
|
|
task->delta = delta;
|
|
task->next = NULL;
|
|
|
|
scheduleTask(service, task);
|
|
return task;
|
|
}
|
|
|
|
void laikaT_delTask(struct sLaika_taskService *service, struct sLaika_task *task) {
|
|
unscheduleTask(service, task);
|
|
laikaM_free(task);
|
|
}
|
|
|
|
void laikaT_pollTasks(struct sLaika_taskService *service) {
|
|
struct sLaika_task *last, *curr = service->headTask;
|
|
clock_t currTick = laikaT_getTime();
|
|
|
|
/* run each task, list is already sorted from closest scheduled task to furthest */
|
|
while (curr != NULL && curr->scheduled <= currTick) { /* if scheduled time is greater than currTime, all events that follow are also not scheduled yet */
|
|
/* walk to next task */
|
|
last = curr;
|
|
curr = curr->next;
|
|
|
|
/* reset task timer */
|
|
unscheduleTask(service, last);
|
|
scheduleTask(service, last);
|
|
|
|
/* dispatch task callback */
|
|
last->callback(service, last, currTick, last->uData);
|
|
}
|
|
}
|
|
|
|
/* will return the delta time in ms till the next event. -1 for no tasks scheduled */
|
|
int laikaT_timeTillTask(struct sLaika_taskService *service) {
|
|
if (service->headTask) {
|
|
int pause = service->headTask->scheduled - laikaT_getTime();
|
|
return (pause > 0) ? pause : 0;
|
|
} else
|
|
return -1; /* no tasks scheduled */
|
|
} |