welcome - welcome - a terminal program which always greets you

git clone git://git.bcharge.de/welcome.git

About | Log | Files | Refs | License

commit a6944b9e913fa0e956d65a0e3cd9638794b8da8e
parent b22ec601297a9249437d3567fc0390e5a40cad87
Author: Bakar Chargeishvili <bakar@bcharge.de>
Date:   Wed, 18 Dec 2024 17:14:20 +0100

Better loading experience using pthreads

Diffstat:
M.gitignore | 1+
MMakefile | 2+-
Mwelcome.c | 126++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
3 files changed, 85 insertions(+), 44 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,3 @@ *.o +*.core welcome diff --git a/Makefile b/Makefile @@ -9,7 +9,7 @@ PREFIX = /usr/local # includes and libs INCS = -I$(PREFIX)/include -LIBS = -L$(PREFIX)/lib -lncurses -l curl +LIBS = -L$(PREFIX)/lib -lncurses -l curl -l pthread # flags CFLAGS = -pedantic -Wall -Os $(INCS) diff --git a/welcome.c b/welcome.c @@ -15,6 +15,20 @@ typedef struct { size_t len; } string; +// Structure to hold all the data we need to fetch +typedef struct { + string location; + string temperature; + string precip; + string sunlife; + string wind; + char *events; + char *today; + size_t w_pipe_events; + size_t w_pipe_today; + int fetch_complete; // Flag to indicate when fetching is done +} FetchData; + void init_string(string *s) { s->len = 0; s->ptr = malloc(s->len+1); @@ -127,6 +141,24 @@ int print_greet(WINDOW* frame) { return 0; } +// Thread function to fetch all the data +void* fetch_data(void* arg) +{ + FetchData* data = (FetchData*)arg; + + curl("wttr.in/?format=%l", &data->location); + curl("wttr.in/?format=%t%20(%f)", &data->temperature); + curl("wttr.in/?format=%w", &data->wind); + curl("wttr.in/?format=%p", &data->precip); + curl("wttr.in/?format=%S%20-%20%s", &data->sunlife); + syspipe("calcurse -r7 --format-apt='- %S -> %E %m\n' --output-datefmt=\"%B %d, %Y\"", + data->events, &data->w_pipe_events); + syspipe("date '+%B %d, %Y' | tr -d '\n'", data->today, &data->w_pipe_today); + + data->fetch_complete = 1; + return NULL; +} + int main() { setlocale(LC_ALL, ""); @@ -149,57 +181,65 @@ int main() wattroff(mainframe,A_BLINK); /***************************** - * Extract the information * + * Extract the information * *****************************/ - string location; - init_string(&location); - string temperature; - init_string(&temperature); - string precip; - init_string(&precip); - string sunlife; - init_string(&sunlife); - string wind; - init_string(&wind); - char *events = calloc(MAXPIPE + 1,sizeof(char)); - char *today = calloc(MAXPIPE + 1,sizeof(char)); + FetchData data = {0}; + init_string(&data.location); + init_string(&data.temperature); + init_string(&data.precip); + init_string(&data.sunlife); + init_string(&data.wind); + data.events = calloc(MAXPIPE + 1, sizeof(char)); + data.today = calloc(MAXPIPE + 1, sizeof(char)); + data.fetch_complete = 0; + + WINDOW *BOARD[10]; + // Create and start the fetch thread + pthread_t fetch_thread; + pthread_create(&fetch_thread, NULL, fetch_data, &data); + + // While data is being fetched, animate the skulls + refresh(); char *skull = calloc(MAXPIPE + 1,sizeof(char)); - size_t w_pipe_events = 0; - size_t w_pipe_today = 0; size_t w_pipe_skull = 0; - curl("wttr.in/?format=%l",&location); - curl("wttr.in/?format=%t%20(%f)",&temperature); - curl("wttr.in/?format=%w",&wind); - curl("wttr.in/?format=%p",&precip); - curl("wttr.in/?format=%S%20-%20%s",&sunlife); - syspipe("calcurse -r7 --format-apt='- %S -> %E %m\n' --output-datefmt=\"%B %d, %Y\"",events,&w_pipe_events); - syspipe("date '+%B %d, %Y' | tr -d '\n'",today,&w_pipe_today); - syspipe("cat skull",skull,&w_pipe_skull); - if(events[0]=='\0') - strcpy(events,"🎉 Looks like you have not planned anything 🎉\n" + syspipe("cat skull", skull, &w_pipe_skull); + //wprintw(mainframe,"%s\n", skull); + //wrefresh(mainframe); + for (int i = 0; i < COLS/w_pipe_skull; i++) { + BOARD[i] = derwin(mainframe, 8, 21, 20, i*20); + } + int loop_cntr = 0; + do{ + int color = loop_cntr%2 ? 1 : 2; + for (int i = 0; i < COLS/w_pipe_skull; i++) { + werase(BOARD[i]); + wattron(BOARD[i], COLOR_PAIR(color)); + wprintw(BOARD[i], skull); + wrefresh(BOARD[i]); + napms(100); + } + loop_cntr++; + } + while (!data.fetch_complete); + + if(data.events[0]=='\0') + strcpy(data.events,"🎉 Looks like you have not planned anything 🎉\n" ); + // Wait for fetch thread to complete + pthread_join(fetch_thread, NULL); + /*************************** - * Print the information * + * Print the information * ***************************/ - wprintw(mainframe,"Today is:\t\t%s\n",today); - wprintw(mainframe,"We are in:\t\t%s\n",location.ptr); - wprintw(mainframe,"Temperature:\t\t%s\n",temperature.ptr); - wprintw(mainframe,"Wind speed:\t\t%s\n",wind.ptr); - wprintw(mainframe,"Precipitation:\t\t%s\n",precip.ptr); - wprintw(mainframe,"Sunrise and sunset:\t%s\n",sunlife.ptr); - WINDOW *BOARD[10]; - refresh(); - wprintw(mainframe,"%s\n", skull); + wprintw(mainframe, "Today is:\t\t%s\n" , data.today); + wprintw(mainframe, "We are in:\t\t%s\n" , data.location.ptr); + wprintw(mainframe, "Temperature:\t\t%s\n" , data.temperature.ptr); + wprintw(mainframe, "Wind speed:\t\t%s\n" , data.wind.ptr); + wprintw(mainframe, "Precipitation:\t\t%s\n" , data.precip.ptr); + wprintw(mainframe, "Sunrise and sunset:\t%s\n" , data.sunlife.ptr); wrefresh(mainframe); - for (int i = 0; i < COLS/w_pipe_skull; i++) { - BOARD[i]=derwin(mainframe,8,21,20,i*20); - wattron(BOARD[i],COLOR_PAIR(2)); - wprintw(BOARD[i],skull); - wrefresh(BOARD[i]); - napms(1000); - } WINDOW* fr = newwin(LINES/2,EVBOX_W,LINES/2,(COLS-EVBOX_W)/2); WINDOW* c = derwin(fr,LINES/2-2,EVBOX_W-4,1,2); @@ -208,7 +248,7 @@ int main() //printw("Events within next 7 days:\t%s\n",events); char evts_title[]="Events within next 7 days\n\n"; mvwaddstr(c,0,(EVBOX_W-strlen(evts_title))/2-1,evts_title); - wprintw(c,events); + wprintw(c,data.events); wrefresh(fr); getch();