// This is a replacement for the old `WaitForChar` function in os_unix.c static InbufPollResult inbuf_poll(int ms) { if (input_ready() || input_poll(ms)) { return kInputAvail; } return input_eof ? kInputEof : kInputNone; }
// Wait for some event bool event_poll(int32_t ms) { bool timed_out; uv_run_mode run_mode = UV_RUN_ONCE; if (input_ready()) { // If there's a pending input event to be consumed, do it now return true; } input_start(); timed_out = false; if (ms > 0) { // Timeout passed as argument to the timer timer.data = &timed_out; // We only start the timer after the loop is running, for that we // use an prepare handle(pass the interval as data to it) timer_prepare.data = &ms; uv_prepare_start(&timer_prepare, timer_prepare_cb); } else if (ms == 0) { // For ms == 0, we need to do a non-blocking event poll by // setting the run mode to UV_RUN_NOWAIT. run_mode = UV_RUN_NOWAIT; } do { // Run one event loop iteration, blocking for events if run_mode is // UV_RUN_ONCE uv_run(uv_default_loop(), run_mode); } while ( // Continue running if ... !input_ready() && // we have no input kl_empty(event_queue) && // no events are waiting to be processed run_mode != UV_RUN_NOWAIT && // ms != 0 !timed_out); // we didn't get a timeout input_stop(); if (ms > 0) { // Stop the timer uv_timer_stop(&timer); } return input_ready() || event_is_pending(); }
/*---------------------------------------------------------------------- This checks whether or not a character (UNIX) is ready to be read, or it times out. Args: time_out -- number of seconds before it will timeout Result: Returns a NO_OP_IDLE or a NO_OP_COMMAND if the timeout expires before input is available, or a KEY_RESIZE if a resize event occurs, or READY_TO_READ if input is available before the timeout. ----*/ UCS check_for_timeout(int time_out) { UCS res = NO_OP_COMMAND; fflush(stdout); #if defined(SIGWINCH) && defined(TIOCGWINSZ) if(!winch_occured){ if(setjmp(winch_state) != 0){ winch_occured = 1; ready_for_winch = 0; /* * Need to unblock signal after longjmp from handler, because * signal is normally unblocked upon routine exit from the handler. */ our_sigunblock(SIGWINCH); } else ready_for_winch = 1; } if(winch_occured){ winch_occured = ready_for_winch = 0; fix_windsize(ps_global); return(KEY_RESIZE); } #endif /* SIGWINCH */ switch(res = input_ready(time_out)){ case BAIL_OUT: read_bail(); /* non-tragic exit */ /* NO RETURN */ case PANIC_NOW: panic1("Select error: %s\n", error_description(errno)); /* NO RETURN */ case READ_INTR: res = NO_OP_COMMAND; /* fall through */ case NO_OP_IDLE: case NO_OP_COMMAND: case READY_TO_READ: #if defined(SIGWINCH) && defined(TIOCGWINSZ) ready_for_winch = 0; #endif return(res); } /* not reachable */ return(res); }
static bool input_poll(int ms) { if (do_profiling == PROF_YES && ms) { prof_inchar_enter(); } if ((ms == - 1 || ms > 0) && !events_enabled && !input_eof) { // The pending input provoked a blocking wait. Do special events now. #6247 blocking = true; multiqueue_process_events(ch_before_blocking_events); } LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof); blocking = false; if (do_profiling == PROF_YES && ms) { prof_inchar_exit(); } return input_ready(); }
/* * ReadyForKey - return true if there's no timeout or we're told input * is available... */ int ReadyForKey(int timeout) { switch(input_ready(timeout)){ case READY_TO_READ: return(1); break; case NO_OP_COMMAND: case NO_OP_IDLE: case READ_INTR: return(0); case BAIL_OUT: case PANIC_NOW: emlwrite("\007Problem reading from keyboard!", NULL); kill(getpid(), SIGHUP); /* Bomb out (saving our work)! */ /* no return */ } /* can't happen */ return(0); }
// Wait for some event bool event_poll(int32_t ms) { uv_run_mode run_mode = UV_RUN_ONCE; if (input_ready()) { // If there's a pending input event to be consumed, do it now return true; } static int recursive = 0; if (!(recursive++)) { // Only needs to start the libuv handle the first time we enter here input_start(); } uv_timer_t timer; uv_prepare_t timer_prepare; TimerData timer_data = {.ms = ms, .timed_out = false, .timer = &timer}; if (ms > 0) { uv_timer_init(uv_default_loop(), &timer); // This prepare handle that actually starts the timer uv_prepare_init(uv_default_loop(), &timer_prepare); // Timeout passed as argument to the timer timer.data = &timer_data; // We only start the timer after the loop is running, for that we // use a prepare handle(pass the interval as data to it) timer_prepare.data = &timer_data; uv_prepare_start(&timer_prepare, timer_prepare_cb); } else if (ms == 0) { // For ms == 0, we need to do a non-blocking event poll by // setting the run mode to UV_RUN_NOWAIT. run_mode = UV_RUN_NOWAIT; } do { // Run one event loop iteration, blocking for events if run_mode is // UV_RUN_ONCE uv_run(uv_default_loop(), run_mode); // Process immediate events outside uv_run since libuv event loop not // support recursion(processing events may cause a recursive event_poll // call) event_process(false); } while ( // Continue running if ... !input_ready() && // we have no input !event_has_deferred() && // no events are waiting to be processed run_mode != UV_RUN_NOWAIT && // ms != 0 !timer_data.timed_out); // we didn't get a timeout if (!(--recursive)) { // Again, only stop when we leave the top-level invocation input_stop(); } if (ms > 0) { // Ensure the timer-related handles are closed and run the event loop // once more to let libuv perform it's cleanup uv_close((uv_handle_t *)&timer, NULL); uv_close((uv_handle_t *)&timer_prepare, NULL); uv_run(uv_default_loop(), UV_RUN_NOWAIT); event_process(false); } return input_ready() || event_has_deferred(); } bool event_has_deferred() { return !kl_empty(get_queue(true)); } // Push an event to the queue void event_push(Event event, bool deferred) { *kl_pushp(Event, get_queue(deferred)) = event; }
int main(int argc, char **argv) { cairo_surface_t *surface; cairo_t *context; int x, y, i, width, height, depth, screen, pressed_key, png; double r, b, v; QTnode *tree; bool rendering; struct XWin **xwin; /* Get the arguments */ if(argc != 3) { printf("Usage: nbody rendering resultsdir\n"); exit(1); } if(*argv[1] == '0') { rendering = false; } else { rendering = true; } char buf[strlen(argv[2]) + 10]; /* Set window size */ width = 1024; height = 1024; depth = 32; tree = init_tree(10, NULL); for (i = 0; i < 100000; i++) { tree->insert(phys_gen_particle()); if (i % 10000 == 0) printf("%d\n", i); } /* Create the drawing surface */ if(rendering) { /* Create the X11 window */ xwin = (struct XWin **)calloc(sizeof(struct XWin *), 1); xwindow_init(width, height, depth, xwin); surface = cairo_xlib_surface_create((*xwin)->dsp, (*xwin)->win, DefaultVisual((*xwin)->dsp, screen), width, height); cairo_xlib_surface_set_size(surface, width, height); } else { surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); } context = cairo_create(surface); cairo_scale(context, width, height); png = 0; while(1) { if(rendering) { if((*xwin)->should_close) { break; } /* Wait on the input (also sync up to disable flickering) */ if(input_ready(xwin)) { pressed_key = get_key(xwin); } } /* Clear the surface with black */ cairo_set_source_rgb(context, 0.0, 0.0, 0.0); cairo_paint(context); std::queue <QTnode *> nodes; QTnode *t; nodes.push(tree); while (!nodes.empty()) { t = nodes.front(); nodes.pop(); if (!t->children.empty()) { for (i = 0; i < t->children.size(); i++) { nodes.push(t->children[i]); } } else { for (std::list <Particle>::iterator p = t->particles.begin(); p != t->particles.end(); p++) { v = f2_norm((*p).vel); if(v >= 0.4) { r = 1.0; b = 0.0; } else if(v < 0.5) { b = 1.0; r = 0.0; } cairo_set_source_rgba(context, (double)r, 0.0, (double)b, 1.0); cairo_rectangle(context, (*p).pos.x, (*p).pos.y, 2e-3, 2e-3); cairo_fill(context); cairo_set_source_rgba(context, (double)r, 0.0, (double)b, 0.2); cairo_rectangle(context, (*p).pos.x - 1e-3, (*p).pos.y - 1e-3, 4e-3, 4e-3); cairo_fill(context); } } } if(rendering) { /* Flush the X window */ flush_input(xwin); update_screen(xwin); } else { mkdir(argv[2], S_IRWXU | S_IRWXG); sprintf(buf, "%s/%05d.png", argv[2], png++); printf("Making %s\n", buf); cairo_surface_write_to_png (surface, buf); } /* Get the new particles */ timing( tree->calc_global_accel(); tree->move_shit(); ); }