Eric Clack
Eric Clack

Reputation: 1926

Can't peek keyboard events multiple times in Smalltalk Pharo 2

I want to peek at keyboard events, and according to the docs for Sensor I can do this without removing the event from the queue with peekKeyboardEvent, however it doesn't seem to work.

This works:

"Show that a single event can be checked multiple times"
Transcript clear; show: 'Type something... '; flush.
(Delay forSeconds: 2) wait.
5 timesRepeat: [  
    Transcript show: (Sensor peekEvent); cr
]

Output:

Type something... #(2 48243801 5 2 8 0 0 1)
#(2 48243801 5 2 8 0 0 1)
#(2 48243801 5 2 8 0 0 1)
#(2 48243801 5 2 8 0 0 1)
#(2 48243801 5 2 8 0 0 1)

But this doesn't:

"Show that a single keyboard event can be checked multiple times"
Transcript clear; show: 'Type something... '; flush.
(Delay forSeconds: 2) wait.
5 timesRepeat: [  
    Transcript show: (Sensor peekKeyboardEvent); cr
]

Output:

Type something... #(2 48205144 97 0 0 97 0 1)
nil
nil
nil
nil

A further question: why doesn't Transcript flush cause the output to appear instantly? It only appears after the script has run.

Upvotes: 4

Views: 284

Answers (1)

aka.nice
aka.nice

Reputation: 9382

First thing, pharo is a target that is moving fast, so it's better to tell which version.

The best way to find the answer is to browse code. I'll show this in current development pharo 3.0
If you browse implementors of peekKeyboardEvent (select it then Alt+m), you will find a version in InputEventSensor:

peekKeyboardEvent
    "Allows for use of old Sensor protocol to get at the keyboard,
    as when running kbdTest or the InterpreterSimulator in Morphic"

    ^eventQueue findFirst: [:buf | self isKbdEvent: buf]

If you analyze inst var references to eventQueue

initialize
        "Initialize the receiver"
        super initialize.
        eventQueue := WaitfreeQueue new.
        ...snip...

Then browse WaitfreeQueue (select it then Alt+b)

findFirst: aBlock
    "Note, this method only for backward compatibility. It duplicating the semantics of #nextOrNilSuchThat: completely.
    Use #nextOrNilSuchThat: instead "

    ^ self nextOrNilSuchThat: aBlock

then:

nextOrNilSuchThat: aBlock
    "Fetch an object from queue that satisfies aBlock, skipping (but not removing) any intermediate objects.
    If no object has been found, answer <nil> and leave me intact.

    NOTA BENE:  aBlock can contain a non-local return (^).
    Found item is removed from queue    .

    If queue currently in the middle of extraction by other process, don't wait and return <nil> immediately"
    ...snip...

You can trust the comment, or verify by yourself in code, this method is consuming the event rather than peeking.

So it seems indeed that this polling style is deprecated and loosing support in pharo

Upvotes: 2

Related Questions