Cancelling events

Top  Previous  Next

The WhiskerServer sends an Event: message to the control whenever an event occurs of which the client has requested notification with one of the 'SetEvent' commands. Usually, this event is then simply passed on, along with the event's time stamp (the time, in ms, from the client's connection or the last call to ResetClock), to the _Event() subroutine of the control.

 

However, there are two occasions when such an event is not simply passed on:

 

1.When the client has instructed the SDK to ignore events of this name (using KillEvent).
2.When a schedule has been setup between this Event and another Event, and a cycle of this schedule is complete.

 

Consider the following extract from a VB program:

 

Private Sub Start()

       Whisker.TimerSetEvent "TrialOver", 1000, 0

       Whisker.LineSetEvent "Lever", "LeverPress", wsLineToOn

End Sub

 

Private Sub Whisker_Event(ByVal Message As String, ByVal Time As Long)

       Select Case Message

       Case "TrialOver"

               Whisker.LineClearEvent "LeverPress"

               Call ITI

       Case "LeverPress"

               Whisker.TimerClearEvent "TrialOver"

               Call give_reinforcer

               Call ITI

               End Select

End Sub

 

This code seems clear enough, I hope. Whatever the event that occurs first, the client cancels other outstanding events, and moves to the ITI (giving a reinforcer if the rat had pressed) . No problems, it seems.

 

But what if the TrialOver timer finishes just before the rat presses a lever?

 

The following sequence might happen:

 

Server's perspective


Client's perspective

Event: TrialOver




Diagonal_arrow_down_right


 

Event: LeverPress


Case "TrialOver"

Whisker.LineClearEvent "LeverPress"


Diagonal_arrows_down_crossing

Call ITI

ClearLineEvent LeverPress


Case "LeverPress"

Whisker.TimerClearEvent "TrialOver"

Call give_reinforcer

Call ITI

 

Thus, because it takes some time for the client's message to reach the Server, there is always the possibility that two events that seem 'mutually exclusive' may actually both be generated – and the ITI routine gets called twice.  This could have all sorts of nasty consequences – possibly trying to run two trials at the same time!

 

This may be a rare event, as the messages pass so quickly, but that doesn't mean we can ignore the problem – and  with devices that may generate lots of events quickly (like a touchscreen) it could happen frequently!

 

In general: ClearEvent commands cannot block events that are 'on the way' from the Server.

 

This may be inconvenient for some clients, especially for those people who are used to languages such as !Arachnid. Whisker SDK therefore adds an extra command to make this  situation easy to avoid.

 

Instead of (or as well as) telling the Server to 'not send any more Events', we can instruct the SDK to ignore any future events of a certain name (Note: we cannot kill just 'line events' of this name – the event name is all the client will receive!).

 

The SDK command

 

Whisker.KillEvent <eventname>

 

tells the SDK to ignore any events (i.e. not to call the _Event subroutine) with the name eventname. This can be used to make sure that we do not respond to events in the kind of situation shown above. The effect of KillEvent can be reversed by

 

Whisker.ReviveEvent <eventname>

 

or

 

Whisker.ReviveEvent ""

 

to undo all previous KillEvent commands (and respond as normal to all events).

 

So if we replace 'ClearLineEvent' with 'KillEvent', we have solved the problem:

 

Server's perspective


Client's perspective

Event: TrialOver




Diagonal_arrow_down_right


 

Event: LeverPress


Case "TrialOver"

Whisker.KillEvent "LeverPress"


Diagonal_arrow_down_right

Call ITI



(Does nothing; event has been Killed)

 

Note that, in this case, the server will continue to send LeverPress messages, until we Call ClearEvent. So we can just ReviveEvent on the next trial when we care about them again.

 

In summary:

 

SetEvent and ClearEvent are used to control whether the Server sends a message. You cannot be certain that an event is not 'on the way' when you clear it.

 

KillEvent and ReviveEvent are used to control whether or not the SDK calls your _Event() procedure when the event arrives. You can be certain that an Event will not be responded to after it has been Killed.