mirror of
https://github.com/psychopy/psychojs.git
synced 2025-05-10 10:40:54 +00:00
Merge pull request #90 from sijiazhao/master
BF: Multiple fixes, mostly re GUI dlg; fixes #52
This commit is contained in:
commit
c48af52eec
@ -19,7 +19,7 @@ import * as util from '../util/Util';
|
|||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
* Graphic User Interface
|
* Graphic User Interface
|
||||||
*
|
*
|
||||||
* @name module:core.GUI
|
* @name module:core.GUI
|
||||||
* @class
|
* @class
|
||||||
* @param {module:core.PsychoJS} psychoJS the PsychoJS instance
|
* @param {module:core.PsychoJS} psychoJS the PsychoJS instance
|
||||||
@ -46,7 +46,7 @@ export class GUI
|
|||||||
* <p>Create a dialog box that (a) enables the participant to set some
|
* <p>Create a dialog box that (a) enables the participant to set some
|
||||||
* experimental values (e.g. the session name), (b) shows progress of resource
|
* experimental values (e.g. the session name), (b) shows progress of resource
|
||||||
* download, and (c) enables the participant to cancel the experiment.</p>
|
* download, and (c) enables the participant to cancel the experiment.</p>
|
||||||
*
|
*
|
||||||
* <b>Setting experiment values</b>
|
* <b>Setting experiment values</b>
|
||||||
* <p>DlgFromDict displays an input field for all values in the dictionary.
|
* <p>DlgFromDict displays an input field for all values in the dictionary.
|
||||||
* It is possible to specify default values e.g.:</p>
|
* It is possible to specify default values e.g.:</p>
|
||||||
@ -55,7 +55,7 @@ export class GUI
|
|||||||
* psychoJS.schedule(psychoJS.gui.DlgFromDict({dictionary: expInfo, title: expName}));</code>
|
* psychoJS.schedule(psychoJS.gui.DlgFromDict({dictionary: expInfo, title: expName}));</code>
|
||||||
* <p>If the participant cancels (by pressing Cancel or by closing the dialog box), then
|
* <p>If the participant cancels (by pressing Cancel or by closing the dialog box), then
|
||||||
* the dictionary remains unchanged.</p>
|
* the dictionary remains unchanged.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.GUI#DlgFromDict
|
* @name module:core.GUI#DlgFromDict
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -79,7 +79,7 @@ export class GUI
|
|||||||
this._progressBarMax = 0;
|
this._progressBarMax = 0;
|
||||||
this._allResourcesDownloaded = false;
|
this._allResourcesDownloaded = false;
|
||||||
this._requiredKeys = [];
|
this._requiredKeys = [];
|
||||||
this._nbSetRequiredKeys = 0;
|
this._setRequiredKeys = new Map();
|
||||||
|
|
||||||
|
|
||||||
// prepare PsychoJS component:
|
// prepare PsychoJS component:
|
||||||
@ -130,7 +130,7 @@ export class GUI
|
|||||||
htmlCode += '<form>';
|
htmlCode += '<form>';
|
||||||
for (const key in dictionary) {
|
for (const key in dictionary) {
|
||||||
const value = dictionary[key];
|
const value = dictionary[key];
|
||||||
const keyId = key + '_id';
|
const keyId = $.escapeSelector(key) + '_id';
|
||||||
|
|
||||||
// only create an input if the key is not in the URL:
|
// only create an input if the key is not in the URL:
|
||||||
let inUrl = false;
|
let inUrl = false;
|
||||||
@ -146,7 +146,7 @@ export class GUI
|
|||||||
|
|
||||||
if (!inUrl)
|
if (!inUrl)
|
||||||
{
|
{
|
||||||
htmlCode += '<label for="' + key + '">' + key + '</label>';
|
htmlCode += '<label for="' + keyId + '">' + key + '</label>';
|
||||||
|
|
||||||
// if the field is required:
|
// if the field is required:
|
||||||
if (key.slice(-1) === '*')
|
if (key.slice(-1) === '*')
|
||||||
@ -200,10 +200,10 @@ export class GUI
|
|||||||
|
|
||||||
// setup change event handlers for all required keys:
|
// setup change event handlers for all required keys:
|
||||||
for (const key of this._requiredKeys) {
|
for (const key of this._requiredKeys) {
|
||||||
const keyId = key + '_id';
|
const keyId = $.escapeSelector(key) + '_id';
|
||||||
const input = document.getElementById(keyId);
|
const input = document.getElementById(keyId);
|
||||||
if (input)
|
if (input)
|
||||||
input.onchange = (event) => GUI._onKeyChange(self, event);
|
input.oninput = (event) => GUI._onKeyChange(self, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// init and open the dialog box:
|
// init and open the dialog box:
|
||||||
@ -227,7 +227,7 @@ export class GUI
|
|||||||
|
|
||||||
// update dictionary:
|
// update dictionary:
|
||||||
for (const key in dictionary) {
|
for (const key in dictionary) {
|
||||||
const input = document.getElementById(key + "_id");
|
const input = document.getElementById($.escapeSelector(key) + "_id");
|
||||||
if (input)
|
if (input)
|
||||||
dictionary[key] = input.value;
|
dictionary[key] = input.value;
|
||||||
}
|
}
|
||||||
@ -255,6 +255,7 @@ export class GUI
|
|||||||
// close is called by both buttons and when the user clicks on the cross:
|
// close is called by both buttons and when the user clicks on the cross:
|
||||||
close: function () {
|
close: function () {
|
||||||
//$.unblockUI();
|
//$.unblockUI();
|
||||||
|
$(this).dialog('destroy').remove();
|
||||||
self._dialogComponent.status = PsychoJS.Status.FINISHED;
|
self._dialogComponent.status = PsychoJS.Status.FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,9 +294,9 @@ export class GUI
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Show a message to the participant in a dialog box.
|
* Show a message to the participant in a dialog box.
|
||||||
*
|
*
|
||||||
* <p>This function can be used to display both warning and error messages.</p>
|
* <p>This function can be used to display both warning and error messages.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.GUI#dialog
|
* @name module:core.GUI#dialog
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -313,8 +314,6 @@ export class GUI
|
|||||||
showOK = true,
|
showOK = true,
|
||||||
onOK
|
onOK
|
||||||
} = {}) {
|
} = {}) {
|
||||||
// destroy previous dialog box:
|
|
||||||
this.destroyDialog();
|
|
||||||
|
|
||||||
let htmlCode;
|
let htmlCode;
|
||||||
let titleColour;
|
let titleColour;
|
||||||
@ -348,7 +347,7 @@ export class GUI
|
|||||||
{
|
{
|
||||||
stackCode += '<li><b>' + error + '</b></li>';
|
stackCode += '<li><b>' + error + '</b></li>';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stackCode += '</ul>';
|
stackCode += '</ul>';
|
||||||
|
|
||||||
@ -391,7 +390,7 @@ export class GUI
|
|||||||
// replace root by the html code:
|
// replace root by the html code:
|
||||||
const dialogElement = document.getElementById('root');
|
const dialogElement = document.getElementById('root');
|
||||||
dialogElement.innerHTML = htmlCode;
|
dialogElement.innerHTML = htmlCode;
|
||||||
|
|
||||||
// init and open the dialog box:
|
// init and open the dialog box:
|
||||||
this._estimateDialogScalingFactor();
|
this._estimateDialogScalingFactor();
|
||||||
const dialogSize = this._getDialogSize();
|
const dialogSize = this._getDialogSize();
|
||||||
@ -410,7 +409,7 @@ export class GUI
|
|||||||
id: "buttonOk",
|
id: "buttonOk",
|
||||||
text: "Ok",
|
text: "Ok",
|
||||||
click: function() {
|
click: function() {
|
||||||
$(this).dialog("close");
|
$(this).dialog("destroy").remove();
|
||||||
|
|
||||||
// execute callback function:
|
// execute callback function:
|
||||||
if (typeof onOK !== 'undefined')
|
if (typeof onOK !== 'undefined')
|
||||||
@ -504,24 +503,6 @@ export class GUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the currently opened dialog box.
|
|
||||||
*
|
|
||||||
* @name module:core.GUI#dialog
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
destroyDialog()
|
|
||||||
{
|
|
||||||
if ($("#expDialog").length) {
|
|
||||||
$("#expDialog").dialog("destroy");
|
|
||||||
}
|
|
||||||
if ($("#msgDialog").length) {
|
|
||||||
$("#msgDialog").dialog("destroy");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener for resource event from the [Server Manager]{@link ServerManager}.
|
* Listener for resource event from the [Server Manager]{@link ServerManager}.
|
||||||
*
|
*
|
||||||
@ -581,7 +562,7 @@ export class GUI
|
|||||||
*/
|
*/
|
||||||
_updateOkButtonStatus()
|
_updateOkButtonStatus()
|
||||||
{
|
{
|
||||||
if (this._psychoJS.getEnvironment() === ExperimentHandler.Environment.LOCAL || (this._allResourcesDownloaded && this._nbSetRequiredKeys >= this._requiredKeys.length) )
|
if (this._psychoJS.getEnvironment() === ExperimentHandler.Environment.LOCAL || (this._allResourcesDownloaded && this._setRequiredKeys.size >= this._requiredKeys.length) )
|
||||||
{
|
{
|
||||||
$("#buttonOk").button("option", "disabled", false);
|
$("#buttonOk").button("option", "disabled", false);
|
||||||
} else
|
} else
|
||||||
@ -656,9 +637,9 @@ export class GUI
|
|||||||
const value = element.value;
|
const value = element.value;
|
||||||
|
|
||||||
if (typeof value !== 'undefined' && value.length > 0)
|
if (typeof value !== 'undefined' && value.length > 0)
|
||||||
gui._nbSetRequiredKeys++;
|
gui._setRequiredKeys.set(event.target, true);
|
||||||
else
|
else
|
||||||
gui._nbSetRequiredKeys--;
|
gui._setRequiredKeys.delete(event.target);
|
||||||
|
|
||||||
gui._updateOkButtonStatus();
|
gui._updateOkButtonStatus();
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import * as util from '../util/Util';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>PsychoJS manages the lifecycle of an experiment. It initialises the PsychoJS library and its various components (e.g. the {@link ServerManager}, the {@link EventManager}), and is used by the experiment to schedule the various tasks.</p>
|
* <p>PsychoJS manages the lifecycle of an experiment. It initialises the PsychoJS library and its various components (e.g. the {@link ServerManager}, the {@link EventManager}), and is used by the experiment to schedule the various tasks.</p>
|
||||||
*
|
*
|
||||||
* @class
|
* @class
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {boolean} [options.debug= true] whether or not to log debug information in the browser console
|
* @param {boolean} [options.debug= true] whether or not to log debug information in the browser console
|
||||||
@ -125,10 +125,10 @@ export class PsychoJS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a PsychoJS Window.
|
* Open a PsychoJS Window.
|
||||||
*
|
*
|
||||||
* <p>This opens a PIXI canvas.</p>
|
* <p>This opens a PIXI canvas.</p>
|
||||||
* <p>Note: we can only open one window.</p>
|
* <p>Note: we can only open one window.</p>
|
||||||
*
|
*
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {string} [options.name] the name of the window
|
* @param {string} [options.name] the name of the window
|
||||||
* @param {boolean} [options.fullscr] whether or not to go fullscreen
|
* @param {boolean} [options.fullscr] whether or not to go fullscreen
|
||||||
@ -138,7 +138,7 @@ export class PsychoJS
|
|||||||
* @param {boolean} [options.waitBlanking] whether or not to wait for all rendering operations to be done
|
* @param {boolean} [options.waitBlanking] whether or not to wait for all rendering operations to be done
|
||||||
* before flipping
|
* before flipping
|
||||||
* @throws {Object.<string, *>} exception if a window has already been opened
|
* @throws {Object.<string, *>} exception if a window has already been opened
|
||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
openWindow({
|
openWindow({
|
||||||
@ -168,7 +168,7 @@ export class PsychoJS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the completion and cancellation URL to which the participant will be redirect at the end of the experiment.
|
* Set the completion and cancellation URL to which the participant will be redirect at the end of the experiment.
|
||||||
*
|
*
|
||||||
* @param {string} completionUrl - the completion URL
|
* @param {string} completionUrl - the completion URL
|
||||||
* @param {string} cancellationUrl - the cancellation URL
|
* @param {string} cancellationUrl - the cancellation URL
|
||||||
*/
|
*/
|
||||||
@ -180,7 +180,7 @@ export class PsychoJS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule a task.
|
* Schedule a task.
|
||||||
*
|
*
|
||||||
* @param task - the task to be scheduled
|
* @param task - the task to be scheduled
|
||||||
* @param args - arguments for that task
|
* @param args - arguments for that task
|
||||||
* @public
|
* @public
|
||||||
@ -198,8 +198,8 @@ export class PsychoJS
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Schedule a series of task based on a condition.
|
* Schedule a series of task based on a condition.
|
||||||
*
|
*
|
||||||
* @param {PsychoJS.condition} condition
|
* @param {PsychoJS.condition} condition
|
||||||
* @param {Scheduler} thenScheduler scheduler to run if the condition is true
|
* @param {Scheduler} thenScheduler scheduler to run if the condition is true
|
||||||
* @param {Scheduler} elseScheduler scheduler to run if the condition is false
|
* @param {Scheduler} elseScheduler scheduler to run if the condition is false
|
||||||
* @public
|
* @public
|
||||||
@ -213,7 +213,7 @@ export class PsychoJS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the experiment.
|
* Start the experiment.
|
||||||
*
|
*
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {string} [options.configURL=config.json] - the URL of the configuration file
|
* @param {string} [options.configURL=config.json] - the URL of the configuration file
|
||||||
* @param {string} [options.expName=UNKNOWN] - the name of the experiment
|
* @param {string} [options.expName=UNKNOWN] - the name of the experiment
|
||||||
@ -324,7 +324,7 @@ export class PsychoJS
|
|||||||
/**
|
/**
|
||||||
* Make the attributes of the given object those of PsychoJS and those of
|
* Make the attributes of the given object those of PsychoJS and those of
|
||||||
* the top level variable (e.g. window) as well.
|
* the top level variable (e.g. window) as well.
|
||||||
*
|
*
|
||||||
* @param {Object.<string, *>} obj the object whose attributes we will mirror
|
* @param {Object.<string, *>} obj the object whose attributes we will mirror
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -344,10 +344,10 @@ export class PsychoJS
|
|||||||
/**
|
/**
|
||||||
* Close everything and exit nicely at the end of the experiment,
|
* Close everything and exit nicely at the end of the experiment,
|
||||||
* potentially redirecting to one of the URLs previously specified by setRedirectUrls.
|
* potentially redirecting to one of the URLs previously specified by setRedirectUrls.
|
||||||
*
|
*
|
||||||
* <p>Note: if the resource manager is busy, we inform the participant
|
* <p>Note: if the resource manager is busy, we inform the participant
|
||||||
* that he or she needs to wait for a bit.</p>
|
* that he or she needs to wait for a bit.</p>
|
||||||
*
|
*
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {string} [options.message] - optional message to be displayed in a dialog box before quitting
|
* @param {string} [options.message] - optional message to be displayed in a dialog box before quitting
|
||||||
* @param {boolean} [options.isCompleted = false] - whether or not the participant has completed the experiment
|
* @param {boolean} [options.isCompleted = false] - whether or not the participant has completed the experiment
|
||||||
@ -387,9 +387,6 @@ export class PsychoJS
|
|||||||
// close the window:
|
// close the window:
|
||||||
self._window.close();
|
self._window.close();
|
||||||
|
|
||||||
// destroy dialog boxes:
|
|
||||||
self._gui.destroyDialog();
|
|
||||||
|
|
||||||
// remove everything from the browser window:
|
// remove everything from the browser window:
|
||||||
while (document.body.hasChildNodes())
|
while (document.body.hasChildNodes())
|
||||||
document.body.removeChild(document.body.lastChild);
|
document.body.removeChild(document.body.lastChild);
|
||||||
@ -415,7 +412,7 @@ export class PsychoJS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure PsychoJS for the running experiment.
|
* Configure PsychoJS for the running experiment.
|
||||||
*
|
*
|
||||||
* @async
|
* @async
|
||||||
* @protected
|
* @protected
|
||||||
* @param {string} configURL - the URL of the configuration file
|
* @param {string} configURL - the URL of the configuration file
|
||||||
@ -515,7 +512,7 @@ export class PsychoJS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Capture all errors and display them in a pop-up error box.
|
* Capture all errors and display them in a pop-up error box.
|
||||||
*
|
*
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_captureErrors() {
|
_captureErrors() {
|
||||||
@ -553,7 +550,7 @@ export class PsychoJS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* PsychoJS status.
|
* PsychoJS status.
|
||||||
*
|
*
|
||||||
* @enum {Symbol}
|
* @enum {Symbol}
|
||||||
* @readonly
|
* @readonly
|
||||||
* @public
|
* @public
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Manager responsible for the communication between the experiment running in the participant's browser and the remote PsychoJS manager running on the remote https://pavlovia.org server.
|
* Manager responsible for the communication between the experiment running in the participant's browser and the remote PsychoJS manager running on the remote https://pavlovia.org server.
|
||||||
*
|
*
|
||||||
* @author Alain Pitiot
|
* @author Alain Pitiot
|
||||||
* @version 2020.1
|
* @version 2020.1
|
||||||
* @copyright (c) 2020 Ilixa Ltd. ({@link http://ilixa.com})
|
* @copyright (c) 2020 Ilixa Ltd. ({@link http://ilixa.com})
|
||||||
@ -21,7 +21,7 @@ import {MonotonicClock} from "../util/Clock";
|
|||||||
* <p>This manager handles all communications between the experiment running in the participant's browser and the remote PsychoJS manager running on the [pavlovia.org]{@link http://pavlovia.org} server, <em>in an asynchronous manner</em>.</p>
|
* <p>This manager handles all communications between the experiment running in the participant's browser and the remote PsychoJS manager running on the [pavlovia.org]{@link http://pavlovia.org} server, <em>in an asynchronous manner</em>.</p>
|
||||||
* <p>It is responsible for reading the configuration file of an experiment, for opening and closing a session, for listing and downloading resources, and for uploading results and log.</p>
|
* <p>It is responsible for reading the configuration file of an experiment, for opening and closing a session, for listing and downloading resources, and for uploading results and log.</p>
|
||||||
* <p>Note: The Server Manager uses [Promises]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise} to deal with asynchronicity, is mostly called by {@link PsychoJS}, and is not exposed to the experiment code.</p>
|
* <p>Note: The Server Manager uses [Promises]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise} to deal with asynchronicity, is mostly called by {@link PsychoJS}, and is not exposed to the experiment code.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager
|
* @name module:core.ServerManager
|
||||||
* @class
|
* @class
|
||||||
* @extends PsychObject
|
* @extends PsychObject
|
||||||
@ -30,7 +30,7 @@ import {MonotonicClock} from "../util/Clock";
|
|||||||
* @param {boolean} [options.autoLog= false] - whether or not to log
|
* @param {boolean} [options.autoLog= false] - whether or not to log
|
||||||
*/
|
*/
|
||||||
export class ServerManager extends PsychObject {
|
export class ServerManager extends PsychObject {
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
psychoJS,
|
psychoJS,
|
||||||
autoLog = false
|
autoLog = false
|
||||||
@ -58,12 +58,12 @@ export class ServerManager extends PsychObject {
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Read the configuration file for the experiment.
|
* Read the configuration file for the experiment.
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#getConfiguration
|
* @name module:core.ServerManager#getConfiguration
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
* @param {string} configURL - the URL of the configuration file
|
* @param {string} configURL - the URL of the configuration file
|
||||||
*
|
*
|
||||||
* @returns {Promise<ServerManager.GetConfigurationPromise>} the response
|
* @returns {Promise<ServerManager.GetConfigurationPromise>} the response
|
||||||
*/
|
*/
|
||||||
getConfiguration(configURL) {
|
getConfiguration(configURL) {
|
||||||
@ -98,7 +98,7 @@ export class ServerManager extends PsychObject {
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Open a session for this experiment on the remote PsychoJS manager.
|
* Open a session for this experiment on the remote PsychoJS manager.
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#openSession
|
* @name module:core.ServerManager#openSession
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -170,7 +170,7 @@ export class ServerManager extends PsychObject {
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Close the session for this experiment on the remote PsychoJS manager.
|
* Close the session for this experiment on the remote PsychoJS manager.
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#closeSession
|
* @name module:core.ServerManager#closeSession
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -230,7 +230,7 @@ export class ServerManager extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of a resource.
|
* Get the value of a resource.
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#getResource
|
* @name module:core.ServerManager#getResource
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -252,7 +252,7 @@ export class ServerManager extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the resource manager status.
|
* Set the resource manager status.
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#setStatus
|
* @name module:core.ServerManager#setStatus
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -280,7 +280,7 @@ export class ServerManager extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the resource manager status to ServerManager.Status.READY.
|
* Reset the resource manager status to ServerManager.Status.READY.
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#resetStatus
|
* @name module:core.ServerManager#resetStatus
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -315,6 +315,7 @@ export class ServerManager extends PsychObject {
|
|||||||
// we use an anonymous async function here since downloadResources is non-blocking (asynchronous)
|
// we use an anonymous async function here since downloadResources is non-blocking (asynchronous)
|
||||||
// but we want to run the asynchronous _listResources and _downloadResources in sequence
|
// but we want to run the asynchronous _listResources and _downloadResources in sequence
|
||||||
const self = this;
|
const self = this;
|
||||||
|
const newResources = new Map();
|
||||||
let download = async () => {
|
let download = async () => {
|
||||||
try {
|
try {
|
||||||
if (self._psychoJS.config.environment === ExperimentHandler.Environment.SERVER) {
|
if (self._psychoJS.config.environment === ExperimentHandler.Environment.SERVER) {
|
||||||
@ -327,13 +328,17 @@ export class ServerManager extends PsychObject {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// only registered the specified resources:
|
// only registered the specified resources:
|
||||||
for (const {name, path} of resources)
|
for (const {name, path} of resources) {
|
||||||
self._resources.set(name, { path });
|
self._resources.set(name, {path});
|
||||||
|
newResources.set(name, {path});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// register the specified resources:
|
// register the specified resources:
|
||||||
for (const {name, path} of resources)
|
for (const {name, path} of resources) {
|
||||||
self._resources.set(name, { path });
|
self._resources.set(name, {path});
|
||||||
|
newResources.set(name, {path});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._nbResources = self._resources.size;
|
self._nbResources = self._resources.size;
|
||||||
@ -343,7 +348,7 @@ export class ServerManager extends PsychObject {
|
|||||||
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.RESOURCES_REGISTERED, count: self._nbResources });
|
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.RESOURCES_REGISTERED, count: self._nbResources });
|
||||||
|
|
||||||
// download the registered resources:
|
// download the registered resources:
|
||||||
await self._downloadRegisteredResources();
|
await self._downloadRegisteredResources(newResources);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log('error', error);
|
console.log('error', error);
|
||||||
@ -355,7 +360,7 @@ export class ServerManager extends PsychObject {
|
|||||||
download();
|
download();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef ServerManager.UploadDataPromise
|
* @typedef ServerManager.UploadDataPromise
|
||||||
* @property {string} origin the calling method
|
* @property {string} origin the calling method
|
||||||
@ -364,13 +369,13 @@ export class ServerManager extends PsychObject {
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Asynchronously upload experiment data to the remote PsychoJS manager.
|
* Asynchronously upload experiment data to the remote PsychoJS manager.
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#uploadData
|
* @name module:core.ServerManager#uploadData
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
* @param {string} key - the data key (e.g. the name of .csv file)
|
* @param {string} key - the data key (e.g. the name of .csv file)
|
||||||
* @param {string} value - the data value (e.g. a string containing the .csv header and records)
|
* @param {string} value - the data value (e.g. a string containing the .csv header and records)
|
||||||
*
|
*
|
||||||
* @returns {Promise<ServerManager.UploadDataPromise>} the response
|
* @returns {Promise<ServerManager.UploadDataPromise>} the response
|
||||||
*/
|
*/
|
||||||
uploadData(key, value)
|
uploadData(key, value)
|
||||||
@ -549,14 +554,14 @@ export class ServerManager extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Download the resources previously registered.
|
* Download the resources previously registered.
|
||||||
*
|
*
|
||||||
* <p>Note: we use the [preloadjs library]{@link https://www.createjs.com/preloadjs}.</p>
|
* <p>Note: we use the [preloadjs library]{@link https://www.createjs.com/preloadjs}.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#_downloadRegisteredResources
|
* @name module:core.ServerManager#_downloadRegisteredResources
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_downloadRegisteredResources()
|
_downloadRegisteredResources(resources = new Map())
|
||||||
{
|
{
|
||||||
const response = { origin: 'ServerManager._downloadResources', context: 'when downloading the resources for experiment: ' + this._psychoJS.config.experiment.name };
|
const response = { origin: 'ServerManager._downloadResources', context: 'when downloading the resources for experiment: ' + this._psychoJS.config.experiment.name };
|
||||||
|
|
||||||
@ -570,6 +575,9 @@ export class ServerManager extends PsychObject {
|
|||||||
this._resourceQueue = new createjs.LoadQueue(true); //, this._psychoJS.config.experiment.resourceDirectory);
|
this._resourceQueue = new createjs.LoadQueue(true); //, this._psychoJS.config.experiment.resourceDirectory);
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
|
const filesToDownload = resources.size ? resources : this._resources;
|
||||||
|
|
||||||
this._resourceQueue.addEventListener("filestart", event => {
|
this._resourceQueue.addEventListener("filestart", event => {
|
||||||
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOADING_RESOURCE, resource: event.item.id });
|
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOADING_RESOURCE, resource: event.item.id });
|
||||||
});
|
});
|
||||||
@ -584,7 +592,7 @@ export class ServerManager extends PsychObject {
|
|||||||
// loading completed:
|
// loading completed:
|
||||||
this._resourceQueue.addEventListener("complete", event => {
|
this._resourceQueue.addEventListener("complete", event => {
|
||||||
self._resourceQueue.close();
|
self._resourceQueue.close();
|
||||||
if (self._nbLoadedResources === self._nbResources) {
|
if (self._nbLoadedResources === filesToDownload.size) {
|
||||||
self.setStatus(ServerManager.Status.READY);
|
self.setStatus(ServerManager.Status.READY);
|
||||||
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOAD_COMPLETED });
|
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOAD_COMPLETED });
|
||||||
}
|
}
|
||||||
@ -602,7 +610,7 @@ export class ServerManager extends PsychObject {
|
|||||||
// (*) dispatch resources to preload.js or howler.js based on extension:
|
// (*) dispatch resources to preload.js or howler.js based on extension:
|
||||||
let manifest = [];
|
let manifest = [];
|
||||||
let soundResources = [];
|
let soundResources = [];
|
||||||
for (const [name, path_data] of this._resources)
|
for (const [name, path_data] of filesToDownload)
|
||||||
{
|
{
|
||||||
const nameParts = name.toLowerCase().split('.');
|
const nameParts = name.toLowerCase().split('.');
|
||||||
const extension = (nameParts.length > 1) ? nameParts.pop() : undefined;
|
const extension = (nameParts.length > 1) ? nameParts.pop() : undefined;
|
||||||
@ -642,7 +650,7 @@ export class ServerManager extends PsychObject {
|
|||||||
if (manifest.length > 0)
|
if (manifest.length > 0)
|
||||||
this._resourceQueue.loadManifest(manifest);
|
this._resourceQueue.loadManifest(manifest);
|
||||||
else {
|
else {
|
||||||
if (this._nbLoadedResources === this._nbResources) {
|
if (this._nbLoadedResources === filesToDownload.size) {
|
||||||
this.setStatus(ServerManager.Status.READY);
|
this.setStatus(ServerManager.Status.READY);
|
||||||
this.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOAD_COMPLETED });
|
this.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOAD_COMPLETED });
|
||||||
}
|
}
|
||||||
@ -665,7 +673,7 @@ export class ServerManager extends PsychObject {
|
|||||||
// self._resources.set(resource.name, howl);
|
// self._resources.set(resource.name, howl);
|
||||||
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.RESOURCE_DOWNLOADED, resource: name });
|
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.RESOURCE_DOWNLOADED, resource: name });
|
||||||
|
|
||||||
if (self._nbLoadedResources === self._nbResources) {
|
if (self._nbLoadedResources === filesToDownload.size) {
|
||||||
self.setStatus(ServerManager.Status.READY);
|
self.setStatus(ServerManager.Status.READY);
|
||||||
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOAD_COMPLETED });
|
self.emit(ServerManager.Event.RESOURCE, { message: ServerManager.Event.DOWNLOAD_COMPLETED });
|
||||||
}
|
}
|
||||||
@ -684,9 +692,9 @@ export class ServerManager extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Server event
|
* Server event
|
||||||
*
|
*
|
||||||
* <p>A server event is emitted by the manager to inform its listeners of either a change of status, or of a resource related event (e.g. download started, download is completed).</p>
|
* <p>A server event is emitted by the manager to inform its listeners of either a change of status, or of a resource related event (e.g. download started, download is completed).</p>
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#Event
|
* @name module:core.ServerManager#Event
|
||||||
* @enum {Symbol}
|
* @enum {Symbol}
|
||||||
* @readonly
|
* @readonly
|
||||||
@ -723,7 +731,7 @@ ServerManager.Event = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Server status
|
* Server status
|
||||||
*
|
*
|
||||||
* @name module:core.ServerManager#Status
|
* @name module:core.ServerManager#Status
|
||||||
* @enum {Symbol}
|
* @enum {Symbol}
|
||||||
* @readonly
|
* @readonly
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Window responsible for displaying the experiment stimuli
|
* Window responsible for displaying the experiment stimuli
|
||||||
*
|
*
|
||||||
* @author Alain Pitiot
|
* @author Alain Pitiot
|
||||||
* @version 2020.1
|
* @version 2020.1
|
||||||
* @copyright (c) 2020 Ilixa Ltd. ({@link http://ilixa.com})
|
* @copyright (c) 2020 Ilixa Ltd. ({@link http://ilixa.com})
|
||||||
@ -15,7 +15,7 @@ import { Logger } from "./Logger";
|
|||||||
/**
|
/**
|
||||||
* <p>Window displays the various stimuli of the experiment.</p>
|
* <p>Window displays the various stimuli of the experiment.</p>
|
||||||
* <p>It sets up a [PIXI]{@link http://www.pixijs.com/} renderer, which we use to render the experiment stimuli.</p>
|
* <p>It sets up a [PIXI]{@link http://www.pixijs.com/} renderer, which we use to render the experiment stimuli.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.Window
|
* @name module:core.Window
|
||||||
* @class
|
* @class
|
||||||
* @extends PsychObject
|
* @extends PsychObject
|
||||||
@ -33,7 +33,7 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for monitorFramePeriod.
|
* Getter for monitorFramePeriod.
|
||||||
*
|
*
|
||||||
* @name module:core.Window#monitorFramePeriod
|
* @name module:core.Window#monitorFramePeriod
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -95,9 +95,9 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the window.
|
* Close the window.
|
||||||
*
|
*
|
||||||
* <p> Note: this actually only removes the canvas used to render the experiment stimuli.</p>
|
* <p> Note: this actually only removes the canvas used to render the experiment stimuli.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.Window#close
|
* @name module:core.Window#close
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -121,7 +121,7 @@ export class Window extends PsychObject {
|
|||||||
{
|
{
|
||||||
this._renderer.destroy();
|
this._renderer.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.removeEventListener('resize', this._resizeCallback);
|
window.removeEventListener('resize', this._resizeCallback);
|
||||||
window.removeEventListener('orientationchange', this._resizeCallback);
|
window.removeEventListener('orientationchange', this._resizeCallback);
|
||||||
|
|
||||||
@ -131,12 +131,12 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimate the frame rate.
|
* Estimate the frame rate.
|
||||||
*
|
*
|
||||||
* @name module:core.Window#getActualFrameRate
|
* @name module:core.Window#getActualFrameRate
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
* @return {number} always returns 60.0 at the moment
|
* @return {number} always returns 60.0 at the moment
|
||||||
*
|
*
|
||||||
* @todo estimate the actual frame rate.
|
* @todo estimate the actual frame rate.
|
||||||
*/
|
*/
|
||||||
getActualFrameRate()
|
getActualFrameRate()
|
||||||
@ -148,7 +148,7 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Take the browser full screen if possible.
|
* Take the browser full screen if possible.
|
||||||
*
|
*
|
||||||
* @name module:core.Window#adjustScreenSize
|
* @name module:core.Window#adjustScreenSize
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -227,9 +227,9 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a message.
|
* Log a message.
|
||||||
*
|
*
|
||||||
* <p> Note: the message will be time-stamped at the next call to requestAnimationFrame.</p>
|
* <p> Note: the message will be time-stamped at the next call to requestAnimationFrame.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.Window#logOnFlip
|
* @name module:core.Window#logOnFlip
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -256,9 +256,9 @@ export class Window extends PsychObject {
|
|||||||
/**
|
/**
|
||||||
* Add a callback function that will run after the next screen flip, i.e. immediately after the next rendering of the
|
* Add a callback function that will run after the next screen flip, i.e. immediately after the next rendering of the
|
||||||
* Window.
|
* Window.
|
||||||
*
|
*
|
||||||
* <p>This is typically used to reset a timer or clock.</p>
|
* <p>This is typically used to reset a timer or clock.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.Window#callOnFlip
|
* @name module:core.Window#callOnFlip
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -273,7 +273,7 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the stimuli onto the canvas.
|
* Render the stimuli onto the canvas.
|
||||||
*
|
*
|
||||||
* @name module:core.Window#render
|
* @name module:core.Window#render
|
||||||
* @function
|
* @function
|
||||||
* @public
|
* @public
|
||||||
@ -315,7 +315,7 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update this window, if need be.
|
* Update this window, if need be.
|
||||||
*
|
*
|
||||||
* @name module:core.Window#_updateIfNeeded
|
* @name module:core.Window#_updateIfNeeded
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
@ -337,7 +337,7 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Recompute this window's draw list and _container children for the next animation frame.
|
* Recompute this window's draw list and _container children for the next animation frame.
|
||||||
*
|
*
|
||||||
* @name module:core.Window#_refresh
|
* @name module:core.Window#_refresh
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
@ -376,10 +376,10 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup PIXI.
|
* Setup PIXI.
|
||||||
*
|
*
|
||||||
* <p>A new renderer is created and a container is added to it. The renderer's touch and mouse events
|
* <p>A new renderer is created and a container is added to it. The renderer's touch and mouse events
|
||||||
* are handled by the {@link EventManager}.</p>
|
* are handled by the {@link EventManager}.</p>
|
||||||
*
|
*
|
||||||
* @name module:core.Window#_setupPixi
|
* @name module:core.Window#_setupPixi
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
@ -457,7 +457,7 @@ export class Window extends PsychObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Send all logged messages to the {@link Logger}.
|
* Send all logged messages to the {@link Logger}.
|
||||||
*
|
*
|
||||||
* @name module:core.Window#_writeLogOnFlip
|
* @name module:core.Window#_writeLogOnFlip
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
|
Loading…
Reference in New Issue
Block a user