Advertisement
phyrrus9

ncurses threaded progress example

Mar 8th, 2018
316
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.06 KB | None | 0 0
  1. /* simple example of using ncurses to display a queue of progress bars
  2.  * save this file as ncprogress.c
  3.  * compile with gcc -o ncp ncprogress.c -pthread -lncurses
  4.  * change MAX_BARS to the size you want your queue to be
  5.  * run ./ncp to test it out */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <time.h>
  10. #include <pthread.h>
  11. #include <ncurses.h>
  12. #define MAX_BARS 5
  13. WINDOW *positions[MAX_BARS] = { NULL };
  14. struct progressContext
  15. {
  16.         void (*callback)(unsigned, unsigned, struct progressContext *);
  17.         WINDOW *win;
  18.         char *name;
  19. };
  20. struct threadContext
  21. {
  22.         struct progressContext *progress;
  23.         int position;
  24.         unsigned seconds;
  25.         pthread_t threadId;
  26. };
  27. void waitLoop(unsigned ms, unsigned interval, struct progressContext *context)
  28. {
  29.         unsigned i, j, s, count = ms/interval;
  30.         for (i = 0, s = 0; i < ms; i += interval, ++s)
  31.         {
  32.                 (*context->callback)(s % 4, (i * 100) / ms, context);
  33.                 usleep(interval * 1000);
  34.         }
  35.         (*context->callback)(0, 100, context);
  36.         printf("\n");
  37. }
  38. void progressw(unsigned spin, unsigned step, struct progressContext *ctx)
  39. {
  40.         int i;
  41.         const char *pgstep = "|\\-/";
  42.         wclear(ctx->win);
  43.         wprintw(ctx->win, "Your title here, this thread is %s seconds\n[", ctx->name); // print window title first
  44.         for (i = 0; i < step; ++i) wprintw(ctx->win, "#"); // print bar
  45.         for (; i < 100; ++i) wprintw(ctx->win, " "); // print blank space
  46.         wprintw(ctx->win, "] %c                       ", step > 99 ? ' ' : pgstep[spin]);
  47.         wrefresh(ctx->win);
  48. }
  49. void *threadWrapper(void *arg)
  50. {
  51. }
  52. int selectPosition()
  53. {
  54.         int i;
  55.         for (i = 0; i < MAX_BARS; ++i)
  56.                 if (positions[i] == NULL)
  57.                         return i;
  58.         return -1;
  59. }
  60. void *threadEntry(void *arg)
  61. {
  62.         struct threadContext *ctx;
  63.         struct progressContext *pctx;
  64.         ctx = arg;
  65.         pctx = ctx->progress;
  66.         waitLoop(ctx->seconds * 1000, 1000, pctx);
  67.         werase(pctx->win);
  68.         wrefresh(pctx->win);
  69.         delwin(pctx->win);
  70.         free(pctx->name);
  71.         free(pctx);
  72.         usleep(200 * 1000);
  73.         positions[ctx->position] = NULL; // put the window back in the list
  74.         free(ctx);
  75.         return NULL;
  76. }
  77. void runThread(unsigned seconds, void (*callback)(unsigned, unsigned, struct progressContext *))
  78. {
  79.         int position;
  80.         struct threadContext *ctx;
  81.         do { position = selectPosition(); } while (position < 0); // wait until we get a window
  82.         positions[position] = (void *)1; // reserve our spot before we create the window, we will change this later
  83.         positions[position] = newwin(2, 120, position * 2, 0); // create an ncurses window for it
  84.         wclear(positions[position]); wrefresh(positions[position]); // initialize the window
  85.         ctx = malloc(sizeof(struct threadContext));
  86.         ctx->threadId = 0;
  87.         ctx->position = position;
  88.         ctx->seconds = seconds;
  89.         ctx->progress = malloc(sizeof(struct progressContext));
  90.         ctx->progress->callback = callback;
  91.         ctx->progress->win = positions[position];
  92.         ctx->progress->name = malloc(8);
  93.         sprintf(ctx->progress->name, "%d", seconds);
  94.         ctx->threadId = pthread_create(&ctx->threadId, NULL, threadEntry, ctx);
  95. }
  96. int running()
  97. {
  98.         int i;
  99.         for (i = 0; i < MAX_BARS; ++i)
  100.                 if (positions[i] != NULL)
  101.                         return 1;
  102.         return 0;
  103. }
  104. int main()
  105. {
  106.         int i;
  107.         const int ndownloads = 18;
  108.         initscr();
  109.         refresh();
  110.         noecho();
  111.         srand(time(NULL));
  112.         for (i = 0; i < ndownloads; ++i)
  113.         {
  114.                 runThread(rand() % 10 + 5, &progressw); // run for random time between 5 and 10 seconds
  115.                 usleep(750 * 1000); //a time out
  116.         }
  117.         sleep(1); // wait for a thread to start
  118.         while (running()); // loop while we wait
  119.         refresh();
  120.         endwin();
  121.         return 0;
  122. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement