Skip to content

Commit

Permalink
Merge pull request #3211 from jspsych/add-response-ends-trial-vs-circle
Browse files Browse the repository at this point in the history
Add `response_ends_trial` for visual search circle plugin
  • Loading branch information
jodeleeuw authored Jan 14, 2024
2 parents d33176a + ba39cca commit c64d3fe
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/strong-ligers-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@jspsych/plugin-visual-search-circle": minor
---

Adds response_ends_trial parameter, with a default value of `true`
1 change: 1 addition & 0 deletions docs/plugins/visual-search-circle.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The `target_present` and `fixation_image` parameters must always be specified. O
| target_absent_key | string | 'f' | The key to press if the target is not present in the search array. |
| trial_duration | numeric | null | The maximum amount of time the participant is allowed to search before the trial will continue. A value of null will allow the participant to search indefinitely. |
| fixation_duration | numeric | 1000 | How long to show the fixation image for before the search array (in milliseconds). |
| response_ends_trial| boolean | true | If true, the trial will end when the participant makes a response. |

## Data Generated

Expand Down
30 changes: 30 additions & 0 deletions packages/plugin-visual-search-circle/src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,36 @@ describe("visual-search-circle", () => {

expect(getData().values()[0].correct).toBe(true);
});

it("wait when response_ends_trial is false", async () => {
const { displayElement, expectFinished, expectRunning, getData } = await startTimeline([
{
type: visualSearchCircle,
target: "target.png",
foil: "foil.png",
fixation_image: "fixation.png",
set_size: 4,
target_present: true,
target_present_key: "a",
target_absent_key: "b",
response_ends_trial: false,
trial_duration: 1500,
},
]);

expect(displayElement.querySelectorAll("img").length).toBe(1);

jest.advanceTimersByTime(1000); // fixation duration

expect(displayElement.querySelectorAll("img").length).toBe(5);
pressKey("a");
await expectRunning();

jest.runAllTimers();
await expectFinished();

expect(getData().values()[0].correct).toBe(true);
});
});

describe("visual-search-circle simulation", () => {
Expand Down
53 changes: 30 additions & 23 deletions packages/plugin-visual-search-circle/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ const info = <const>{
pretty_name: "Fixation duration",
default: 1000,
},
/** Whether a keyboard response ends the trial early */
response_ends_trial: {
type: ParameterType.BOOL,
pretty_name: "Response ends trial",
default: true,
},
},
};

Expand Down Expand Up @@ -153,12 +159,21 @@ class VisualSearchCirclePlugin implements JsPsychPlugin<Info> {
}, trial.fixation_duration);
};

const end_trial = (rt: number, correct: boolean, key_press: string) => {
const response = {
rt: null,
key: null,
correct: false,
};

const end_trial = () => {
this.jsPsych.pluginAPI.clearAllTimeouts();
this.jsPsych.pluginAPI.cancelAllKeyboardResponses();

// data saving
var trial_data = {
correct: correct,
rt: rt,
response: key_press,
const trial_data = {
correct: response.correct,
rt: response.rt,
response: response.key,
locations: display_locs,
target_present: trial.target_present,
set_size: trial.set_size,
Expand Down Expand Up @@ -186,11 +201,7 @@ class VisualSearchCirclePlugin implements JsPsychPlugin<Info> {
"px;'></img>";
}

var trial_over = false;

const after_response = (info: { key: string; rt: number }) => {
trial_over = true;

var correct = false;

if (
Expand All @@ -202,12 +213,16 @@ class VisualSearchCirclePlugin implements JsPsychPlugin<Info> {
correct = true;
}

clear_display();
response.rt = info.rt;
response.key = info.key;
response.correct = correct;

end_trial(info.rt, correct, info.key);
if (trial.response_ends_trial) {
end_trial();
}
};

var valid_keys = [trial.target_present_key, trial.target_absent_key];
const valid_keys = [trial.target_present_key, trial.target_absent_key];

const key_listener = this.jsPsych.pluginAPI.getKeyboardResponse({
callback_function: after_response,
Expand All @@ -219,19 +234,11 @@ class VisualSearchCirclePlugin implements JsPsychPlugin<Info> {

if (trial.trial_duration !== null) {
this.jsPsych.pluginAPI.setTimeout(() => {
if (!trial_over) {
if (!response.rt) {
this.jsPsych.pluginAPI.cancelKeyboardResponse(key_listener);

trial_over = true;

var rt = null;
var correct = false;
var key_press = null;

clear_display();

end_trial(rt, correct, key_press);
}

end_trial();
}, trial.trial_duration);
}

Expand Down

0 comments on commit c64d3fe

Please sign in to comment.