]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/worm.c
ncurses 5.6 - patch 20080112
[ncurses.git] / test / worm.c
index 4692668bdcfe6f43fcf4925ce641e0a1b04a431d..172b1dd846f7c681123140d469e1c5534a22adb1 100644 (file)
@@ -61,11 +61,15 @@ Options:
   traces will be dumped.  The program stops and waits for one character of
   input at the beginning and end of the interval.
 
-  $Id: worm.c,v 1.48 2007/09/15 21:42:16 tom Exp $
+  $Id: worm.c,v 1.51 2008/01/13 01:03:23 tom Exp $
 */
 
 #include <test.priv.h>
 
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
+
 static chtype flavor[] =
 {
     'O', '*', '#', '$', '%', '0', '@',
@@ -84,8 +88,14 @@ typedef struct worm {
     short *xpos;
     short *ypos;
     chtype attrs;
+#ifdef USE_PTHREADS
+    pthread_t thread;
+#endif
 } WORM;
 
+static unsigned long sequence = 0;
+static bool quitting = FALSE;
+
 static WORM worm[40];
 static short **refs;
 
@@ -299,12 +309,59 @@ draw_worm(WINDOW *win, void *data)
 
 #if !defined(NCURSES_VERSION_PATCH) || (NCURSES_VERSION_PATCH < 20070915)
 static int
-use_window(WINDOW *win, int (*func)(WINDOW *, void *), void *data)
+use_window(WINDOW *win, int (*func) (WINDOW *, void *), void *data)
 {
     return func(win, data);
 }
 #endif
 
+#ifdef USE_PTHREADS
+static bool
+quit_worm(void)
+{
+    napms(10);                 /* let the other thread(s) have a chance */
+    return quitting;
+}
+
+static void *
+start_worm(void *arg)
+{
+    unsigned long compare = 0;
+    while (!quit_worm()) {
+       while (compare < sequence) {
+           ++compare;
+           use_window(stdscr, draw_worm, arg);
+       }
+    }
+    return NULL;
+}
+#endif
+
+static bool
+draw_all_worms(void)
+{
+    bool done = FALSE;
+    int n;
+    struct worm *w;
+
+#ifdef USE_PTHREADS
+    static bool first = TRUE;
+    if (first) {
+       first = FALSE;
+       for (n = 0, w = &worm[0]; n < number; n++, w++) {
+           int rc;
+           rc = pthread_create(&(w->thread), NULL, start_worm, w);
+       }
+    }
+#else
+    for (n = 0, w = &worm[0]; n < number; n++, w++) {
+       if (use_window(stdscr, draw_worm, w))
+           done = TRUE;
+    }
+#endif
+    return done;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -440,13 +497,13 @@ main(int argc, char *argv[])
            }
        }
     }
-    napms(10);
     refresh();
     nodelay(stdscr, TRUE);
 
     while (!done) {
        int ch;
 
+       ++sequence;
        if ((ch = getch()) > 0) {
 #ifdef TRACE
            if (trace_start || trace_end) {
@@ -489,6 +546,7 @@ main(int argc, char *argv[])
             * normal operation -T.Dickey
             */
            if (ch == 'q') {
+               quitting = TRUE;
                done = TRUE;
                continue;
            } else if (ch == 's') {
@@ -498,10 +556,7 @@ main(int argc, char *argv[])
            }
        }
 
-       for (n = 0, w = &worm[0]; n < number; n++, w++) {
-           if (use_window(stdscr, draw_worm, w))
-               done = TRUE;
-       }
+       done = draw_all_worms();
        napms(10);
        refresh();
     }
@@ -516,6 +571,14 @@ main(int argc, char *argv[])
        free(w->xpos);
        free(w->ypos);
     }
+#endif
+#ifdef USE_PTHREADS
+    /*
+     * Do this just in case one of the threads did not really exit.
+     */
+    for (n = 0; n < number; n++) {
+       pthread_join(worm[n].thread, NULL);
+    }
 #endif
     ExitProgram(EXIT_SUCCESS);
 }