sav

Sorting Algorithms Visualized
Index Commits Files Refs README LICENSE
commit 8bf9f72a28d5544361b6351dad6d82e720274fcd
parent e8e9e2eb6739c670abd2da61e652887cca79f047
Author: klewer-martin <martin.cachari@gmail.com>
Date:   Fri, 15 Apr 2022 01:13:37 -0300

Added sort_handler

Added sort_handler, a function pointer array defined in sort.h which
handles sav->sort_algo and calls the corresponding function

Diffstat:
MMakefile | 2+-
Marray.c | 3+--
Mdrw.c | 25++++++++++++-------------
Mdrw.h | 3++-
Mmain.c | 52++++++++++++++++++++++------------------------------
Msav.c | 15+++------------
Msav.h | 8+++-----
Msdl_extra.c | 6++----
Msort.c | 25+++++++++----------------
Msort.h | 15+++++++++++++++
Mstatus.h | 1+
Mutil.c | 9+++------
12 files changed, 74 insertions(+), 90 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
 CC := cc
 CLIBS := `sdl2-config --libs --cflags`
-CFLAGS := -lSDL2_ttf -lm -Werror -pedantic -ansi -std=c99 -g -pthread
+CFLAGS := -lSDL2_ttf -lm -Werror -pedantic -ansi -std=c99 -pthread
 SRCS := main.c sav.c util.c sort.c drw.c sdl_extra.c array.c
 OBJS := $(SRCS:.c=.o)
 LIBS := array.h status.h
diff --git a/array.c b/array.c
@@ -3,8 +3,7 @@
 #include <stdio.h>
 #include <time.h>
 
-void
-shuffle(Arr *arr) {
+void shuffle(Arr *arr) {
     srand((unsigned int)time(NULL));
     for(size_t i = 0; i < arr->len; i++)
         while(!(arr->v[i] = rand() % ARR_MAX));
diff --git a/drw.c b/drw.c
@@ -1,7 +1,6 @@
 #include "drw.h"
 
-void
-drw_element_color(Drw *drw, int x, int y, int h, unsigned int col) {
+void drw_element_color(Drw *drw, int x, int y, int h, unsigned int col) {
     SDL_Rect rect;
     unsigned char r, g, b, a;
 
@@ -23,8 +22,7 @@ drw_element_color(Drw *drw, int x, int y, int h, unsigned int col) {
     SDL_RenderDrawLine(drw->rend, x + drw->x_border, y - drw->y_border, x + drw->x_border, y - drw->y_border - h);
 }
 
-void
-drw_array_graph(Drw *drw, SAV *sav) {
+void drw_array_graph(Drw *drw, SAV *sav) {
     int x, w, h;
 
     SDL_GetWindowSize(drw->win, &w, &h);
@@ -41,8 +39,7 @@ drw_array_graph(Drw *drw, SAV *sav) {
     drw_status_bar(drw, sav);
 }
 
-void
-drw_status_bar(Drw *drw, SAV *sav) {
+void drw_status_bar(Drw *drw, SAV *sav) {
     SDL_Rect rect;
     int bar_border = 2;
 
@@ -57,7 +54,7 @@ drw_status_bar(Drw *drw, SAV *sav) {
     SDL_SetRenderDrawColor(drw->rend, 0, 0, 0, 0); /* RGBA */
     SDL_RenderFillRect(drw->rend, &rect);
 
-    if((sav->status == RUN) || (sav->status == UPDATE) || (sav->status == START)) {
+    if((sav->status == RUN) || (sav->status == UPDATE) || (sav->status == START) || sav->status == WELCOME) {
         if(sav->sort_status == SORTED) {
             snprintf(drw->bar_text, drw->bar_text_len - 2,
                     "SORTED (%s sort) done in %.2fs, L: %ld, C: %ld, S: %ld, extra storage used: %ld Bytes",
@@ -67,6 +64,11 @@ drw_status_bar(Drw *drw, SAV *sav) {
         } else if(sav->sort_status == PAUSE) {
             if(sav->status == START) {
                 snprintf(drw->bar_text, drw->bar_text_len - 2,
+                        "(%s sort selected) press SPACE to start sorting",
+                        algo_strings[sav->sort_algo], sav->arr->len, sav->cmps,
+                        sav->swps);
+            } else if(sav->status == WELCOME) {
+                snprintf(drw->bar_text, drw->bar_text_len - 2,
                         "Welcome to sorting algorithms visualized - (%s sort selected) press SPACE to start sorting",
                         algo_strings[sav->sort_algo], sav->arr->len, sav->cmps,
                         sav->swps);
@@ -87,8 +89,7 @@ drw_status_bar(Drw *drw, SAV *sav) {
     memset(drw->bar_text, 0, sizeof(char) * drw->bar_text_len);
 }
 
-void
-drw_text(Drw *drw, char *text, int x, int y) {
+void drw_text(Drw *drw, char *text, int x, int y) {
     drw->text_surface = TTF_RenderText_Blended(drw->font, text, drw->text_color);
     drw->text_texture = SDL_CreateTextureFromSurface(drw->rend, drw->text_surface);
 
@@ -100,8 +101,7 @@ drw_text(Drw *drw, char *text, int x, int y) {
     SDL_RenderCopy(drw->rend, drw->text_texture, NULL, &drw->bar_text_rect);
 }
 
-status_t
-Drw_new(Drw **drw) {
+status_t Drw_new(Drw **drw) {
     SDL_Renderer *rend;
     SDL_Window *win;
     TTF_Font *font;
@@ -165,8 +165,7 @@ Drw_new(Drw **drw) {
     return OK;
 }
 
-void
-Drw_destroy(Drw *drw) {
+void Drw_destroy(Drw *drw) {
     if(drw == NULL) return;
 
     TTF_CloseFont(drw->font);
diff --git a/drw.h b/drw.h
@@ -7,6 +7,7 @@
 #include "sav.h"
 #include "util.h"
 #include "sdl_extra.h"
+#include "sort.h"
 
 #define SEL_COLOR    0x00FF0000 // RGBA (A not used rn)
 #define CMP_COLOR    0x00FFFF00
@@ -49,4 +50,4 @@ void drw_text(Drw *drw, char *text, int x, int y);
 void drw_array_graph(Drw *drw, SAV *sav);
 void drw_status_bar(Drw *drw, SAV *sav);
 
-#endif // __DRAW_H__
+#endif
diff --git a/main.c b/main.c
@@ -7,31 +7,26 @@
 #include "sdl_extra.h"
 #include "array.h"
 
+#define WELCOME_MSG_TIME 5
+
 void check_events(Drw *, SAV *);
 void *routine_wrapper(void *);
 
-void *
-routine_wrapper(void *arg) {
+void *routine_wrapper(void *arg) {
     SAV *sav = (SAV *)arg;
 
-    switch(sav->sort_algo) {
-        case BUBBLE_SORT:  bubble_sort(sav); break;
-        case INSERTION_SORT: insertion_sort(sav); break;
-        case MERGE_SORT: merge_sort_wrapper(sav); break;
-        case QUICK_SORT: quick_sort_wrapper(sav); break;
-        default:  {
-            fprintf(stderr, "\"sort_algo\" not set. exiting\n");
-            sav->status = STOP;
-            break;
-        }
-    }
+    if(sav->sort_algo == ALGORITHMS_COUNT) {
+        fprintf(stderr, "ERROR: \"sort_algo\" not set. exiting\n");
+        sav->status = STOP;
+    } else sort_handler[sav->sort_algo](sav);
+
     return NULL;
 }
 
-int
-main (void) {
+int main (void) {
     SAV *sav;
     Drw *drw;
+    clock_t ti, tc;
 
     pthread_t p1;
     status_t st;
@@ -43,19 +38,23 @@ main (void) {
     shuffle(sav->arr);
 
     /* selecting the sorting algorithms */
-    sav->sort_algo = BUBBLE_SORT;
+    sav->sort_algo = QUICK_SORT;
 
     /* start sorting thread */
     pthread_create(&p1, NULL, &routine_wrapper, (void *)sav);
 
-
-    sav->status = START;
+    sav->status = WELCOME;
     sav->sort_status = PAUSE;
+    ti = clock();
 
     /* main loop */
     while(sav->status != STOP) {
         check_events(drw, sav);
 
+        if(sav->status == WELCOME)
+            if((((tc = clock()) - ti) / CLOCKS_PER_SEC) > WELCOME_MSG_TIME)
+                sav->status = START;
+
         drw_array_graph(drw, sav);
         drw_status_bar(drw, sav);
         SDL_RenderPresent(drw->rend);
@@ -70,7 +69,6 @@ main (void) {
             pthread_create(&p1, NULL, &routine_wrapper, (void *)sav);
         }
     }
-
     end:
     pthread_join(p1, NULL);
 
@@ -79,8 +77,7 @@ main (void) {
     return 0;
 }
 
-void
-check_events(Drw *drw, SAV *sav) {
+void check_events(Drw *drw, SAV *sav) {
     SDL_Event event;
     while (SDL_PollEvent(&event)) {
         switch(event.type) {
@@ -92,18 +89,13 @@ check_events(Drw *drw, SAV *sav) {
             case SDL_SCANCODE_R:
                 if(sav->sort_status == SORTED) sav->status = RESTART;
                 break;
-            /* case SDL_SCANCODE_S: */
-            /*     shuffle(sav->arr); */
-            /*     break; */
             case SDL_SCANCODE_SPACE:
-                printf("status: %d, sort_status: %d\n", sav->status, sav->sort_status);
-                /* if(sav->status == START) sav->status = sav->sort_status = RUN; */
                 if(sav->sort_status == PAUSE) sav->status = sav->sort_status = RUN;
                 else if(sav->sort_status == RUN) sav->sort_status = PAUSE;
-
                 break;
             default: break;
-           }
+            }
+            break;
         case SDL_WINDOWEVENT:
             switch(event.window.event) {
             case SDL_WINDOWEVENT_RESIZED:
@@ -114,10 +106,10 @@ check_events(Drw *drw, SAV *sav) {
                 /* set new window borders */
                 drw->x_border = (drw->w / 2) - ((sav->arr->len * RECT_WIDTH) / 2);
                 drw->y_border = (drw->h / 2) - (ARR_MAX / 2);
-
                 break;
             default: break;
-           }
+            }
+            break;
         default: break;
         }
     }
diff --git a/sav.c b/sav.c
@@ -1,14 +1,6 @@
 #include "sav.h"
 
-char *algo_strings[SORT_MAX_ALGORITHMS] = {
-    "bubble",
-    "insertion",
-    "merge",
-    "quick"
-};
-
-status_t
-SAV_new(SAV **sav) {
+status_t SAV_new(SAV **sav) {
     if((*sav = (SAV *)malloc(sizeof(SAV))) == NULL)
         return ERROR_MEMORY_ALLOC;
 
@@ -16,7 +8,7 @@ SAV_new(SAV **sav) {
     (*sav)->cmps = (*sav)->swps = (*sav)->its = (*sav)->B_used = 0;
     (*sav)->status = RUN;
     (*sav)->sort_status = PAUSE;
-    (*sav)->sort_algo = SORT_MAX_ALGORITHMS;
+    (*sav)->sort_algo = ALGORITHMS_COUNT;
 
     if(((*sav)->arr = (Arr *)malloc(sizeof(Arr))) == NULL)
         return ERROR_MEMORY_ALLOC;
@@ -32,8 +24,7 @@ SAV_new(SAV **sav) {
     return 0;
 }
 
-void
-SAV_destroy(SAV *sav) {
+void SAV_destroy(SAV *sav) {
     if(sav == NULL) return;
 
     free(sav->arr->v);
diff --git a/sav.h b/sav.h
@@ -11,11 +11,11 @@
 #include "array.h"
 
 typedef enum {
-    BUBBLE_SORT = 0,
+    BUBBLE_SORT,
     INSERTION_SORT,
     MERGE_SORT,
     QUICK_SORT,
-    SORT_MAX_ALGORITHMS
+    ALGORITHMS_COUNT
 } sort_t;
 
 typedef struct {
@@ -25,9 +25,7 @@ typedef struct {
     status_t status;
     status_t sort_status;
     sort_t sort_algo;
-} SAV; 
-
-extern char *algo_strings[SORT_MAX_ALGORITHMS];
+} SAV;
 
 status_t SAV_new(SAV **sav);
 void SAV_destroy(SAV *sav);
diff --git a/sdl_extra.c b/sdl_extra.c
@@ -1,7 +1,6 @@
 #include "sdl_extra.h"
 
-status_t
-SDL_setup(SDL_Window **win, SDL_Renderer **rend) {
+status_t SDL_setup(SDL_Window **win, SDL_Renderer **rend) {
     int min_w, min_h;
 
     SDL_Init(SDL_INIT_VIDEO);
@@ -35,8 +34,7 @@ SDL_setup(SDL_Window **win, SDL_Renderer **rend) {
     return OK;
 }
 
-status_t
-SDL_cleanup(SDL_Window *win, SDL_Renderer *rend) {
+status_t SDL_cleanup(SDL_Window *win, SDL_Renderer *rend) {
     if((win == NULL) || (rend == NULL))
         return ERROR_NULL_POINTER;
 
diff --git a/sort.c b/sort.c
@@ -6,8 +6,7 @@
 
 #define DELAY    5
 
-void
-insertion_sort(SAV *sav) {
+void insertion_sort(SAV *sav) {
     int key;
     size_t i, j;
 
@@ -58,8 +57,7 @@ insertion_sort(SAV *sav) {
     if(sav->status != STOP) sav->sort_status = SORTED;
 }
 
-void
-bubble_sort(SAV *sav) {
+void bubble_sort(SAV *sav) {
     size_t i, j;
 
     if((sav->sort_status == STOP) || (sav->status == STOP)) return;
@@ -101,8 +99,7 @@ bubble_sort(SAV *sav) {
     if(sav->status != STOP) sav->sort_status = SORTED;
 }
 
-void
-merge(SAV *sav, int low, int middle, int high) {
+void merge(SAV *sav, int low, int middle, int high) {
     size_t n1, n2, i, j, k;
 
     if((sav->sort_status == STOP) || (sav->status == STOP)) return;
@@ -117,10 +114,10 @@ merge(SAV *sav, int low, int middle, int high) {
     sav->B_used += n2;
 
     /* B holds middle low array */
-    for(i = low, j = 0; i < middle; i++, j++) 
+    for(i = low, j = 0; i < middle; i++, j++)
         B[j] = sav->arr->v[i];
 
-    /* C middle high part of the array */ 
+    /* C middle high part of the array */
     for(i = middle, j = 0; i < high; i++, j++)
         C[j] = sav->arr->v[i];
 
@@ -152,8 +149,7 @@ merge(SAV *sav, int low, int middle, int high) {
         sav->arr->v[k++] = C[j++];
 }
 
-void
-merge_sort(SAV *sav, int low, int high) {
+void merge_sort(SAV *sav, int low, int high) {
     if(sav == NULL) return;
 
     if((sav->sort_status == STOP) || (sav->status == STOP))
@@ -186,8 +182,7 @@ void merge_sort_wrapper(SAV *sav) {
     if(sav->status != STOP) sav->sort_status = SORTED;
 }
 
-void
-quick_sort_partition(SAV *sav, int low, int *middle, int high) {
+void quick_sort_partition(SAV *sav, int low, int *middle, int high) {
     int i, j, pivot;
 
     pivot = high;
@@ -215,8 +210,7 @@ quick_sort_partition(SAV *sav, int low, int *middle, int high) {
     *middle = i;
 }
 
-void
-quick_sort(SAV *sav, int low, int high) {
+void quick_sort(SAV *sav, int low, int high) {
     int pivot;
 
     if(sav->status == STOP) return;
@@ -229,8 +223,7 @@ quick_sort(SAV *sav, int low, int high) {
     }
 }
 
-void
-quick_sort_wrapper(SAV *sav) {
+void quick_sort_wrapper(SAV *sav) {
     sav->ti = clock();
     quick_sort(sav, 0, sav->arr->len - 1);
     printf("SORT: sorting array done\n");
diff --git a/sort.h b/sort.h
@@ -17,4 +17,19 @@ void quick_sort_wrapper(SAV *sav);
 void quick_sort(SAV *sav, int low, int high);
 void quick_sort_partition(SAV *sav, int low, int *middle, int high);
 
+static void (*sort_handler[ALGORITHMS_COUNT])(SAV *) = {
+    &bubble_sort,
+    &insertion_sort,
+    &merge_sort_wrapper,
+    &quick_sort_wrapper
+};
+
+/* static const char *algo_strings[ALGORITHMS_COUNT]; */
+static const char *algo_strings[ALGORITHMS_COUNT] = {
+    "bubble",
+    "insertion",
+    "merge",
+    "quick"
+};
+
 #endif // __SORT_H__
diff --git a/status.h b/status.h
@@ -14,6 +14,7 @@ typedef enum {
     SORTED,
     START,
     RESTART,
+    WELCOME,
     STOP
 } status_t;
 
diff --git a/util.c b/util.c
@@ -1,21 +1,18 @@
 #include "util.h"
 
-void
-wait_main_thread(status_t *st) {
+void wait_main_thread(status_t *st) {
     if((*st != STOP) && (*st != PAUSE)) *st = UPDATE;
 
     /* wait 'til main thread changes st value to RUN */
     while((*st == UPDATE) || (*st == PAUSE));
 }
 
-void
-end(const char *msg) {
+void end(const char *msg) {
     fprintf(stderr, "%s\n", msg);
     exit(1);
 }
 
-void
-swap(int *a, int *b)
+void swap(int *a, int *b)
 {
     int tmp;
     tmp = (*a);