diff --git a/Makefile b/Makefile index 4a35442..0f27e84 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,10 @@ planner: $(PLF) db: $(DBF) gcc -c $(CFLAGS) $(DBF) + +edit: + nvim $(PLF) Makefile $(LLST) src/test.c + clean: rm -rf *.o debugOut src/*.gch diff --git a/doc/.$overview.drawio.bkp b/doc/.$overview.drawio.bkp new file mode 100644 index 0000000..a3a924e --- /dev/null +++ b/doc/.$overview.drawio.bkp @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/llist.c b/src/llist.c index 517af41..f2a6a30 100644 --- a/src/llist.c +++ b/src/llist.c @@ -1,5 +1,7 @@ #include "llist.h" +#include #include +#include /* create new linked list * use llistFree after use @@ -8,7 +10,7 @@ * only use to initialize * To insert into list use llistAppend */ -llist *llistNew(void *data, int (*cmpFN)(void *a, void *b)) { +llist *llistNew(void *data, int (*cmpFN)(const void *a, const void *b)) { llist *r = (llist *)malloc(sizeof(llist)); if (r != NULL) { r->cmpFn = cmpFN; @@ -71,3 +73,15 @@ void llistFree(llist *head) { head = tmp; } } +/* + * get linked list length + */ +int llistLen(llist *head) { + int len = 0; + llist *c = head; + while (c != NULL) { + len += 1; + c = c->next; + } + return len; +} diff --git a/src/llist.h b/src/llist.h index 49c206f..34f5a67 100644 --- a/src/llist.h +++ b/src/llist.h @@ -7,11 +7,11 @@ typedef struct llist { struct llist *next; struct llist *prev; struct llist *tail; - int (*cmpFn)(void *a, void *b); // function that compares data + int (*cmpFn)(const void *a, const void *b); // function that compares data } llist; // create new linked list with content(void* data) and cmpFN -llist *llistNew(void *data, int (*cmpFN)(void *a, void *b)); +llist *llistNew(void *data, int (*cmpFN)(const void *a, const void *b)); // create new node with data and append to tail of head llist *llistAppend(llist *head, void *data); // return llistNode that contains key or NULL @@ -20,5 +20,10 @@ llist *llistGet(llist *head, void *key); bool llistContains(llist *head, void *key); // free llist node (Does Not free data it contains!!) void llistFree(llist *head); +// count llistLen +int llistLen(llist *head); + +void llistPrintT(llist *head); +void llistPrintH(llist *head); #endif diff --git a/src/planner.c b/src/planner.c index fb00f5a..656414f 100644 --- a/src/planner.c +++ b/src/planner.c @@ -7,35 +7,84 @@ */ #include "planner.h" // for subject and event structs -#include "config.h" +#include "llist.h" +#include +#include #include #include #include +#include + +const uint intervalLen = 45; // min +const uint pauseLen = 10; // const char taskFormat[] = "Task { %.64s = {\n created={%lu},\n deadline={%lu},\n " "priority={%d},\n spare={%lu}\n}\n"; const char eventFormat[] = - "Event { %s = {\n start={%lu},\n end={%lu},\n spare={%lu}\n}\n"; + "Event { %s = {\n start={%s},\n end={%s},\n spare={%lu}\n}\n"; +void llistPrintT(llist *head) { + llist *c = head; + while (c != NULL) { + printTask((Task *)c->data); + c = c->next; + } +} +// print Event to stdout +void printEvent(Event *s) { + char st[26]; + char e[26]; + ctime_r(&s->plannedStartTime, st); + ctime_r(&s->plannedEndTime, e); + printf(eventFormat, s->task->name, st, e, s->spare); + // printTask(s->task); +} +void llistPrintE(llist *head) { + llist *c = head; + while (c != NULL) { + printEvent((Event *)c->data); + c = c->next; + } +} +void freeEvent(Event *e) { + free(e->task); + free(e); +} +void llistFreeE(llist *head) { + while (head != NULL) { + free((Event *)head->data); + llist *tmp = head; + head = head->next; + free(tmp); + } +} +void llistFreeT(llist *head) { + while (head != NULL) { + free(head->data); + llist *tmp = head; + head = head->next; + free(tmp); + } +} +void planLog(char *msg, bool e) { + if (!e) + printf("[Planner][log] %s\n", msg); + else + fprintf(stderr, "==== [Planner][Err] %s\n", msg); +} Event *newEvent(Task *t, time_t s, time_t e, uint64_t sp) { Event *r = (Event *)malloc(sizeof(Event)); if (r != NULL) { r->task = t; - r->plannedEndTime = s; + r->plannedStartTime = s; r->plannedEndTime = e; r->spare = sp; } return r; } -// print Event to stdout -void printEvent(Event *s) { - printf(eventFormat, s->task->name, s->plannedStartTime, s->plannedEndTime, - s->spare); -} - /* * creat new task with name n created c deadline d priority p spare sp */ @@ -87,22 +136,136 @@ char *taskToStr(Task *t) { // for llist // compare task by name -int cmpTaskN(void *a, void *b) { +int cmpTaskN(const void *a, const void *b) { Task *aa = (Task *)a; Task *bb = (Task *)b; return strcmp(aa->name, bb->name); } // compare task by priority -int cmpTaskP(void *a, void *b) { +int cmpTaskP(const void *a, const void *b) { Task *aa = (Task *)a; Task *bb = (Task *)b; - return aa->priority - bb->priority; + return bb->priority - aa->priority; } // cmp event by task name -int cmpEvent(void *a, void *b) { +int cmpEvent(const void *a, const void *b) { Event *aa = (Event *)a; Event *bb = (Event *)b; return cmpTaskN(aa->task, bb->task); } + +llist *genPlan(llist *head, time_t timeAvail) { + + // map llist to pointer arr & sort by priority + // second arr sorted bby name + int lLen = llistLen(head); + planLog("genpla: got llist\n", false); + printf("len: %d\n", lLen); + llistPrintT(head); + + // Task *sortedNames = calloc(lLen, sizeof(Task)); + Task *sortedPrio = calloc(lLen, sizeof(Task)); + if (/*sortedNames == NULL ||*/ sortedPrio == NULL) { + planLog("gen plan : calloc failed!!\n", true); + return NULL; + } + + // add Tasks from llist to arr + llist *c = head; + for (int i = 0; c != NULL; i++) { + // sortedNames[i] = *copyTask(c->data); + // sortedPrio[i] = *copyTask(c->data); + // sortedNames[i] = *(Task *)c->data; + sortedPrio[i] = *(Task *)c->data; + c = c->next; + } + + // sort + // qsort(sortedNames, lLen, sizeof(Task), cmpTaskN); + qsort(sortedPrio, lLen, sizeof(Task), cmpTaskP); + + // // test print + // planLog("sortendName", 0); + // for (int i = 0; i < lLen; i++) { + // printTask(sortedNames + i); + // } + + planLog("sortendPrio", 0); + for (int i = 0; i < lLen; i++) { + printTask(sortedPrio + i); + } + + planLog("creating eventList", false); + + // genertate plan basen on priorities and available time + time_t now = time(NULL); + struct tm *lc = localtime(&now); + llist *events_ll = llistNew(NULL, cmpEvent); + if (events_ll == NULL) { + exit(1); + } + // time_t avail = mktime(timeAvail); + time_t start, end; + // (mktime(lc) < mktime(timeAvail)) + do { + start = mktime(lc); // start now + lc->tm_min += intervalLen; + end = mktime(lc); // + + llist *tmp = llistGet(head, sortedPrio); + Event *c = NULL; + if (tmp != NULL) { + c = newEvent(tmp->data, start, end, + 0); // use elem with wighest priority + } + llistAppend(events_ll, c); + // printEvent(c); + // printEvent((Event *)((events_ll)->next)->data); + + // decrement priority of first elem and resort list + (*sortedPrio).priority -= 1; + qsort(sortedPrio, lLen, sizeof(Task), cmpTaskP); + + lc->tm_min += pauseLen; // add pause + + } while (mktime(lc) < timeAvail); + + // for (int i = 0; i < lLen; i++) { + // time_t start = mktime(lc); + // + // printf("start:: %s\n", ctime(&start)); + // lc->tm_min += 45; + // time_t end = mktime(lc); + // printf("end:: %s\n", ctime(&end)); + // + // Event *c = newEvent(sortedPrio + i, start, end, 0); + // printEvent(c); + // lc->tm_min += 15; + // llistAppend(events_ll, c); + // } + // + + // free empty head + llist *tmp = events_ll; + events_ll = events_ll->next; + tmp->next = NULL; + llistFreeE(tmp); + llistPrintE(events_ll); + + // update prioriteis in original llist + for (int i = 0; i < lLen; i++) { + llist *tmp = llistGet(head, sortedPrio + i); + if (tmp != NULL) { + ((Task *)(tmp->data))->priority = sortedPrio[i].priority; + } + } + free(sortedPrio); + + planLog("END GEN PLAN", 0); + // llistFreeT(head); + // send updated tasks to db for storage + + return events_ll; +} diff --git a/src/planner.h b/src/planner.h index 2d232c7..0eca7b1 100644 --- a/src/planner.h +++ b/src/planner.h @@ -1,11 +1,12 @@ #ifndef PLANNER #define PLANNER +#include "llist.h" #include #include /* * task subject struct used to track different tasks - * create new task with taskNew(name, time_t created, time_t deadline, int + d* create new task with taskNew(name, time_t created, time_t deadline, int * priority, uint64_t spare) * * should be freed by user @@ -29,8 +30,8 @@ Task *newTask(char *n, time_t c, time_t d, int p, uint64_t sp); /* * compare function for Task */ -int cmpTaskN(void *a, void *b); -int cmpTaskP(void *a, void *b); +int cmpTaskN(const void *a, const void *b); +int cmpTaskP(const void *a, const void *b); /* * return allocated string representation of Task @@ -40,6 +41,7 @@ char *taskToStr(Task *t); * prints human readable str of Task to stdout */ void printTask(Task *s); +void llistFreeT(llist *head); /* * create deepCopy of task @@ -73,8 +75,12 @@ Event *newEvent(Task *t, time_t s, time_t e, uint64_t sp); /* * compare function for Event */ -int cmpEvent(void *a, void *b); - -int genPlan(Task *head); +void freeEvent(Event *e); +void llistFreeE(llist *head); +int cmpEvent(const void *a, const void *b); +/* + * takes llist of tasks and returns llist of events + */ +llist *genPlan(llist *head, time_t timeAvail); #endif // !PLANNER diff --git a/src/test.c b/src/test.c index 9ac3dba..fa215e7 100644 --- a/src/test.c +++ b/src/test.c @@ -4,8 +4,10 @@ #include "llist.h" #include "planner.h" // for subject and event structs #include "ui.h" +#include #include #include +#include int main() { @@ -14,38 +16,51 @@ int main() { // create new task named LinAlg with priority 3, created now with deadline in // 5 days sp is currently unused spare var Task *t1 = newTask("LinAlg", now, now + days(5), 3, 0); + assert(t1 != NULL); // Stack Allocated vars only for local use! - Task t2 = { - .name = "Phys", .created = now, .deadline = now + days(2), .priority = 7}; + Task *t2 = newTask("Phys", now, now + days(2), 7, 0); + assert(t2 != NULL); + Task *t3 = newTask("Analysis", now, now + days(10), 5, 0); + assert(t3 != NULL); + Task *t4 = newTask("TM1", now, now + days(1), 9, 0); + assert(t4 != NULL); printf("%s\n", ctime(&now)); // new llist test llist *list1 = llistNew(t1, cmpTaskN); - llistAppend(list1, &t2); + llistAppend(list1, t2); + llistAppend(list1, t3); + llistAppend(list1, t4); + + // gnerate plan from task list in time + struct tm *lc = localtime(&now); + lc->tm_hour += 9; // add available time; + time_t maxTime = mktime(lc); // create timestamp + llist *l1 = genPlan(list1, maxTime); // return inked list of event; + llistFreeE(l1); // print test tasks - printTask(t1); - printTask(&t2); + // printTask(t1); // find in list & modify - Task search = {.name = "Phys"}; // key to look for. cmpTask only compares - // names using strcmp(a.name, b.name) - llist *found = llistGet(list1, &search); - if (found != NULL) { - ((Task *)found->data)->deadline = time(NULL) + days(10); - ((Task *)found->data)->priority = 9; - printTask(found->data); - } else { - printf("%s not in List!\n", search.name); - } - - char *t1Str = taskToStr(t1); - printf("%s\n", t1Str); - free(t1Str); - - free(t1); - + // Task search = {.name = "Analysis"}; // key to look for. cmpTask only + // compares + // // names using strcmp(a.name, b.name) + // llist *found = llistGet(list1, &search); + // if (found != NULL) { + // ((Task *)found->data)->deadline = time(NULL) + days(10); + // // ((Task *)found->data)->priority Names= 9; + // // printTask(found->data); + // } else { + // printf("%s not in List!\n", search.name); + // } + // + // char *t1Str = taskToStr(t1); + // // printf("%s\n", t1Str); + // llistFreeT(list1); + // free(t1Str); + // return 0; }