From 6c91fb7d60bba9889d8998801312794bb6f8783a Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 12 Dec 2024 16:08:11 +0100 Subject: [PATCH 1/5] proof of concept planner --- doc/.$overview.drawio.bkp | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 doc/.$overview.drawio.bkp 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7c16f20bc2287a17b14545abc40ca365b117e3e1 Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 12 Dec 2024 16:08:19 +0100 Subject: [PATCH 2/5] proof of concept planner --- src/llist.c | 16 ++++++- src/llist.h | 9 +++- src/planner.c | 116 ++++++++++++++++++++++++++++++++++++++++++++------ src/planner.h | 15 ++++--- src/test.c | 19 +++++++-- 5 files changed, 149 insertions(+), 26 deletions(-) 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..2ea0a92 100644 --- a/src/planner.c +++ b/src/planner.c @@ -7,35 +7,60 @@ */ #include "planner.h" // for subject and event structs -#include "config.h" +#include "llist.h" +#include +#include #include #include #include +#include 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); +} +void llistPrintE(llist *head) { + llist *c = head; + while (c != NULL) { + printEvent((Event *)c->data); + c = c->next; + } +} +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 +112,87 @@ 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) { + + // 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] = *(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); + + time_t now = time(NULL); + struct tm *lc = localtime(&now); + llist *events_ll = llistNew(NULL, cmpEvent); + 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); + } + + llistPrintE(events_ll->next); + + planLog("END GEN PLAN", 0); + + return events_ll; +} diff --git a/src/planner.h b/src/planner.h index 2d232c7..9d0c3d9 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 @@ -73,8 +74,10 @@ 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); +int cmpEvent(const void *a, const void *b); +/* + * takes llist of tasks and returns llist of events + */ +llist *genPlan(llist *head); #endif // !PLANNER diff --git a/src/test.c b/src/test.c index 9ac3dba..c3a61c5 100644 --- a/src/test.c +++ b/src/test.c @@ -4,6 +4,7 @@ #include "llist.h" #include "planner.h" // for subject and event structs #include "ui.h" +#include #include #include @@ -14,20 +15,29 @@ 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); + + genPlan(list1); // print test tasks printTask(t1); - printTask(&t2); + printTask(t2); // find in list & modify Task search = {.name = "Phys"}; // key to look for. cmpTask only compares @@ -46,6 +56,7 @@ int main() { free(t1Str); free(t1); + free(t2); return 0; } From 8629bb0420acf4098b91d3b1597fc7b2c61d1dab Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 12 Dec 2024 16:24:19 +0100 Subject: [PATCH 3/5] modified: src/planner.c modified: src/planner.h modified: src/test.c --- src/planner.c | 20 ++++++++++++++++++++ src/planner.h | 3 +++ src/test.c | 7 +++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/planner.c b/src/planner.c index 2ea0a92..909f385 100644 --- a/src/planner.c +++ b/src/planner.c @@ -43,6 +43,26 @@ void llistPrintE(llist *head) { 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); diff --git a/src/planner.h b/src/planner.h index 9d0c3d9..c390e47 100644 --- a/src/planner.h +++ b/src/planner.h @@ -41,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 @@ -74,6 +75,8 @@ Event *newEvent(Task *t, time_t s, time_t e, uint64_t sp); /* * compare function for Event */ +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 diff --git a/src/test.c b/src/test.c index c3a61c5..0a5f98c 100644 --- a/src/test.c +++ b/src/test.c @@ -33,7 +33,8 @@ int main() { llistAppend(list1, t3); llistAppend(list1, t4); - genPlan(list1); + llist *l1 = genPlan(list1); + llistFreeE(l1); // print test tasks printTask(t1); @@ -53,10 +54,8 @@ int main() { char *t1Str = taskToStr(t1); printf("%s\n", t1Str); + llistFreeT(list1); free(t1Str); - free(t1); - free(t2); - return 0; } From 568c1dcf7d444950a8fdb716b7622694b6e0b966 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 13 Dec 2024 17:32:41 +0100 Subject: [PATCH 4/5] planner makes plans now --- Makefile | 4 +++ src/planner.c | 84 +++++++++++++++++++++++++++++++++++++-------------- src/planner.h | 2 +- src/test.c | 43 ++++++++++++++------------ 4 files changed, 91 insertions(+), 42 deletions(-) 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/src/planner.c b/src/planner.c index 909f385..2653d71 100644 --- a/src/planner.c +++ b/src/planner.c @@ -15,6 +15,9 @@ #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"; @@ -35,6 +38,7 @@ void printEvent(Event *s) { 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; @@ -152,7 +156,7 @@ int cmpEvent(const void *a, const void *b) { return cmpTaskN(aa->task, bb->task); } -llist *genPlan(llist *head) { +llist *genPlan(llist *head, time_t timeAvail) { // map llist to pointer arr & sort by priority // second arr sorted bby name @@ -161,9 +165,9 @@ llist *genPlan(llist *head) { printf("len: %d\n", lLen); llistPrintT(head); - Task *sortedNames = calloc(lLen, sizeof(Task)); + // Task *sortedNames = calloc(lLen, sizeof(Task)); Task *sortedPrio = calloc(lLen, sizeof(Task)); - if (sortedNames == NULL || sortedPrio == NULL) { + if (/*sortedNames == NULL ||*/ sortedPrio == NULL) { planLog("gen plan : calloc failed!!\n", true); return NULL; } @@ -171,20 +175,22 @@ llist *genPlan(llist *head) { // add Tasks from llist to arr llist *c = head; for (int i = 0; c != NULL; i++) { - sortedNames[i] = *(Task *)c->data; + // 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(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); - } + // // 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++) { @@ -193,26 +199,60 @@ llist *genPlan(llist *head) { 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); - for (int i = 0; i < lLen; i++) { - time_t start = mktime(lc); + // 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); // - 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; + Event *c = + newEvent(sortedPrio, start, end, 0); // use elem with wighest priority llistAppend(events_ll, c); - } + printEvent(c); - llistPrintE(events_ll->next); + // 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); + + // for (int i = 0; i < lLen; i++) { + // printTask(sortedPrio + i); + // } 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 c390e47..0eca7b1 100644 --- a/src/planner.h +++ b/src/planner.h @@ -81,6 +81,6 @@ int cmpEvent(const void *a, const void *b); /* * takes llist of tasks and returns llist of events */ -llist *genPlan(llist *head); +llist *genPlan(llist *head, time_t timeAvail); #endif // !PLANNER diff --git a/src/test.c b/src/test.c index 0a5f98c..fa215e7 100644 --- a/src/test.c +++ b/src/test.c @@ -7,6 +7,7 @@ #include #include #include +#include int main() { @@ -33,29 +34,33 @@ int main() { llistAppend(list1, t3); llistAppend(list1, t4); - llist *l1 = genPlan(list1); + // 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); - llistFreeT(list1); - free(t1Str); - + // 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; } From 5bbfc52403003c1280a0a0b6d8ef0923742b129e Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 13 Dec 2024 18:07:35 +0100 Subject: [PATCH 5/5] fixed mem bug --- src/planner.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/planner.c b/src/planner.c index 2653d71..656414f 100644 --- a/src/planner.c +++ b/src/planner.c @@ -38,7 +38,7 @@ void printEvent(Event *s) { ctime_r(&s->plannedStartTime, st); ctime_r(&s->plannedEndTime, e); printf(eventFormat, s->task->name, st, e, s->spare); - printTask(s->task); + // printTask(s->task); } void llistPrintE(llist *head) { llist *c = head; @@ -203,6 +203,9 @@ llist *genPlan(llist *head, time_t timeAvail) { 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)) @@ -211,10 +214,15 @@ llist *genPlan(llist *head, time_t timeAvail) { lc->tm_min += intervalLen; end = mktime(lc); // - Event *c = - newEvent(sortedPrio, start, end, 0); // use elem with wighest priority + 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(c); + // printEvent((Event *)((events_ll)->next)->data); // decrement priority of first elem and resort list (*sortedPrio).priority -= 1; @@ -246,12 +254,17 @@ llist *genPlan(llist *head, time_t timeAvail) { llistFreeE(tmp); llistPrintE(events_ll); - // for (int i = 0; i < lLen; i++) { - // printTask(sortedPrio + i); - // } + // 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); + // llistFreeT(head); // send updated tasks to db for storage return events_ll;