psychopy/psychopy — pull request #103 by kastman (2012-02-21 20:29:24+00:00)
Title: Subtle fMRI Emulator Named Key Bug

When using the fMRI Emulator, most keys work as sync signals (the default signal is the key "5"). However, named keys ("equal", "period", "slash") were not advancing the simulator, leaving it sitting and waiting for sync signals even though the SyncGenerator thread was dutifully providing them on cue.

Turns out there's a [very] subtle bug in the way that the SyncGenerator class added keys to the key buffer that preventing them form being used. Previously, the SyncGenerator added the sync key to the key buffer directly as a key string:

```python
# "emit" a sync pulse by placing a key in the buffer:
event._keyBuffer.append(self.sync)
```

I don't know if this is just drift since the emulator class was written, but the keyBuffer is currently expecting a list of tuples (key, onset) and not simply a key.

In event.py, the list of keys is created by walking through the keyBuffer and collecting the first item in each list, which is supposed to be the key (when a tuple is returned from Pyglet or Pygame). Since strings are really just lists of chars, string == string[0] for a string of length 1, since indexing into the string just returns the first character.

Since this didn't affect sites where the sync key is length 1, it was easy to overlook. I think the best fix is to patch the emulator to provide the keyBuffer with the tuple that it's expecting:

```python
# "emit" a sync pulse by placing a key in the buffer:
event._keyBuffer.append((self.sync, core.getTime()))
```

I hoped to write some tests (MRSettings['sync'] = 5... MRSettings['sync'] = 'equal') but used up a whole morning trying to get the existing tests to pass before writing my own, so I gave up and just submitted the request. I'll still work on it, but hopefully it's alright to submit this without. Cheers,

Erik