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:
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();