def do_flip(self, block=True): # call the flip EventLoop.window.dispatch('on_flip') # TODO: use sync events instead! if block: # draw a transparent point # position glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, "\x00\x00\x00\x0a\x00\x00\x00\x0a") # color glVertexAttrib4f(3, 0.0, 0.0, 0.0, 0.0) glDrawArrays(GL_POINTS, 0, 1) # wait for flip then point to draw glFinish() # record the time immediately self.last_flip = event_time(clock.now(), 0.0) else: # we didn't block, so set to predicted flip time self.last_flip = event_time(max(self._next_flip_time, clock.now()), 0.0) # update flip times self._next_flip_time = self.last_flip['time'] + self.flip_interval self._next_draw_time = self.last_flip['time'] + self.flip_interval/2. self._did_draw = False return self.last_flip
def do_flip(self, block=True): # call the flip EventLoop.window.dispatch('on_flip') # TODO: use sync events instead! if block: # draw a transparent point # position glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, "\x00\x00\x00\x0a\x00\x00\x00\x0a") # color glVertexAttrib4f(3, 0.0, 0.0, 0.0, 0.0) glDrawArrays(GL_POINTS, 0, 1) # wait for flip then point to draw glFinish() # record the time immediately self.last_flip = event_time(clock.now(), 0.0) else: # we didn't block, so set to predicted flip time self.last_flip = event_time(self._next_flip_time, 0.0) # update flip times self._next_flip_time = self.last_flip['time'] + self.flip_interval self._next_draw_time = self.last_flip['time'] + self.flip_interval / 2. self._did_draw = False return self.last_flip
def __init__(self, exp=None): super(SmileApp, self).__init__() self.exp = exp self.callbacks = {} self.pending_flip_time = None self.video_queue = [] self.force_blocking_flip = False self.force_nonblocking_flip = False self.flip_interval = 1 / 60. # default to 60 Hz # set event_time stuff self.event_time = event_time(0., 0.) self.dispatch_input_event_time = event_time(0., 0.) # make Window avail to exp self._Window = Window
def __init__(self, exp=None): super(SmileApp, self).__init__() self.exp = exp self.callbacks = {} self.pending_flip_time = None self.video_queue = [] self.force_blocking_flip = False self.force_nonblocking_flip = False self.flip_interval = 1/60. # default to 60 Hz # set event_time stuff self.event_time = event_time(0., 0.) self.dispatch_input_event_time = event_time(0., 0.) # make Window avail to exp self._Window = Window
def _pulse_off_callback(self): self._task.write([0.0]) ev = clock.now() # set the pulse time self._pulse_off = event_time(ev, 0.0) # let's schedule finalizing self._ended = True clock.schedule(self.finalize)
def __init__(self): # set up the values of interest and their refs self._width = 0.0 self._width_ref = Ref.getattr(self, "_width") self._height = 0.0 self._height_ref = Ref.getattr(self, "_height") self._last_flip = event_time(0.0, 0.0) self._last_flip_ref = Ref.getattr(self, "_last_flip") self._mouse_pos = (0, 0) self._mouse_pos_ref = Ref.getattr(self, "_mouse_pos") self._mouse_button = None self._mouse_button_ref = Ref.getattr(self, "_mouse_button") self._keys_down = set() self._issued_key_refs = weakref.WeakValueDictionary()
def _pulse_off_callback(self): # turn off the code if self._sync_style == "parallel": start_time = clock.now() self._sport.setData(0) end_time = clock.now() else: start_time = clock.now() self._sport.setData("0") end_time = clock.now() # clean up / close the port self._sport = None # set the pulse time time_err = (end_time - start_time)/2. self._pulse_off = event_time(start_time+time_err, time_err) # let's schedule finalizing self._ended = True clock.schedule(self.finalize)
def _callback(self): # we've started self._started = True # push it outlet global _got_nidaqmx if _got_nidaqmx: if type(self._push_vals == list): self._task.write(self._push_vals) else: self._task.write([self.push_vals]) ev = clock.now() else: self._pulse_on = None self._pulse_off = None self._ended = True clock.schedule(self.leave) clock.schedule(self.finalize) return # set the pulse time self._pulse_on = event_time(ev, 0.0) # schedule leaving (as soon as this method is done) clock.schedule(self.leave) # schedule the off time if self._width > 0.0: # we're gonna turn off ourselves clock.schedule(self._pulse_off_callback, event_time=self._pulse_on['time'] + self._width) else: # we're gonna leave it self._pulse_off = None # so we can finalize now, too clock.schedule(self.finalize) self._ended = True
def _idle_callback(self, event_loop): # record the time range self._new_time = clock.now() # call any of our scheduled events that are ready clock.tick() # dispatch input events time_err = (clock.now() - self._post_dispatch_time) / 2.0 self.dispatch_input_event_time = event_time( self._post_dispatch_time + time_err, time_err) event_loop.dispatch_input() self._post_dispatch_time = clock.now() # processing video and drawing can only happen if we have # not already drawn if not self._did_draw: # prepare for every video to be drawn on the next flip for video in self.video_queue: # the desired video time must be after the previous flip # is done, so making sure the next_flip_time is after # ensures this is the case if (video.flip_time - self._next_flip_time) < 0.0: if (not video.drawn and ((self.pending_flip_time is None and self._new_time >= (video.flip_time - (self.flip_interval / 2.0))) or video.flip_time == self.pending_flip_time)): # prepare that video change video.update_cb() # it will be drawn video.drawn = True # save the pending time so all other changes # for that time will also run self.pending_flip_time = video.flip_time else: # either none are ready or the remaining are # for a subsequent flip break else: break # do kivy ticks and draw when we're ready # happens at half the flip interval since last flip if clock.now() >= self._next_draw_time: # tick the kivy clock _kivy_clock.tick() # sync Builder and call tick_draw to prepare to draw Builder.sync() _kivy_clock.tick_draw() Builder.sync() EventLoop.window.dispatch('on_draw') # process smile video callbacks for the upcoming flip self._flip_time_callbacks = [] for video in self.video_queue: if video.drawn and video.flip_time == self.pending_flip_time: # append the flip time callback if video.flip_time_cb is not None: self._flip_time_callbacks.append( video.flip_time_cb) # mark that video as flipped (it's gonna be) video.flipped = True else: # no more of the videos could match, so break break # remove any video change that's gonna be flipped while len(self.video_queue) and self.video_queue[0].flipped: del self.video_queue[0] # we've drawn the one time we can this frame self._did_draw = True # do a flip when we're ready # must have completed draw (this will ensure we don't do double flips # inside the FLIP_TIME_MARGIN b/c did_draw will be reset to False upon # the flip if self._did_draw and \ clock.now() >= self._next_flip_time-FLIP_TIME_MARGIN: # test if blocking or non-blocking flip # do a blocking if: # 1) Forcing a blocking flip_interval # OR # 2) We have a specific flip callback request and we # are not forcing a non-blocking flip if self.force_blocking_flip or \ (len(self._flip_time_callbacks) and not self.force_nonblocking_flip): # do a blocking flip self.do_flip(block=True) else: # do a non-blocking flip self.do_flip(block=False) # still may need to update flip_time_callbacks # even though they may be wrong for non-blocking flips for cb in self._flip_time_callbacks: cb(self.last_flip) # tell refs that last_flip updated self.exp._screen._set_last_flip(self.last_flip) # reset for next flip self.pending_flip_time = None # exit if experiment done if not self.exp._root_executor._active: if self.exp._root_executor._enter_time: # stop if we're not active, but we have an enter time self.stop() # give time to other threads clock.usleep(IDLE_USLEEP) # save the time self._last_time = clock.now() time_err = (self._last_time - self._new_time) / 2.0 self.event_time = event_time(self._new_time + time_err, time_err)
def _callback(self): # we've started self._started = True # Pull in the global variables global PI global SI if PI or SI: # send the port code and time it try: if self._sync_style == "parallel": # Create a parallel port object # from the global variable (locks it exclusively) self._sport = PI(address=self._port) start_time = clock.now() self._sport.setData(self._code_num) end_time = clock.now() elif self._sync_style == "serial": self._sport = SI(address=self._port) start_time = clock.now() self._sport.setData(self._code_num) end_time = clock.now() except: # eventually figure out which errors to catch sys.stderr.write("\nWARNING: The sync module could not send pulses,\n" + "\tso no sync pulsing will be generated.\n\n") PI = None self._pport = None self._pulse_on = None self._pulse_off = None self._ended = True clock.schedule(self.leave) clock.schedule(self.finalize) return # set the pulse time time_err = (end_time - start_time)/2. self._pulse_on = event_time(start_time+time_err, time_err) # schedule leaving (as soon as this method is done) clock.schedule(self.leave) # schedule the off time if self._width > 0.0: # we're gonna turn off ourselves clock.schedule(self._pulse_off_callback, event_time=self._pulse_on['time']+self._width) else: # we're gonna leave it self._pulse_off = None # clean up/ close the port self._sport = None # so we can finalize now, too clock.schedule(self.finalize) self._ended = True else: # we can leave and finalize now self._pulse_on = None self._pulse_off = None self._ended = True clock.schedule(self.leave) clock.schedule(self.finalize)
def _idle_callback(self, event_loop): # record the time range self._new_time = clock.now() # call any of our scheduled events that are ready clock.tick() # dispatch input events time_err = (clock.now() - self._post_dispatch_time) / 2.0 self.dispatch_input_event_time = event_time(self._post_dispatch_time + time_err, time_err) event_loop.dispatch_input() self._post_dispatch_time = clock.now() # processing video and drawing can only happen if we have # not already drawn if not self._did_draw: # prepare for every video to be drawn on the next flip for video in self.video_queue: # the desired video time must be after the previous flip # is done, so making sure the next_flip_time is after # ensures this is the case if (video.flip_time - self._next_flip_time) < 0.0: if (not video.drawn and ((self.pending_flip_time is None and self._new_time >= (video.flip_time - (self.flip_interval / 2.0))) or video.flip_time == self.pending_flip_time)): # prepare that video change video.update_cb() # it will be drawn video.drawn = True # save the pending time so all other changes # for that time will also run self.pending_flip_time = video.flip_time else: # either none are ready or the remaining are # for a subsequent flip break else: break # do kivy ticks and draw when we're ready # happens at half the flip interval since last flip if clock.now() >= self._next_draw_time: # tick the kivy clock _kivy_clock.tick() # sync Builder and call tick_draw to prepare to draw Builder.sync() _kivy_clock.tick_draw() Builder.sync() EventLoop.window.dispatch('on_draw') # process smile video callbacks for the upcoming flip self._flip_time_callbacks = [] for video in self.video_queue: if video.drawn and video.flip_time == self.pending_flip_time: # append the flip time callback if video.flip_time_cb is not None: self._flip_time_callbacks.append(video.flip_time_cb) # mark that video as flipped (it's gonna be) video.flipped = True else: # no more of the videos could match, so break break # remove any video change that's gonna be flipped while len(self.video_queue) and self.video_queue[0].flipped: del self.video_queue[0] # we've drawn the one time we can this frame self._did_draw = True # do a flip when we're ready # must have completed draw (this will ensure we don't do double flips # inside the FLIP_TIME_MARGIN b/c did_draw will be reset to False upon # the flip if self._did_draw and \ clock.now() >= self._next_flip_time-FLIP_TIME_MARGIN: # test if blocking or non-blocking flip # do a blocking if: # 1) Forcing a blocking flip_interval # OR # 2) We have a specific flip callback request and we # are not forcing a non-blocking flip if self.force_blocking_flip or \ (len(self._flip_time_callbacks) and not self.force_nonblocking_flip): # do a blocking flip self.do_flip(block=True) else: # do a non-blocking flip self.do_flip(block=False) # still may need to update flip_time_callbacks # even though they may be wrong for non-blocking flips for cb in self._flip_time_callbacks: cb(self.last_flip) # tell refs that last_flip updated self.exp._screen._set_last_flip(self.last_flip) # reset for next flip self.pending_flip_time = None # exit if experiment done if not self.exp._root_executor._active: if self.exp._root_executor._enter_time: # stop if we're not active, but we have an enter time self.stop() # give time to other threads clock.usleep(IDLE_USLEEP) # save the time self._last_time = clock.now() time_err = (self._last_time - self._new_time) / 2.0 self.event_time = event_time(self._new_time + time_err, time_err)