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 _idle_callback(self, event_loop): # record the time range self._new_time = clock.now() time_err = (self._new_time - self._last_time) / 2.0 self.event_time = event_time(self._last_time + time_err, time_err) clock.tick() ready_for_video = (self._new_time - self.last_flip["time"] >= self.flip_interval) ready_for_kivy_tick = ready_for_video and (self._new_time - self._last_kivy_tick >= self.flip_interval) need_draw = False for video in self.video_queue: 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)): video.update_cb() need_draw = True video.drawn = True self.pending_flip_time = video.flip_time else: break do_kivy_tick = ready_for_kivy_tick or need_draw if do_kivy_tick: _kivy_clock.tick() self._last_kivy_tick = self._new_time event_loop.dispatch_input() if do_kivy_tick: Builder.sync() _kivy_clock.tick_draw() Builder.sync() kivy_needs_draw = EventLoop.window.canvas.needs_redraw or need_draw #print (_kivy_clock.get_fps(), _kivy_clock.get_rfps(), self._new_time) #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! else: kivy_needs_draw = False if kivy_needs_draw: EventLoop.window.dispatch('on_draw') if ready_for_video: need_flip = kivy_needs_draw and self.pending_flip_time is None flip_time_callbacks = [] for video in self.video_queue: if video.drawn and video.flip_time == self.pending_flip_time: need_flip = True if video.flip_time_cb is not None: flip_time_callbacks.append(video.flip_time_cb) video.flipped = True else: break while len(self.video_queue) and self.video_queue[0].flipped: del self.video_queue[0] if need_flip: if len(flip_time_callbacks): #print "BLOCKING FLIP!" #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! self.blocking_flip() #TODO: use sync events instead! for cb in flip_time_callbacks: cb(self.last_flip) else: #print "FLIP!" #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! EventLoop.window.dispatch('on_flip') self.last_flip = event_time(clock.now(), 0.0) self.pending_flip_time = None # save the time self._last_time = self._new_time # exit if experiment done if not self.exp._root_state._active: self.stop() # give time to other threads clock.usleep(250)
def _idle_callback(self, event_loop): # record the time range self._new_time = clock.now() time_err = (self._new_time - self._last_time) / 2.0 self.event_time = event_time(self._last_time + time_err, time_err) # call any of our scheduled events that are ready clock.tick() # see if we're ready for video ready_for_video = ((self._new_time - self.last_flip["time"]) >= (self.flip_interval - FLIP_TIME_MARGIN)) # see if the kivy clock needs a tick # throttled by flip interval ready_for_kivy_tick = ready_for_video and (self._new_time - self._last_kivy_tick >= self.flip_interval) # prepare for every video to be drawn on the next flip need_draw = False for video in self.video_queue: 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() need_draw = True 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 # do a kivy tick if we're going to be drawing or enough time # has passed (see above) do_kivy_tick = ready_for_kivy_tick or need_draw if do_kivy_tick: # tick the kivy clock _kivy_clock.tick() self._last_kivy_tick = self._new_time # dispatch input events event_loop.dispatch_input() # process the builder and check for kivy draws if do_kivy_tick: Builder.sync() _kivy_clock.tick_draw() Builder.sync() kivy_needs_draw = EventLoop.window.canvas.needs_redraw or need_draw # print (_kivy_clock.get_fps(), # _kivy_clock.get_rfps(), self._new_time) else: kivy_needs_draw = False # dispatch draw if necessary if kivy_needs_draw: EventLoop.window.dispatch('on_draw') # handle video and flips if ready_for_video: # we need flip if kivy needs one need_flip = kivy_needs_draw and self.pending_flip_time is None flip_time_callbacks = [] for video in self.video_queue: if video.drawn and video.flip_time == self.pending_flip_time: # a smile video change is ready, so we need flip need_flip = True # append the flip time callback if video.flip_time_cb is not None: 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] # do flip if necessary if need_flip: # test if blocking or non-blocking flip # do a blocking if: # 1) The pending flip is outside a single flip interval # AND # 2) Forcing a blocking flip_interval # OR # 3) We have a specific flip callback request and we # are not forcing a non-blocking flip if (self.pending_flip_time > (self.last_flip['time'] + self.flip_interval + FLIP_TIME_MARGIN)) and \ (self.force_blocking_flip or (len(flip_time_callbacks) and not self.force_nonblocking_flip)): # print "BLOCKING FLIP!" self.blocking_flip() # for cb in flip_time_callbacks: # cb(self.last_flip) else: # non-blicking flip # print "FLIP!" EventLoop.window.dispatch('on_flip') self.last_flip = event_time(clock.now(), 0.0) # still may need to update flip_time_callbacks # even though they will be wrong for cb in flip_time_callbacks: cb(self.last_flip) # tell refs that last_flip updated self.last_flip_ref.dep_changed() # no longer pending flip self.pending_flip_time = None # save the time self._last_time = self._new_time # 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(250)
def _idle_callback(self, event_loop): # record the time range self._new_time = clock.now() time_err = (self._new_time - self._last_time) / 2.0 self.event_time = event_time(self._last_time + time_err, time_err) clock.tick() ready_for_video = (self._new_time - self.last_flip["time"] >= self.flip_interval) ready_for_kivy_tick = ready_for_video and ( self._new_time - self._last_kivy_tick >= self.flip_interval) need_draw = False for video in self.video_queue: 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)): video.update_cb() need_draw = True video.drawn = True self.pending_flip_time = video.flip_time else: break do_kivy_tick = ready_for_kivy_tick or need_draw if do_kivy_tick: _kivy_clock.tick() self._last_kivy_tick = self._new_time event_loop.dispatch_input() if do_kivy_tick: Builder.sync() _kivy_clock.tick_draw() Builder.sync() kivy_needs_draw = EventLoop.window.canvas.needs_redraw or need_draw #print (_kivy_clock.get_fps(), _kivy_clock.get_rfps(), self._new_time) #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! else: kivy_needs_draw = False if kivy_needs_draw: EventLoop.window.dispatch('on_draw') if ready_for_video: need_flip = kivy_needs_draw and self.pending_flip_time is None flip_time_callbacks = [] for video in self.video_queue: if video.drawn and video.flip_time == self.pending_flip_time: need_flip = True if video.flip_time_cb is not None: flip_time_callbacks.append(video.flip_time_cb) video.flipped = True else: break while len(self.video_queue) and self.video_queue[0].flipped: del self.video_queue[0] if need_flip: if len(flip_time_callbacks): #print "BLOCKING FLIP!" #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! self.blocking_flip() #TODO: use sync events instead! for cb in flip_time_callbacks: cb(self.last_flip) else: #print "FLIP!" #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! EventLoop.window.dispatch('on_flip') self.last_flip = event_time(clock.now(), 0.0) self.pending_flip_time = None # save the time self._last_time = self._new_time # exit if experiment done if not self.exp._root_state._active: self.stop() # give time to other threads clock.usleep(250)
def _idle_callback(self, event_loop): # record the time range self._new_time = clock.now() time_err = (self._new_time - self._last_time) / 2.0 self.event_time = event_time(self._last_time + time_err, time_err) # call any of our scheduled events that are ready clock.tick() # see if we're ready for video ready_for_video = ((self._new_time - self.last_flip["time"]) >= (self.flip_interval - FLIP_TIME_MARGIN)) # see if the kivy clock needs a tick # throttled by flip interval ready_for_kivy_tick = ready_for_video and ( self._new_time - self._last_kivy_tick >= self.flip_interval) # prepare for every video to be drawn on the next flip need_draw = False for video in self.video_queue: 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() need_draw = True 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 # do a kivy tick if we're going to be drawing or enough time # has passed (see above) # but only tick and draw once before a flip do_kivy_tick = ready_for_kivy_tick or need_draw if do_kivy_tick: # tick the kivy clock _kivy_clock.tick() self._last_kivy_tick = self._new_time # dispatch input events event_loop.dispatch_input() # process the builder and check for kivy draws if do_kivy_tick: Builder.sync() _kivy_clock.tick_draw() Builder.sync() kivy_needs_draw = EventLoop.window.canvas.needs_redraw or need_draw # print (_kivy_clock.get_fps(), # _kivy_clock.get_rfps(), self._new_time) else: kivy_needs_draw = False # dispatch draw if necessary if kivy_needs_draw: EventLoop.window.dispatch('on_draw') # handle video and flips if ready_for_video: # we need flip if kivy needs one need_flip = kivy_needs_draw and self.pending_flip_time is None flip_time_callbacks = [] for video in self.video_queue: if video.drawn and video.flip_time == self.pending_flip_time: # a smile video change is ready, so we need flip need_flip = True # append the flip time callback if video.flip_time_cb is not None: 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] # do flip if necessary if need_flip: # 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(flip_time_callbacks) and not self.force_nonblocking_flip): # print "BLOCKING FLIP!" self.blocking_flip() else: # non-blocking flip # print "FLIP!" EventLoop.window.dispatch('on_flip') self.last_flip = event_time(clock.now(), 0.0) # still may need to update flip_time_callbacks # even though they may be wrong for non-blocking flips for cb in flip_time_callbacks: cb(self.last_flip) # tell refs that last_flip updated self.exp._screen._set_last_flip(self.last_flip) # no longer pending flip self.pending_flip_time = None # save the time self._last_time = self._new_time # 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)
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)