From 9f1b759e2fac0b15a7ef5a7a527ba66dbdc319b6 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 9 Jul 2009 00:32:30 +0000 Subject: Enable drawing progres bars in the background. --- tests/gl.c | 7 ++++-- tests/png.c | 8 +++---- tests/tests.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- tests/tests.h | 6 ++++- 4 files changed, 90 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/gl.c b/tests/gl.c index e6daa3e..8b999af 100644 --- a/tests/gl.c +++ b/tests/gl.c @@ -24,10 +24,9 @@ int main() { dmnsn_display *display; - dmnsn_progress *progress; + dmnsn_progress *progress, *barprogress; dmnsn_scene *scene; dmnsn_canvas *canvas; - unsigned int i; /* Set the resilience low for tests */ dmnsn_set_resilience(DMNSN_SEVERITY_LOW); @@ -64,6 +63,8 @@ main() { return EXIT_FAILURE; } + barprogress = dmnsn_progressbar_async("Raytracing scene: ", progress); + /* Display the scene as it's rendered */ while (dmnsn_get_progress(progress) < 1.0) { if (dmnsn_gl_write_canvas(scene->canvas) != 0) { @@ -75,6 +76,8 @@ main() { dmnsn_display_flush(display); } + dmnsn_finish_progress(barprogress); + if (dmnsn_finish_progress(progress) != 0) { dmnsn_delete_display(display); dmnsn_delete_default_scene(scene); diff --git a/tests/png.c b/tests/png.c index e5641f5..488cd56 100644 --- a/tests/png.c +++ b/tests/png.c @@ -56,7 +56,7 @@ main() { return EXIT_FAILURE; } - progressbar("Raytracing scene: ", progress); + dmnsn_progressbar("Raytracing scene: ", progress); if (dmnsn_finish_progress(progress) != 0) { dmnsn_delete_default_scene(scene); @@ -81,7 +81,7 @@ main() { return EXIT_FAILURE; } - progressbar("Writing PNG file: ", progress); + dmnsn_progressbar("Writing PNG file: ", progress); if (dmnsn_finish_progress(progress) != 0) { fclose(ofile); @@ -111,7 +111,7 @@ main() { return EXIT_FAILURE; } - progressbar("Reading PNG file: ", progress); + dmnsn_progressbar("Reading PNG file: ", progress); if (dmnsn_finish_progress(progress) != 0) { fclose(ifile); @@ -138,7 +138,7 @@ main() { return EXIT_FAILURE; } - progressbar("Writing PNG file: ", progress); + dmnsn_progressbar("Writing PNG file: ", progress); if (dmnsn_finish_progress(progress) != 0) { fclose(ofile); diff --git a/tests/tests.c b/tests/tests.c index e91e290..cbf7ff8 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -229,11 +229,83 @@ dmnsn_display_flush(dmnsn_display *display) /* Print a progress bar of the progress of `progress' */ void -progressbar(const char *str, const dmnsn_progress *progress) +dmnsn_progressbar(const char *str, const dmnsn_progress *progress) +{ + dmnsn_progress *barprogress = dmnsn_progressbar_async(str, progress); + if (dmnsn_finish_progress(barprogress) != 0) { + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Progress bar background thread failed."); + } +} + +typedef struct { + dmnsn_progress *barprogress; + const char *str; + const dmnsn_progress *progress; +} dmnsn_progressbar_payload; + +/* Progress bar thread callback */ +static void *dmnsn_progressbar_thread(void *ptr); + +/* Print a progress bar in the background */ +dmnsn_progress * +dmnsn_progressbar_async(const char *str, const dmnsn_progress *progress) +{ + dmnsn_progress *barprogress = dmnsn_new_progress(); + dmnsn_progressbar_payload *payload; + + if (barprogress) { + payload = malloc(sizeof(dmnsn_progressbar_payload)); + if (!payload) { + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Couldn't allocate progress bar payload."); + } + + payload->barprogress = barprogress; + payload->str = str; + payload->progress = progress; + + /* Create the worker thread */ + if (pthread_create(&barprogress->thread, NULL, &dmnsn_progressbar_thread, + payload) + != 0) { + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Couldn't start progress bar background thread."); + } + } + + return barprogress; +} + +/* Actual progress bar implementation */ +static int dmnsn_progressbar_impl(dmnsn_progress *barprogress, const char *str, + const dmnsn_progress *progress); + +/* Progress bar thread callback */ +static void * +dmnsn_progressbar_thread(void *ptr) +{ + dmnsn_progressbar_payload *payload = ptr; + int *retval = malloc(sizeof(int)); + if (retval) { + *retval = dmnsn_progressbar_impl(payload->barprogress, + payload->str, payload->progress); + } + dmnsn_done_progress(payload->barprogress); + free(payload); + return retval; +} + +/* Actual progress bar implementation */ +static int +dmnsn_progressbar_impl(dmnsn_progress *barprogress, + const char *str, const dmnsn_progress *progress) { const unsigned int increments = 32; unsigned int i; + dmnsn_new_progress_element(barprogress, increments); + printf("%s|", str); fflush(stdout); for (i = 0; i < increments; ++i) { @@ -241,7 +313,10 @@ progressbar(const char *str, const dmnsn_progress *progress) printf("="); fflush(stdout); + dmnsn_increment_progress(barprogress); } printf("|\n"); fflush(stdout); + + return 0; } diff --git a/tests/tests.h b/tests/tests.h index bedc215..19111c8 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -61,7 +61,11 @@ void dmnsn_display_flush(dmnsn_display *display); */ /* Print a progress bar of the progress of `progress' */ -void progressbar(const char *str, const dmnsn_progress *progress); +void dmnsn_progressbar(const char *str, const dmnsn_progress *progress); +/* Print a progress bar asynchronously, convienently guaranteed to succeed if + it returns so our tests don't get cluttered up */ +dmnsn_progress *dmnsn_progressbar_async(const char *str, + const dmnsn_progress *progress); #ifdef __cplusplus } -- cgit v1.2.3