Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
 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()
Exemplo n.º 7
0
 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()
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
    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)