update
[mTask.git] / client / task.c
index 1c16ce5..12789ce 100644 (file)
@@ -5,52 +5,62 @@
 #include "spec.h"
 #include "interface.h"
 
-struct task tasks[MAXTASKS];
+#define TASKSPACE 128
+
+uint8_t taskspace[TASKSPACE] = {0};
+uint8_t *spacepointer = (uint8_t *)&taskspace;
+uint8_t taskid = 0;
+struct task *head = NULL;
 
 void task_init(void)
 {
-       memset(&tasks, 0, sizeof(struct task)*MAXTASKS);
+       memset(&taskspace, 0, TASKSPACE);
+       head = NULL;
 }
 
 void task_register(void)
 {
-       uint8_t ct;
-       uint16_t i;
+       int i;
+       if(spacepointer+sizeof(struct task) > taskspace+TASKSPACE){
+               die("Out of memory... Not enough to allocate taskstruct");
+       }
 
-       for(ct = 0; ct<MAXTASKS; ct++)
-               if(!tasks[ct].used)
-                       break;
-       if(ct == MAXTASKS)
-               die("Trying to add too much tasks...");
+       //We haven't had a task before, therefore we initialize head
+       struct task *t = (struct task *)spacepointer;
+       if(head == NULL) {
+               head = t;
+       }
 
-       memset(&tasks[ct], 0, sizeof(struct task));
        //Read interval
-       tasks[ct].interval = read16();
-       debug("interval: %d\n", tasks[ct].interval);
+       t->interval = read16();
+       debug("interval: %d\n", t->interval);
 
        //Interrupt task
-       if(is_interrupt_task(&tasks[ct])) {
+       if(is_interrupt_task(t)) {
 
        }
 
        //Read tasklength
-       tasks[ct].tlen = read16();
-       debug("task interval: %d, length: %d\n",
-             tasks[ct].interval, tasks[ct].tlen);
+       t->tasklength = read16();
+       debug("task interval: %d, length: %d\n", t->interval, t->tasklength);
+
+       if(spacepointer+t->tasklength > taskspace+TASKSPACE){
+               die("Out of memory... Not enough to allocate bytes");
+       }
+
+       spacepointer += t->tasklength;
 
-       if(tasks[ct].tlen > MAXTASKSIZE)
-               die("Task is too long: %d", tasks[ct].tlen);
        //Read task bytecode
-       for(i = 0; i<tasks[ct].tlen; i++){
-               tasks[ct].bc[i] = read_byte();
+       for(i = 0; i<t->tasklength; i++){
+               t->bc[i] = read_byte();
        }
        //Return the task number for later removal
-       debug("Received a task of length %d", tasks[ct].tlen);
-       tasks[ct].used = true;
-       tasks[ct].lastrun = 0L;
+       debug("Received a task of length %d", t->tasklength);
+       t->lastrun = 0L;
+       t->taskid = taskid++;
 
        write_byte('t');
-       write16(ct);
+       write16(t->taskid);
        write_byte('\n');
 }
 
@@ -66,16 +76,54 @@ bool had_interrupt(struct task* t)
        (void)t;
 }
 
-void task_delete(void)
+struct task *task_head(void)
 {
-       uint8_t c = read16();
-       tasks[c].used = false;
-       write_byte('d');
-       write16(c);
-       write_byte('\n');
+       return head;
+}
+
+struct task *task_next(struct task *t)
+{
+       if(t == NULL){
+               return NULL;
+       }
+
+       uint8_t *next = (uint8_t *)t;
+       next += sizeof(struct task);
+       next += t->tasklength;
+
+       return next > spacepointer ? NULL : (struct task *)next;
 }
 
-struct task *task_get(int num)
+void task_delete(void)
 {
-       return tasks[num].used ? &tasks[num] : NULL;
+       uint8_t c = read16();
+       struct task *t = NULL;
+       while(t != NULL){
+               if(t->taskid == c){
+                       break;
+               }
+               t = task_next(t);
+       }
+       if(t != NULL){
+               //We found the task, now we move everything from the end of the task up
+               //to the spacepointer right
+               uint8_t *start = (uint8_t *)t;
+               uint8_t *end = start + sizeof(struct task) + t->tasklength;
+               debug("Moving %lu bytes\n", spacepointer-end);
+               for(int i = 0; i<spacepointer-end; i++){
+                       start[i] = end[i];
+               }
+
+               //Decrement the spacepointer
+               spacepointer -= end-start;
+
+               if(t == head){
+                       head = task_next(t);
+               }
+
+               //Write acknowledgement
+               write_byte('d');
+               write16(c);
+               write_byte('\n');
+       }
 }