Skip to content

Commit d603ea2

Browse files
Merge pull request #47 from a2i2/nick/store-result-after-powerup
Save the trial data immediately after the power up animation [CON-2637]
2 parents aeddafc + cba6e27 commit d603ea2

File tree

2 files changed

+127
-125
lines changed

2 files changed

+127
-125
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ Note: When 'Game Time' is mentioned it refers to the Clock used by the Phaser Ga
9292
| `pressTimes` | Array[Number] | An array containing each time the power button was pressed curing the power up animation. Individual press counts are derived from the current Game Time at which the tap occured. |
9393
| `trialSuccess` | Boolean | Whether or not the user reached the effort threshold current trial (0 or 1). |
9494
| `coinsRunningTotal` | Float | The total number of coins the user has earned so far in the task across all completed trials. |
95-
| `trialEndTime` | Number | The Game Time at which the current trial ended. the practice task ended. |
95+
| `trialEndTime` | Number | The Game Time at which the current trial is marked as completed, either that be at the end of the power-up animation or as soon as the route selector times out. |
9696
| `effortTimeLimit` | Number | The amount of time in milliseconds given to the user to reach the effort threshold for the current trial. |
9797
| `recalibration` | Boolean | Whether or not the `thresholdMax` was adjusted due to the user reaching a new maximum number of presses (0 or 1). |
9898
| `thresholdMax` | Number | The maximum number of taps the user has achieved so far across all completed trials, include the calibration trials. |

public/src/scenes/mainTask.js

Lines changed: 126 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -602,134 +602,13 @@ var effortOutcome = function() {
602602
},
603603
callbackScope: this});
604604
}
605+
606+
// save the data immediately after powerup/timeout in the event the walking animation gets interrupted before it completes
607+
saveData(this);
605608
};
606609

607610
// 4. When player hits end of scene, save trial data and move on to the next trial (reload the scene)
608611
var trialEnd = function () {
609-
// get trial end time
610-
trialEndTime = Math.round(this.time.now);
611-
612-
// n.b. nCalibrates now set in versionInfo.js
613-
// we completed the practice, but might be loading back from a cached run so we've already calibrated
614-
615-
var updatedNumCalibrates = nCalibrates;
616-
if (GameCache.cache?.practiceComplete == true && runPractice) {
617-
updatedNumCalibrates = 0;
618-
}
619-
620-
if (trialNo < updatedNumCalibrates) {
621-
// get variables to use
622-
pressTimes = this.registry.get('pressTimes');
623-
pressCount = this.registry.get('pressCount');
624-
pressStartTime = pressTimes[0]; // pressStartTime is the first pressTime
625-
pressEndTime = pressTimes[pressTimes.length - 1]; // pressEndTime is the last pressTime
626-
627-
// get level of effort chosen
628-
if (choice == 'route 1') {
629-
trialEffortPropChosen = trialEffortPropMax1;
630-
trialEffort = trialEffort1;
631-
}
632-
else {
633-
trialEffortPropChosen = trialEffortPropMax2; // else they chose route 2
634-
trialEffort = trialEffort2;
635-
}
636-
// for success trials if pressTime was faster than expected given the effort level, recalibrate
637-
if (pressCount >= trialEffort &&
638-
((pressEndTime - pressStartTime) < (effortTime * trialEffortPropChosen))) {
639-
// calculate their new 100% threshold
640-
var threshold = Math.round(((pressCount / ((pressEndTime - pressStartTime) / 1000)) * (effortTime / 1000)))
641-
// if threshold is greater than the original maxPress: thresholdMax is updated
642-
if (threshold > maxPressCount) {
643-
thresholdMax = threshold
644-
var recalibration = 1;
645-
}
646-
else {
647-
// continue with thresholdMax at maxPressCount
648-
var recalibration = 0;
649-
thresholdMax = maxPressCount;
650-
}
651-
}
652-
else {// the trial wasn't successful or did not need recalibration:
653-
var recalibration = 0; // record recalibration didn't occur
654-
// also keep thresholdMax at maxPressCount
655-
thresholdMax = maxPressCount
656-
657-
}
658-
// save thresholdMax
659-
this.registry.set("thresholdMax", { thresholdMax });
660-
// save it in its own document for easy retrieval later
661-
// saveThresholdMax(this.registry.get("thresholdMax")); // [for firebase]
662-
}
663-
else { // if we are past the first calibration trials
664-
var recalibration = 0; // record recalibration didn't occur
665-
thresholdMax = maxPressCount // do not adjust thresholdMax
666-
};
667-
668-
if (choice == 'timeout') {
669-
// if the choice was a timeout then reset all the relevant variables so the payload doesn't retain the previous trial's data
670-
trialEffortPropChosen = 0;
671-
trialEffort = 0;
672-
choiceRT = 0;
673-
pressCount = 0;
674-
pressTimes = [];
675-
trialSuccess = 0;
676-
pressStartTime = 0;
677-
pressEndTime = 0;
678-
coinsWonThisTrial = 0;
679-
}
680-
681-
// set data to be saved into registry
682-
let taskAttempt = new TaskAttempt(
683-
trialNo,
684-
trialStartTime,
685-
trialReward1,
686-
trialEffort1,
687-
trialEffortPropMax1,
688-
trialReward2,
689-
trialEffort2,
690-
trialEffortPropMax2,
691-
choice,
692-
choiceRT,
693-
pressCount,
694-
pressTimes,
695-
trialSuccess,
696-
nCoins,
697-
trialEndTime,
698-
effortTime,
699-
recalibration,
700-
thresholdMax,
701-
powerCountdown
702-
);
703-
704-
// save the data in a registry for later retrieval
705-
this.registry.set("trial" + trialNo, taskAttempt);
706-
707-
// save data
708-
EmbedContext.sendMessage("trialResult", taskAttempt.stringify());
709-
console.log(this.registry.get("trial" + trialNo));
710-
// saveTaskData(trial, this.registry.get(`trial${trial}`)); // [for firebase]
711-
//saveTrialDataPav(this.registry.get(`trial${trial}`)); // [for Pavlovia deployment only]
712-
713-
// as a fallback for the case where the player misses the coins, we will add the coins regardless if the player touches them or not
714-
if (trialSuccess && choice == 'route 1') {
715-
coinsWonThisTrial = trialReward1;
716-
nCoins += coinsWonThisTrial;
717-
} else if (trialSuccess && choice == 'route 2') {
718-
coinsWonThisTrial = trialReward2;
719-
nCoins += coinsWonThisTrial;
720-
} else {
721-
coinsWonThisTrial = 0;
722-
}
723-
724-
// save the current coin choice to the cache by adding on to the previous dictionary if present
725-
let coinChoices = GameCache.cache?.trialResults ?? {};
726-
coinChoices['trial' + trialNo] = trialSuccess ? coinsWonThisTrial : 0;
727-
728-
// notify the native apps of what the current game state is so they can cache it
729-
let currentGameState = new GameCache(true, trialNo + 1, maxPressCount, nCoins, coinChoices, randTrialsIdx, this.trialSequenceFile);
730-
GameCache.cache = currentGameState;
731-
EmbedContext.sendMessage('currentGameCache', currentGameState.stringify());
732-
733612
// if the user has been shown the 'Are you still there?' message and they trigger it again, kick them out of the task
734613
let isLastTrial = trialNo == nTrials - 1;
735614
let missedTrialDialogShownLimitReached = (missedTrialDialogsShown >= missedTrialDialogLimit) && missedTrialDialogLimit > 0; // ensure that a limit of 0 allows the dialog to be shown as many times as needed
@@ -922,3 +801,126 @@ var showBottomScreenPanel = function(context, titleText, subtitleText, bottomBut
922801
var storeCountdownStarted = function(startTime) {
923802
powerCountdown = startTime;
924803
}
804+
805+
var saveData = function(context) {
806+
// get trial end time
807+
trialEndTime = Math.round(context.time.now);
808+
809+
// n.b. nCalibrates now set in versionInfo.js
810+
// we completed the practice, but might be loading back from a cached run so we've already calibrated
811+
var updatedNumCalibrates = nCalibrates;
812+
if (GameCache.cache?.practiceComplete == true && runPractice) {
813+
updatedNumCalibrates = 0;
814+
}
815+
816+
if (trialNo < updatedNumCalibrates) {
817+
// get variables to use
818+
pressTimes = context.registry.get('pressTimes');
819+
pressCount = context.registry.get('pressCount');
820+
pressStartTime = pressTimes[0]; // pressStartTime is the first pressTime
821+
pressEndTime = pressTimes[pressTimes.length - 1]; // pressEndTime is the last pressTime
822+
823+
// get level of effort chosen
824+
if (choice == 'route 1') {
825+
trialEffortPropChosen = trialEffortPropMax1;
826+
trialEffort = trialEffort1;
827+
}
828+
else {
829+
trialEffortPropChosen = trialEffortPropMax2; // else they chose route 2
830+
trialEffort = trialEffort2;
831+
}
832+
// for success trials if pressTime was faster than expected given the effort level, recalibrate
833+
if (pressCount >= trialEffort &&
834+
((pressEndTime - pressStartTime) < (effortTime * trialEffortPropChosen))) {
835+
// calculate their new 100% threshold
836+
var threshold = Math.round(((pressCount / ((pressEndTime - pressStartTime) / 1000)) * (effortTime / 1000)))
837+
// if threshold is greater than the original maxPress: thresholdMax is updated
838+
if (threshold > maxPressCount) {
839+
thresholdMax = threshold
840+
var recalibration = 1;
841+
}
842+
else {
843+
// continue with thresholdMax at maxPressCount
844+
var recalibration = 0;
845+
thresholdMax = maxPressCount;
846+
}
847+
}
848+
else {// the trial wasn't successful or did not need recalibration:
849+
var recalibration = 0; // record recalibration didn't occur
850+
// also keep thresholdMax at maxPressCount
851+
thresholdMax = maxPressCount
852+
853+
}
854+
// save thresholdMax
855+
context.registry.set("thresholdMax", { thresholdMax });
856+
// save it in its own document for easy retrieval later
857+
// saveThresholdMax(this.registry.get("thresholdMax")); // [for firebase]
858+
}
859+
else { // if we are past the first calibration trials
860+
var recalibration = 0; // record recalibration didn't occur
861+
thresholdMax = maxPressCount // do not adjust thresholdMax
862+
};
863+
864+
// as a fallback for the case where the player misses the coins, we will add the coins regardless if the player touches them or not
865+
if (trialSuccess && choice == 'route 1') {
866+
coinsWonThisTrial = trialReward1;
867+
nCoins += coinsWonThisTrial;
868+
} else if (trialSuccess && choice == 'route 2') {
869+
coinsWonThisTrial = trialReward2;
870+
nCoins += coinsWonThisTrial;
871+
} else {
872+
coinsWonThisTrial = 0;
873+
}
874+
875+
if (choice == 'timeout') {
876+
// if the choice was a timeout then reset all the relevant variables so the payload doesn't retain the previous trial's data
877+
trialEffortPropChosen = 0;
878+
trialEffort = 0;
879+
choiceRT = 0;
880+
pressCount = 0;
881+
pressTimes = [];
882+
trialSuccess = 0;
883+
pressStartTime = 0;
884+
pressEndTime = 0;
885+
coinsWonThisTrial = 0;
886+
}
887+
888+
// set data to be saved into registry
889+
let taskAttempt = new TaskAttempt(
890+
trialNo,
891+
trialStartTime,
892+
trialReward1,
893+
trialEffort1,
894+
trialEffortPropMax1,
895+
trialReward2,
896+
trialEffort2,
897+
trialEffortPropMax2,
898+
choice,
899+
choiceRT,
900+
pressCount,
901+
pressTimes,
902+
trialSuccess,
903+
nCoins,
904+
trialEndTime,
905+
effortTime,
906+
recalibration,
907+
thresholdMax,
908+
powerCountdown
909+
);
910+
911+
// save the data in a registry for later retrieval
912+
context.registry.set("trial" + trialNo, taskAttempt);
913+
914+
// inform the native apps of the trial result
915+
EmbedContext.sendMessage("trialResult", taskAttempt.stringify());
916+
console.log(context.registry.get("trial" + trialNo));
917+
918+
// save the current coin choice to the cache by adding on to the previous dictionary if present
919+
let coinChoices = GameCache.cache?.trialResults ?? {};
920+
coinChoices['trial' + trialNo] = trialSuccess ? coinsWonThisTrial : 0;
921+
922+
// notify the native apps of what the current game state is so they can cache it
923+
let currentGameState = new GameCache(true, trialNo + 1, maxPressCount, nCoins, coinChoices, randTrialsIdx, context.trialSequenceFile);
924+
GameCache.cache = currentGameState;
925+
EmbedContext.sendMessage('currentGameCache', currentGameState.stringify());
926+
}

0 commit comments

Comments
 (0)