1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
"""
A streaming button box.
This module contains a class implementing a streaming button box.
"""
__author__ = 'Florian Krause <florian@expyriment.org>, \
Oliver Lindemann <oliver@expyriment.org>'
__version__ = '0.7.0'
__revision__ = '55a4e7e'
__date__ = 'Wed Mar 26 14:33:37 2014 +0100'
import defaults
import expyriment
from expyriment.misc import compare_codes
from expyriment.misc._timer import get_time
from _keyboard import Keyboard
from _input_output import Input, Output
class StreamingButtonBox(Input, Output):
"""A class implementing a streaming button box input."""
def __init__(self, interface, baseline):
"""Create a streaming button box input.
Parameters
----------
interface : io.SerialPort or io.ParallelPort
an interface object
baseline : int
code that is sent when nothing is pressed (int)
"""
Input.__init__(self)
Output.__init__(self)
self._interface = interface
if baseline is not None:
self._baseline = baseline
else:
self._baseline = defaults.streamingbuttonbox_baseline
@property
def interface(self):
"""Getter for interface."""
return self._interface
@property
def baseline(self):
"""Getter for baseline."""
return self._baseline
@baseline.setter
def baseline(self, value):
"""Setter for baseline"""
self._baseline = value
def clear(self):
"""Clear the receive buffer (if available)."""
self._interface.clear()
if self._logging:
expyriment._active_exp._event_file_log("{0},cleared".format(
self.__class__.__name__), 2)
def check(self, codes=None, bitwise_comparison=False):
"""Check for response codes.
If bitwise_comparison = True, the function performs a bitwise
comparison (logical and) between codes and received input.
Parameters
----------
codes : int or list, optional
certain bit pattern or list of bit pattern to wait for,
if codes is not set (None) the function returns
for any event that differs from the baseline
bitwise_comparison : bool, optional
make a bitwise comparison (default=False)
Returns
-------
key : int
key code or None
"""
while True:
read = self._interface.poll()
if read is not None:
if codes is None and read != self._baseline:
if self._logging:
expyriment._active_exp._event_file_log(
"{0},received,{1},check".format(
self.__class__.__name__,
read), 2)
return read
elif compare_codes(read, codes, bitwise_comparison):
if self._logging:
expyriment._active_exp._event_file_log(
"{0},received,{1},check".format(
self.__class__.__name__,
read))
return read
else:
return None
def wait(self, codes=None, duration=None, no_clear_buffer=False,
bitwise_comparison=False, check_for_control_keys=True):
"""Wait for responses defined as codes.
Notes
-----
If bitwise_comparision = True, the function performs a bitwise
comparison (logical and) between codes and received input and waits
until a certain bit pattern is set.
This will also by default check for control keys (quit and pause).
Thus, keyboard events will be cleared from the cue and cannot be
received by a Keyboard().check() anymore!
Parameters
----------
codes : int or list, optional
bit pattern to wait for
if codes is not set (None) the function returns for any
event that differs from the baseline
duration : int, optional
maximal time to wait in ms
no_clear_buffer : bool, optional
do not clear the buffer (default = False)
bitwise_comparison : bool, optional
make a bitwise comparison (default = False)
check_for_control_keys : bool, optional
checks if control key has been pressed (default=True)
Returns
-------
key : int
key code (or None) that quitted waiting
rt : int
reaction time
"""
start = get_time()
rt = None
if not no_clear_buffer:
self.clear()
while True:
expyriment._active_exp._execute_wait_callback()
if duration is not None:
if int((get_time() - start) * 1000) > duration:
return None, None
found = self.check(codes, bitwise_comparison)
if found is not None:
rt = int((get_time() - start) * 1000)
break
if check_for_control_keys:
if Keyboard.process_control_keys():
break
if self._logging:
expyriment._active_exp._event_file_log(
"{0},received,{1},wait".format(
self.__class__.__name__,
found))
return found, rt
|