diff --git a/.changeset/young-pumpkins-argue.md b/.changeset/young-pumpkins-argue.md new file mode 100644 index 00000000..f28ad5a9 --- /dev/null +++ b/.changeset/young-pumpkins-argue.md @@ -0,0 +1,5 @@ +--- +"@jspsych-contrib/plugin-video-several-keyboard-responses": major +--- + +Make data `rt` `key` and `video_time` fields always be an array, even when multiple responses are not allowed. Improve compatibility of simulation mode, though there are still some likely inconsistencies. diff --git a/packages/plugin-video-several-keyboard-responses/src/index.spec.ts b/packages/plugin-video-several-keyboard-responses/src/index.spec.ts index e270ff9d..2e35e597 100644 --- a/packages/plugin-video-several-keyboard-responses/src/index.spec.ts +++ b/packages/plugin-video-several-keyboard-responses/src/index.spec.ts @@ -40,12 +40,17 @@ describe("video-several-keyboard-responses simulation", () => { await expectFinished(); - expect(getData().values()[0].rt).toBeGreaterThan(0); - expect(typeof getData().values()[0].response).toBe("string"); + const data = getData().values()[0]; + + console.log(data); + + expect(data.rt.every((value) => value > 0)).toBe(true); + expect(data.response.length).toEqual(data.rt.length); + expect(data.video_time.length).toEqual(data.rt.length); }); // can't run this until we mock video elements. - test("visual mode works", async () => { + test.skip("visual mode works", async () => { const jsPsych = initJsPsych(); const timeline = [ @@ -53,7 +58,8 @@ describe("video-several-keyboard-responses simulation", () => { type: videoSeveralKeyboardResponses, stimulus: ["foo.mp4"], prompt: "foo", - trial_duration: 1000, + trial_ends_after_video: true, + response_ends_trial: false, }, ]; @@ -78,5 +84,6 @@ describe("video-several-keyboard-responses simulation", () => { expect(rt.every((value) => value > 0)).toBe(true); expect(response.every((value) => typeof value === "string")).toBe(true); expect(video_time.every((value) => typeof value === "number")).toBe(true); + expect(response.length).toEqual(rt.length); }); }); diff --git a/packages/plugin-video-several-keyboard-responses/src/index.ts b/packages/plugin-video-several-keyboard-responses/src/index.ts index c8f4f32b..6f53c67d 100644 --- a/packages/plugin-video-several-keyboard-responses/src/index.ts +++ b/packages/plugin-video-several-keyboard-responses/src/index.ts @@ -295,14 +295,8 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { "#jspsych-video-several-keyboard-responses-stimulus" ).className += " responded"; - // by default only record the first response if (response.key == null) { - if (!trial.multiple_responses_allowed) { - // Would make sense to add it to a list, but then it would not be backwards compatible? - response = { rt: info.rt, key: info.key, video_time: video_element.currentTime }; - } else { - response = { rt: [info.rt], key: [info.key], video_time: [video_element.currentTime] }; - } + response = { rt: [info.rt], key: [info.key], video_time: [video_element.currentTime] }; } else if (trial.multiple_responses_allowed) { response.rt.push(info.rt); response.key.push(info.key); @@ -366,7 +360,9 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { const respond = () => { if (data.rt !== null) { - this.jsPsych.pluginAPI.pressKey(data.response, data.rt); + for (let i = 0; i < data.rt.length; i++) { + this.jsPsych.pluginAPI.pressKey(data.response[i], data.rt[i]); + } } }; @@ -378,16 +374,35 @@ class VideoSeveralKeyboardResponsesPlugin implements JsPsychPlugin { } private create_simulation_data(trial: TrialType, simulation_options) { + let n_responses = this.jsPsych.randomization.randomInt(1, 5); + if (!trial.multiple_responses_allowed) { + n_responses = 1; + } + + const rts = []; + const responses = []; + let last_rt = 0; + for (let i = 0; i < n_responses; i++) { + const rt = Math.round(this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true)); + rts.push(rt + last_rt); + last_rt = rt; + responses.push(this.jsPsych.pluginAPI.getValidKey(trial.choices)); + } + + console.log(rts); + const default_data = { stimulus: trial.stimulus, - rt: this.jsPsych.randomization.sampleExGaussian(500, 50, 1 / 150, true), - response: this.jsPsych.pluginAPI.getValidKey(trial.choices), - video_time: 0, + response: responses, + rt: rts, + video_time: rts, }; const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options); - this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data); + //this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data); + + console.log(data); return data; }