Skip to content

Commit 61094d7

Browse files
authored
Merge pull request #3039 from jspsych/simulation-mode-fixes
Fixes for simulation mode
2 parents ba66284 + 545ecba commit 61094d7

File tree

20 files changed

+522
-40
lines changed

20 files changed

+522
-40
lines changed

.changeset/clean-insects-juggle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"jspsych": patch
3+
---
4+
5+
Fix error in how nested parameters were handled in simulation mode, #2911

.changeset/cuddly-mails-bathe.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@jspsych/plugin-instructions": patch
3+
---
4+
5+
Fix simulation mode behavior so that setting RT and/or view_history correctly sets the other parameter

.changeset/few-badgers-rescue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"jspsych": patch
3+
---
4+
5+
Fixed how simulation mode handles `setTimeout` calls to ensure that timeouts are cleared at the end of a trial, even in cases where the user interacts with a simulated trial when the simulation is being run in `visual` mode.

.changeset/funny-guests-rhyme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@jspsych/plugin-serial-reaction-time": patch
3+
---
4+
5+
Fixed issue that caused `pre_target_duration` parameter to not work correctly

.changeset/mean-ads-clap.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@jspsych/plugin-fullscreen": minor
3+
---
4+
5+
Plugin now records RT of the button press to launch fullscreen mode and simulation mode supports setting this property

.changeset/soft-cameras-lie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"jspsych": patch
3+
---
4+
5+
Fixed issue where a trial's `on_load` was not called when using simulation mode but setting a trial's `simulate` option to `false`.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"jspsych": patch
3+
---
4+
5+
Fix target of simulation `dispatchEvent` so that simulation mode works with custom `display_element`

docs/plugins/fullscreen.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ In addition to the [default data collected by all plugins](../overview/plugins.m
2525
Name | Type | Value
2626
-----|------|------
2727
success | boolean | true if the browser supports fullscreen mode (i.e., is not Safari)
28+
rt | number | Response time to click the button that launches fullscreen mode
2829

2930
## Simulation Mode
3031

packages/jspsych/src/JsPsych.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -627,13 +627,14 @@ export class JsPsych {
627627
};
628628

629629
let trial_complete;
630+
let trial_sim_opts;
631+
let trial_sim_opts_merged;
630632
if (!this.simulation_mode) {
631633
trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);
632634
}
633635
if (this.simulation_mode) {
634636
// check if the trial supports simulation
635637
if (trial.type.simulate) {
636-
let trial_sim_opts;
637638
if (!trial.simulation_options) {
638639
trial_sim_opts = this.simulation_options.default;
639640
}
@@ -656,16 +657,23 @@ export class JsPsych {
656657
trial_sim_opts = trial.simulation_options;
657658
}
658659
}
659-
trial_sim_opts = this.utils.deepCopy(trial_sim_opts);
660-
trial_sim_opts = this.replaceFunctionsWithValues(trial_sim_opts, null);
660+
// merge in default options that aren't overriden by the trial's simulation_options
661+
// including nested parameters in the simulation_options
662+
trial_sim_opts_merged = this.utils.deepMerge(
663+
this.simulation_options.default,
664+
trial_sim_opts
665+
);
661666

662-
if (trial_sim_opts?.simulate === false) {
667+
trial_sim_opts_merged = this.utils.deepCopy(trial_sim_opts_merged);
668+
trial_sim_opts_merged = this.replaceFunctionsWithValues(trial_sim_opts_merged, null);
669+
670+
if (trial_sim_opts_merged?.simulate === false) {
663671
trial_complete = trial.type.trial(this.DOM_target, trial, load_callback);
664672
} else {
665673
trial_complete = trial.type.simulate(
666674
trial,
667-
trial_sim_opts?.mode || this.simulation_mode,
668-
trial_sim_opts,
675+
trial_sim_opts_merged?.mode || this.simulation_mode,
676+
trial_sim_opts_merged,
669677
load_callback
670678
);
671679
}
@@ -678,8 +686,13 @@ export class JsPsych {
678686
// see if trial_complete is a Promise by looking for .then() function
679687
const is_promise = trial_complete && typeof trial_complete.then == "function";
680688

681-
// in simulation mode we let the simulate function call the load_callback always.
682-
if (!is_promise && !this.simulation_mode) {
689+
// in simulation mode we let the simulate function call the load_callback always,
690+
// so we don't need to call it here. however, if we are in simulation mode but not simulating
691+
// this particular trial we need to call it.
692+
if (
693+
!is_promise &&
694+
(!this.simulation_mode || (this.simulation_mode && trial_sim_opts_merged?.simulate === false))
695+
) {
683696
load_callback();
684697
}
685698

packages/jspsych/src/modules/plugin-api/SimulationAPI.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
export class SimulationAPI {
2+
constructor(
3+
private getDisplayContainerElement: () => HTMLElement,
4+
private setJsPsychTimeout: (callback: () => void, delay: number) => number
5+
) {}
6+
27
dispatchEvent(event: Event) {
3-
document.body.dispatchEvent(event);
8+
this.getDisplayContainerElement().dispatchEvent(event);
49
}
510

611
/**
@@ -26,7 +31,7 @@ export class SimulationAPI {
2631
*/
2732
pressKey(key: string, delay = 0) {
2833
if (delay > 0) {
29-
setTimeout(() => {
34+
this.setJsPsychTimeout(() => {
3035
this.keyDown(key);
3136
this.keyUp(key);
3237
}, delay);
@@ -43,7 +48,7 @@ export class SimulationAPI {
4348
*/
4449
clickTarget(target: Element, delay = 0) {
4550
if (delay > 0) {
46-
setTimeout(() => {
51+
this.setJsPsychTimeout(() => {
4752
target.dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));
4853
target.dispatchEvent(new MouseEvent("mouseup", { bubbles: true }));
4954
target.dispatchEvent(new MouseEvent("click", { bubbles: true }));
@@ -63,7 +68,7 @@ export class SimulationAPI {
6368
*/
6469
fillTextInput(target: HTMLInputElement, text: string, delay = 0) {
6570
if (delay > 0) {
66-
setTimeout(() => {
71+
this.setJsPsychTimeout(() => {
6772
target.value = text;
6873
}, delay);
6974
} else {

0 commit comments

Comments
 (0)