From 1b25755419b5b15f3e5802cf6a65b113d8d77cf4 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:07:39 +0100 Subject: [PATCH 1/8] The BaseCache has a new method `exists` that will return a boolean if an entry for the given key exists in the cache or not. --- src/cache/BaseCache.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/cache/BaseCache.js b/src/cache/BaseCache.js index 7dba163af..9cf4dcc56 100644 --- a/src/cache/BaseCache.js +++ b/src/cache/BaseCache.js @@ -83,6 +83,7 @@ var BaseCache = new Class({ /** * Checks if this cache contains an item matching the given key. + * This performs the same action as `BaseCache.exists`. * * @method Phaser.Cache.BaseCache#has * @since 3.0.0 @@ -96,6 +97,22 @@ var BaseCache = new Class({ return this.entries.has(key); }, + /** + * Checks if this cache contains an item matching the given key. + * This performs the same action as `BaseCache.has` and is called directly by the Loader. + * + * @method Phaser.Cache.BaseCache#exists + * @since 3.7.0 + * + * @param {string} key - The unique key of the item to be checked in this cache. + * + * @return {boolean} Returns `true` if the cache contains an item matching the given key, otherwise `false`. + */ + exists: function (key) + { + return this.entries.has(key); + }, + /** * Gets an item from this cache based on the given key. * From 75a49d284c739af54ed1abdb3f64a36318244f85 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:13:06 +0100 Subject: [PATCH 2/8] Added hasCacheConflict and addToCache methods/ --- src/loader/File.js | 72 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/src/loader/File.js b/src/loader/File.js index e03c4a047..feced7a16 100644 --- a/src/loader/File.js +++ b/src/loader/File.js @@ -40,14 +40,33 @@ var XHRSettings = require('./XHRSettings'); * @constructor * @since 3.0.0 * + * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File. * @param {FileConfig} fileConfig - [description] */ var File = new Class({ initialize: - function File (fileConfig) + function File (loader, fileConfig) { + /** + * A reference to the Loader that is going to load this file. + * + * @name Phaser.Loader.File#loader + * @type {Phaser.Loader.LoaderPlugin} + * @since 3.0.0 + */ + this.loader = loader; + + /** + * A reference to the Cache, or Texture Manager, that is going to store this file if it loads. + * + * @name Phaser.Loader.File#cache + * @type {(Phaser.Cache.BaseCache|Phaser.Textures.TextureManager)} + * @since 3.7.0 + */ + this.cache = GetFastValue(fileConfig, 'cache'); + /** * The file type string (image, json, etc) for sorting within the Loader. * @@ -112,15 +131,6 @@ var File = new Class({ this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {})); } - /** - * The LoaderPlugin instance that is loading this file. - * - * @name Phaser.Loader.File#loader - * @type {?Phaser.Loader.LoaderPlugin} - * @since 3.0.0 - */ - this.loader = null; - /** * The XMLHttpRequest instance (as created by XHR Loader) that is loading this File. * @@ -275,22 +285,18 @@ var File = new Class({ * * @method Phaser.Loader.File#load * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that will load this File. */ - load: function (loader) + load: function () { - this.loader = loader; - if (this.state === CONST.FILE_POPULATED) { this.onComplete(); - loader.nextFile(this); + this.loader.nextFile(this); } else { - this.src = GetURL(this, loader.baseURL); + this.src = GetURL(this, this.loader.baseURL); if (this.src.indexOf('data:') === 0) { @@ -298,7 +304,7 @@ var File = new Class({ } else { - this.xhrLoader = XHRLoader(this, loader.xhr); + this.xhrLoader = XHRLoader(this, this.loader.xhr); } } }, @@ -407,6 +413,36 @@ var File = new Class({ { this.state = CONST.FILE_COMPLETE; } + }, + + /** + * Checks if a key matching the one used by this file exists in the target Cache or not. + * This is called automatically by the LoaderPlugin to decide if the file can be safely + * loaded or will conflict. + * + * @method Phaser.Loader.File#hasCacheConflict + * @since 3.7.0 + * + * @return {boolean} `true` if adding this file will cause a conflict, otherwise `false`. + */ + hasCacheConflict: function () + { + return (this.cache.exists(this.key)); + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * It will emit a `filecomplete` event from the LoaderPlugin. + * This method is often overridden by specific file types. + * + * @method Phaser.Loader.File#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + this.cache.add(this.key, this.data); + + this.loader.emit('filecomplete', this.key, this); } }); From 83a1965cb869aafc51e2575e2a230096e2a1e2d4 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:13:43 +0100 Subject: [PATCH 3/8] Files types updated to support new cache config value --- src/loader/filetypes/AnimationJSONFile.js | 8 +++---- src/loader/filetypes/AtlasJSONFile.js | 11 ++++----- src/loader/filetypes/AudioFile.js | 11 +++++---- src/loader/filetypes/BinaryFile.js | 11 +++++---- src/loader/filetypes/GLSLFile.js | 11 +++++---- src/loader/filetypes/HTML5AudioFile.js | 29 ++++++++++++----------- src/loader/filetypes/HTMLFile.js | 18 ++++++++++---- src/loader/filetypes/ImageFile.js | 26 +++++++++++++------- src/loader/filetypes/JSONFile.js | 7 +++--- src/loader/filetypes/SVGFile.js | 18 ++++++++++---- src/loader/filetypes/SpriteSheetFile.js | 15 ++++++++---- src/loader/filetypes/TextFile.js | 11 +++++---- src/loader/filetypes/TilemapCSVFile.js | 18 ++++++++++---- src/loader/filetypes/TilemapJSONFile.js | 21 +++++++++++----- src/loader/filetypes/UnityAtlasFile.js | 8 +++---- src/loader/filetypes/XMLFile.js | 11 +++++---- 16 files changed, 144 insertions(+), 90 deletions(-) diff --git a/src/loader/filetypes/AnimationJSONFile.js b/src/loader/filetypes/AnimationJSONFile.js index 07bec0797..639f780ad 100644 --- a/src/loader/filetypes/AnimationJSONFile.js +++ b/src/loader/filetypes/AnimationJSONFile.js @@ -20,9 +20,9 @@ var JSONFile = require('./JSONFile.js'); * * @return {Phaser.Loader.FileTypes.JSONFile} A File instance to be added to the Loader. */ -var AnimationJSONFile = function (key, url, path, xhrSettings) +var AnimationJSONFile = function (loader, key, url, xhrSettings) { - var json = new JSONFile(key, url, path, xhrSettings); + var json = new JSONFile(loader, key, url, xhrSettings); // Override the File type json.type = 'animationJSON'; @@ -55,12 +55,12 @@ FileTypesManager.register('animation', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new AnimationJSONFile(key[i], url, this.path, xhrSettings)); + this.addFile(new AnimationJSONFile(this, key[i], url, xhrSettings)); } } else { - this.addFile(new AnimationJSONFile(key, url, this.path, xhrSettings)); + this.addFile(new AnimationJSONFile(this, key, url, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/AtlasJSONFile.js b/src/loader/filetypes/AtlasJSONFile.js index 669594d9e..ece83846a 100644 --- a/src/loader/filetypes/AtlasJSONFile.js +++ b/src/loader/filetypes/AtlasJSONFile.js @@ -23,10 +23,10 @@ var JSONFile = require('./JSONFile.js'); * * @return {object} An object containing two File objects to be added to the loader. */ -var AtlasJSONFile = function (key, textureURL, atlasURL, path, textureXhrSettings, atlasXhrSettings) +var AtlasJSONFile = function (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { - var image = new ImageFile(key, textureURL, path, textureXhrSettings); - var data = new JSONFile(key, atlasURL, path, atlasXhrSettings); + var image = new ImageFile(loader, key, textureURL, textureXhrSettings); + var data = new JSONFile(loader, key, atlasURL, atlasXhrSettings); // Link them together image.linkFile = data; @@ -60,20 +60,19 @@ var AtlasJSONFile = function (key, textureURL, atlasURL, path, textureXhrSetting */ FileTypesManager.register('atlas', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { - var files; // If param key is an object, use object based loading method if ((typeof key === 'object') && (key !== null)) { - files = new AtlasJSONFile(key.key, key.texture, key.data, this.path, textureXhrSettings, atlasXhrSettings); + files = new AtlasJSONFile(this, key.key, key.texture, key.data, textureXhrSettings, atlasXhrSettings); } // Else just use the parameters like normal else { // Returns an object with two properties: 'texture' and 'data' - files = new AtlasJSONFile(key, textureURL, atlasURL, this.path, textureXhrSettings, atlasXhrSettings); + files = new AtlasJSONFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); } this.addFile(files.texture); diff --git a/src/loader/filetypes/AudioFile.js b/src/loader/filetypes/AudioFile.js index 70c8ca47f..6562dd0d1 100644 --- a/src/loader/filetypes/AudioFile.js +++ b/src/loader/filetypes/AudioFile.js @@ -33,7 +33,7 @@ var AudioFile = new Class({ initialize: - function AudioFile (key, url, path, xhrSettings, audioContext) + function AudioFile (loader, key, url, xhrSettings, audioContext) { /** * [description] @@ -46,15 +46,16 @@ var AudioFile = new Class({ var fileConfig = { type: 'audio', + cache: loader.cacheManager.audio, extension: GetFastValue(url, 'type', ''), responseType: 'arraybuffer', key: key, url: GetFastValue(url, 'uri', url), - path: path, + path: loader.path, xhrSettings: xhrSettings }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, /** @@ -119,11 +120,11 @@ AudioFile.create = function (loader, key, urls, config, xhrSettings) if (deviceAudio.webAudio && !(audioConfig && audioConfig.disableWebAudio)) { - return new AudioFile(key, url, loader.path, xhrSettings, game.sound.context); + return new AudioFile(loader, key, url, xhrSettings, game.sound.context); } else { - return new HTML5AudioFile(key, url, loader.path, config); + return new HTML5AudioFile(loader, key, url, config); } }; diff --git a/src/loader/filetypes/BinaryFile.js b/src/loader/filetypes/BinaryFile.js index ea79e477e..8c634ebcf 100644 --- a/src/loader/filetypes/BinaryFile.js +++ b/src/loader/filetypes/BinaryFile.js @@ -31,21 +31,22 @@ var BinaryFile = new Class({ initialize: - function BinaryFile (key, url, path, xhrSettings) + function BinaryFile (loader, key, url, xhrSettings) { var fileKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', ''); var fileConfig = { type: 'binary', + cache: loader.cacheManager.binary, extension: GetFastValue(key, 'extension', 'bin'), responseType: 'arraybuffer', key: fileKey, url: GetFastValue(key, 'file', url), - path: path, + path: loader.path, xhrSettings: GetFastValue(key, 'xhr', xhrSettings) }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, onProcess: function (callback) @@ -85,12 +86,12 @@ FileTypesManager.register('binary', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new BinaryFile(key[i], url, this.path, xhrSettings)); + this.addFile(new BinaryFile(this, key[i], url, xhrSettings)); } } else { - this.addFile(new BinaryFile(key, url, this.path, xhrSettings)); + this.addFile(new BinaryFile(this, key, url, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/GLSLFile.js b/src/loader/filetypes/GLSLFile.js index eb1b50bcc..a257c6d53 100644 --- a/src/loader/filetypes/GLSLFile.js +++ b/src/loader/filetypes/GLSLFile.js @@ -31,21 +31,22 @@ var GLSLFile = new Class({ initialize: - function GLSLFile (key, url, path, xhrSettings) + function GLSLFile (loader, key, url, xhrSettings) { var fileKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', ''); var fileConfig = { type: 'glsl', + cache: loader.cacheManager.shader, extension: GetFastValue(key, 'extension', 'glsl'), responseType: 'text', key: fileKey, url: GetFastValue(key, 'file', url), - path: path, + path: loader.path, xhrSettings: GetFastValue(key, 'xhr', xhrSettings) }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, onProcess: function (callback) @@ -85,12 +86,12 @@ FileTypesManager.register('glsl', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new GLSLFile(key[i], url, this.path, xhrSettings)); + this.addFile(new GLSLFile(this, key[i], url, xhrSettings)); } } else { - this.addFile(new GLSLFile(key, url, this.path, xhrSettings)); + this.addFile(new GLSLFile(this, key, url, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/HTML5AudioFile.js b/src/loader/filetypes/HTML5AudioFile.js index 2bcee8e44..578e13d78 100644 --- a/src/loader/filetypes/HTML5AudioFile.js +++ b/src/loader/filetypes/HTML5AudioFile.js @@ -30,23 +30,24 @@ var HTML5AudioFile = new Class({ initialize: - function HTML5AudioFile (key, url, path, config) - { - this.locked = 'ontouchstart' in window; + function HTML5AudioFile (loader, key, url, config) + { + this.locked = 'ontouchstart' in window; - this.loaded = false; + this.loaded = false; - var fileConfig = { - type: 'audio', - extension: GetFastValue(url, 'type', ''), - key: key, - url: GetFastValue(url, 'uri', url), - path: path, - config: config - }; + var fileConfig = { + type: 'audio', + cache: loader.cacheManager.audio, + extension: GetFastValue(url, 'type', ''), + key: key, + url: GetFastValue(url, 'uri', url), + path: loader.path, + config: config + }; - File.call(this, fileConfig); - }, + File.call(this, loader, fileConfig); + }, onLoad: function () { diff --git a/src/loader/filetypes/HTMLFile.js b/src/loader/filetypes/HTMLFile.js index 00631de7b..e8feff4b4 100644 --- a/src/loader/filetypes/HTMLFile.js +++ b/src/loader/filetypes/HTMLFile.js @@ -33,7 +33,7 @@ var HTMLFile = new Class({ initialize: - function HTMLFile (key, url, width, height, path, xhrSettings) + function HTMLFile (loader, key, url, width, height, xhrSettings) { if (width === undefined) { width = 512; } if (height === undefined) { height = 512; } @@ -42,11 +42,12 @@ var HTMLFile = new Class({ var fileConfig = { type: 'html', + cache: loader.textureManager, extension: GetFastValue(key, 'extension', 'html'), responseType: 'text', key: fileKey, url: GetFastValue(key, 'file', url), - path: path, + path: loader.path, xhrSettings: GetFastValue(key, 'xhr', xhrSettings), config: { width: width, @@ -54,7 +55,7 @@ var HTMLFile = new Class({ } }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, onProcess: function (callback) @@ -113,6 +114,13 @@ var HTMLFile = new Class({ }; File.createObjectURL(this.data, blob, 'image/svg+xml'); + }, + + addToCache: function () + { + this.cache.addImage(this.key, this.data); + + this.loader.emit('filecomplete', this.key, this); } }); @@ -143,12 +151,12 @@ FileTypesManager.register('html', function (key, url, width, height, xhrSettings for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new HTMLFile(key[i], url, width, height, this.path, xhrSettings)); + this.addFile(new HTMLFile(this, key[i], url, width, height, xhrSettings)); } } else { - this.addFile(new HTMLFile(key, url, width, height, this.path, xhrSettings)); + this.addFile(new HTMLFile(this, key, url, width, height, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/ImageFile.js b/src/loader/filetypes/ImageFile.js index e41003efa..58a6ded17 100644 --- a/src/loader/filetypes/ImageFile.js +++ b/src/loader/filetypes/ImageFile.js @@ -48,22 +48,23 @@ var ImageFile = new Class({ // this.load.image({ key: 'bunny' }); // this.load.image({ key: 'bunny', extension: 'jpg' }); - function ImageFile (key, url, path, xhrSettings, config) + function ImageFile (loader, key, url, xhrSettings, config) { var fileKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', ''); var fileConfig = { type: 'image', + cache: loader.textureManager, extension: GetFastValue(key, 'extension', 'png'), responseType: 'blob', key: fileKey, url: GetFastValue(key, 'file', url), - path: path, + path: loader.path, xhrSettings: GetFastValue(key, 'xhr', xhrSettings), config: GetFastValue(key, 'config', config) }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, onProcess: function (callback) @@ -95,6 +96,13 @@ var ImageFile = new Class({ }; File.createObjectURL(this.data, this.xhrLoader.response, 'image/png'); + }, + + addToCache: function () + { + this.cache.addImage(this.key, this.data); + + this.loader.emit('filecomplete', this.key, this); } }); @@ -131,14 +139,14 @@ FileTypesManager.register('image', function (key, url, xhrSettings) if (Array.isArray(urls) && urls.length === 2) { - fileA = this.addFile(new ImageFile(key[i], urls[0], this.path, xhrSettings)); - fileB = this.addFile(new ImageFile(key[i], urls[1], this.path, xhrSettings)); + fileA = this.addFile(new ImageFile(this, key[i], urls[0], xhrSettings)); + fileB = this.addFile(new ImageFile(this, key[i], urls[1], xhrSettings)); fileA.setLinkFile(fileB, 'dataimage'); } else { - this.addFile(new ImageFile(key[i], url, this.path, xhrSettings)); + this.addFile(new ImageFile(this, key[i], url, xhrSettings)); } } } @@ -148,14 +156,14 @@ FileTypesManager.register('image', function (key, url, xhrSettings) if (Array.isArray(urls) && urls.length === 2) { - fileA = this.addFile(new ImageFile(key, urls[0], this.path, xhrSettings)); - fileB = this.addFile(new ImageFile(key, urls[1], this.path, xhrSettings)); + fileA = this.addFile(new ImageFile(this, key, urls[0], xhrSettings)); + fileB = this.addFile(new ImageFile(this, key, urls[1], xhrSettings)); fileA.setLinkFile(fileB, 'dataimage'); } else { - this.addFile(new ImageFile(key, url, this.path, xhrSettings)); + this.addFile(new ImageFile(this, key, url, xhrSettings)); } } diff --git a/src/loader/filetypes/JSONFile.js b/src/loader/filetypes/JSONFile.js index 9d64b326c..3612e869b 100644 --- a/src/loader/filetypes/JSONFile.js +++ b/src/loader/filetypes/JSONFile.js @@ -33,21 +33,22 @@ var JSONFile = new Class({ // url can either be a string, in which case it is treated like a proper url, or an object, in which case it is treated as a ready-made JS Object - function JSONFile (key, url, path, xhrSettings) + function JSONFile (loader, key, url, xhrSettings) { var fileKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', ''); var fileConfig = { type: 'json', + cache: loader.cacheManager.json, extension: GetFastValue(key, 'extension', 'json'), responseType: 'text', key: fileKey, url: GetFastValue(key, 'file', url), - path: path, + path: loader.path, xhrSettings: GetFastValue(key, 'xhr', xhrSettings) }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); if (typeof fileConfig.url === 'object') { diff --git a/src/loader/filetypes/SVGFile.js b/src/loader/filetypes/SVGFile.js index 92d7f5876..809ee2a33 100644 --- a/src/loader/filetypes/SVGFile.js +++ b/src/loader/filetypes/SVGFile.js @@ -31,21 +31,22 @@ var SVGFile = new Class({ initialize: - function SVGFile (key, url, path, xhrSettings) + function SVGFile (loader, key, url, xhrSettings) { var fileKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', ''); var fileConfig = { type: 'svg', + cache: loader.textureManager, extension: GetFastValue(key, 'extension', 'svg'), responseType: 'text', key: fileKey, url: GetFastValue(key, 'file', url), - path: path, + path: loader.path, xhrSettings: GetFastValue(key, 'xhr', xhrSettings) }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, onProcess: function (callback) @@ -106,6 +107,13 @@ var SVGFile = new Class({ }; File.createObjectURL(this.data, blob, 'image/svg+xml'); + }, + + addToCache: function () + { + this.cache.addImage(this.key, this.data); + + this.loader.emit('filecomplete', this.key, this); } }); @@ -134,12 +142,12 @@ FileTypesManager.register('svg', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new SVGFile(key[i], url, this.path, xhrSettings)); + this.addFile(new SVGFile(this, key[i], url, xhrSettings)); } } else { - this.addFile(new SVGFile(key, url, this.path, xhrSettings)); + this.addFile(new SVGFile(this, key, url, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/SpriteSheetFile.js b/src/loader/filetypes/SpriteSheetFile.js index 49650b132..c909e3d12 100644 --- a/src/loader/filetypes/SpriteSheetFile.js +++ b/src/loader/filetypes/SpriteSheetFile.js @@ -21,13 +21,20 @@ var ImageFile = require('./ImageFile.js'); * * @return {object} An object containing two File objects to be added to the loader. */ -var SpriteSheetFile = function (key, url, config, path, xhrSettings) +var SpriteSheetFile = function (loader, key, url, config, xhrSettings) { - var image = new ImageFile(key, url, path, xhrSettings, config); + var image = new ImageFile(loader, key, url, xhrSettings, config); // Override the File type image.type = 'spritesheet'; + image.addToCache = function () + { + this.cache.addSpriteSheet(this.key, this.data, this.config); + + this.loader.emit('filecomplete', this.key, this); + } + return image; }; @@ -56,12 +63,12 @@ FileTypesManager.register('spritesheet', function (key, url, config, xhrSettings for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new SpriteSheetFile(key[i], url, null, this.path, xhrSettings)); + this.addFile(new SpriteSheetFile(this, key[i], url, null, xhrSettings)); } } else { - this.addFile(new SpriteSheetFile(key, url, config, this.path, xhrSettings)); + this.addFile(new SpriteSheetFile(this, key, url, config, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/TextFile.js b/src/loader/filetypes/TextFile.js index c433d944f..dd06104e3 100644 --- a/src/loader/filetypes/TextFile.js +++ b/src/loader/filetypes/TextFile.js @@ -30,19 +30,20 @@ var TextFile = new Class({ initialize: - function TextFile (key, url, path, xhrSettings) + function TextFile (loader, key, url, xhrSettings) { var fileConfig = { type: 'text', + cache: loader.cacheManager.text, extension: 'txt', responseType: 'text', key: key, url: url, - path: path, + path: loader.path, xhrSettings: xhrSettings }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, onProcess: function (callback) @@ -82,12 +83,12 @@ FileTypesManager.register('text', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new TextFile(key[i], url, this.path, xhrSettings)); + this.addFile(new TextFile(this, key[i], url, xhrSettings)); } } else { - this.addFile(new TextFile(key, url, this.path, xhrSettings)); + this.addFile(new TextFile(this, key, url, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/TilemapCSVFile.js b/src/loader/filetypes/TilemapCSVFile.js index 1409c2a8d..9a252c98c 100644 --- a/src/loader/filetypes/TilemapCSVFile.js +++ b/src/loader/filetypes/TilemapCSVFile.js @@ -32,19 +32,20 @@ var TilemapCSVFile = new Class({ initialize: - function TilemapCSVFile (key, url, path, format, xhrSettings) + function TilemapCSVFile (loader, key, url, format, xhrSettings) { var fileConfig = { type: 'tilemapCSV', + cache: loader.cacheManager.tilemap, extension: '.csv', responseType: 'text', key: key, url: url, - path: path, + path: loader.path, xhrSettings: xhrSettings }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); this.tilemapFormat = format; }, @@ -58,6 +59,13 @@ var TilemapCSVFile = new Class({ this.onComplete(); callback(this); + }, + + addToCache: function () + { + this.cache.add(this.key, { format: this.tilemapFormat, data: this.data }); + + this.loader.emit('filecomplete', this.key, this); } }); @@ -86,12 +94,12 @@ FileTypesManager.register('tilemapCSV', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new TilemapCSVFile(key[i], url, this.path, TILEMAP_FORMATS.CSV, xhrSettings)); + this.addFile(new TilemapCSVFile(this, key[i], url, TILEMAP_FORMATS.CSV, xhrSettings)); } } else { - this.addFile(new TilemapCSVFile(key, url, this.path, TILEMAP_FORMATS.CSV, xhrSettings)); + this.addFile(new TilemapCSVFile(this, key, url, TILEMAP_FORMATS.CSV, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/TilemapJSONFile.js b/src/loader/filetypes/TilemapJSONFile.js index 11e55f9ce..b496b6e73 100644 --- a/src/loader/filetypes/TilemapJSONFile.js +++ b/src/loader/filetypes/TilemapJSONFile.js @@ -22,15 +22,24 @@ var TILEMAP_FORMATS = require('../../tilemaps/Formats'); * * @return {object} An object containing two File objects to be added to the loader. */ -var TilemapJSONFile = function (key, url, path, format, xhrSettings) +var TilemapJSONFile = function (loader, key, url, format, xhrSettings) { - var json = new JSONFile(key, url, path, xhrSettings); + var json = new JSONFile(loader, key, url, xhrSettings); // Override the File type json.type = 'tilemapJSON'; + json.cache = loader.cacheManager.tilemap; + json.tilemapFormat = format; + json.addToCache = function () + { + this.cache.add(this.key, { format: this.tilemapFormat, data: this.data }); + + this.loader.emit('filecomplete', this.key, this); + } + return json; }; @@ -58,12 +67,12 @@ FileTypesManager.register('tilemapTiledJSON', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(TilemapJSONFile(key[i], url, this.path, TILEMAP_FORMATS.TILED_JSON, xhrSettings)); + this.addFile(TilemapJSONFile(this, key[i], url, TILEMAP_FORMATS.TILED_JSON, xhrSettings)); } } else { - this.addFile(TilemapJSONFile(key, url, this.path, TILEMAP_FORMATS.TILED_JSON, xhrSettings)); + this.addFile(TilemapJSONFile(this, key, url, TILEMAP_FORMATS.TILED_JSON, xhrSettings)); } // For method chaining @@ -94,12 +103,12 @@ FileTypesManager.register('tilemapWeltmeister', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(TilemapJSONFile(key[i], url, this.path, TILEMAP_FORMATS.WELTMEISTER, xhrSettings)); + this.addFile(TilemapJSONFile(this, key[i], url, TILEMAP_FORMATS.WELTMEISTER, xhrSettings)); } } else { - this.addFile(TilemapJSONFile(key, url, this.path, TILEMAP_FORMATS.WELTMEISTER, xhrSettings)); + this.addFile(TilemapJSONFile(this, key, url, TILEMAP_FORMATS.WELTMEISTER, xhrSettings)); } // For method chaining diff --git a/src/loader/filetypes/UnityAtlasFile.js b/src/loader/filetypes/UnityAtlasFile.js index 8978f95b5..78d75af93 100644 --- a/src/loader/filetypes/UnityAtlasFile.js +++ b/src/loader/filetypes/UnityAtlasFile.js @@ -23,10 +23,10 @@ var TextFile = require('./TextFile.js'); * * @return {object} An object containing two File objects to be added to the loader. */ -var UnityAtlasFile = function (key, textureURL, atlasURL, path, textureXhrSettings, atlasXhrSettings) +var UnityAtlasFile = function (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { - var image = new ImageFile(key, textureURL, path, textureXhrSettings); - var data = new TextFile(key, atlasURL, path, atlasXhrSettings); + var image = new ImageFile(loader, key, textureURL, textureXhrSettings); + var data = new TextFile(loader, key, atlasURL, atlasXhrSettings); // Link them together image.linkFile = data; @@ -61,7 +61,7 @@ var UnityAtlasFile = function (key, textureURL, atlasURL, path, textureXhrSettin FileTypesManager.register('unityAtlas', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { // Returns an object with two properties: 'texture' and 'data' - var files = new UnityAtlasFile(key, textureURL, atlasURL, this.path, textureXhrSettings, atlasXhrSettings); + var files = new UnityAtlasFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); this.addFile(files.texture); this.addFile(files.data); diff --git a/src/loader/filetypes/XMLFile.js b/src/loader/filetypes/XMLFile.js index 84a325fb5..677b7430a 100644 --- a/src/loader/filetypes/XMLFile.js +++ b/src/loader/filetypes/XMLFile.js @@ -32,21 +32,22 @@ var XMLFile = new Class({ initialize: - function XMLFile (key, url, path, xhrSettings) + function XMLFile (loader, key, url, xhrSettings) { var fileKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', ''); var fileConfig = { type: 'xml', + cache: loader.cacheManager.xml, extension: GetFastValue(key, 'extension', 'xml'), responseType: 'text', key: fileKey, url: GetFastValue(key, 'file', url), - path: path, + path: loader.path, xhrSettings: GetFastValue(key, 'xhr', xhrSettings) }; - File.call(this, fileConfig); + File.call(this, loader, fileConfig); }, onProcess: function (callback) @@ -91,12 +92,12 @@ FileTypesManager.register('xml', function (key, url, xhrSettings) for (var i = 0; i < key.length; i++) { // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new XMLFile(key[i], url, this.path, xhrSettings)); + this.addFile(new XMLFile(this, key[i], url, xhrSettings)); } } else { - this.addFile(new XMLFile(key, url, this.path, xhrSettings)); + this.addFile(new XMLFile(this, key, url, xhrSettings)); } // For method chaining From a07cc81806d2bc8fdff89802498e11d939bc1b65 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:14:10 +0100 Subject: [PATCH 4/8] Fixed passing of data for freshly added Scenes --- src/scene/SceneManager.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/scene/SceneManager.js b/src/scene/SceneManager.js index d363e6dc9..e4ce81c77 100644 --- a/src/scene/SceneManager.js +++ b/src/scene/SceneManager.js @@ -319,6 +319,11 @@ var SceneManager = new Class({ data: data }); + if (!this.isBooted) + { + this._data[key] = { data: data }; + } + return null; } From 9843da10536442d6e794078ac2a1a638deaad0f8 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:16:09 +0100 Subject: [PATCH 5/8] Check file cache and pass processing of the file off to the file itself --- src/loader/LoaderPlugin.js | 69 ++++++++++++++------------------------ 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/src/loader/LoaderPlugin.js b/src/loader/LoaderPlugin.js index ce965e179..982e99229 100644 --- a/src/loader/LoaderPlugin.js +++ b/src/loader/LoaderPlugin.js @@ -84,6 +84,24 @@ var LoaderPlugin = new Class({ */ this.systems = scene.sys; + /** + * A reference to the global Cache Manager. + * + * @name Phaser.Loader.LoaderPlugin#cacheManager + * @type {Phaser.Cache.CacheManager} + * @since 3.7.0 + */ + this.cacheManager = scene.sys.cache; + + /** + * A reference to the global Texture Manager. + * + * @name Phaser.Loader.LoaderPlugin#textureManager + * @type {Phaser.Textures.TextureManager} + * @since 3.7.0 + */ + this.textureManager = scene.sys.textures; + /** * [description] * @@ -350,9 +368,13 @@ var LoaderPlugin = new Class({ return -1; } - file.path = this.path; + // Does the file already exist in the cache or texture manager? + if (!file.hasCacheConflict()) + { + file.path = this.path; - this.list.set(file); + this.list.set(file); + } return file; }, @@ -721,12 +743,6 @@ var LoaderPlugin = new Class({ animJSON.push(file); break; - case 'image': - case 'svg': - case 'html': - textures.addImage(file.key, file.data); - break; - case 'atlasjson': fileA = file.fileA; @@ -789,34 +805,6 @@ var LoaderPlugin = new Class({ } break; - case 'spritesheet': - textures.addSpriteSheet(file.key, file.data, file.config); - break; - - case 'json': - cache.json.add(file.key, file.data); - break; - - case 'xml': - cache.xml.add(file.key, file.data); - break; - - case 'text': - cache.text.add(file.key, file.data); - break; - - case 'obj': - cache.obj.add(file.key, file.data); - break; - - case 'binary': - cache.binary.add(file.key, file.data); - break; - - case 'audio': - cache.audio.add(file.key, file.data); - break; - case 'audioSprite': var files = [ file.fileA, file.fileB ]; @@ -828,14 +816,9 @@ var LoaderPlugin = new Class({ break; - case 'glsl': - cache.shader.add(file.key, file.data); - break; + default: + file.addToCache(); - case 'tilemapCSV': - case 'tilemapJSON': - cache.tilemap.add(file.key, { format: file.tilemapFormat, data: file.data }); - break; } }); From 074fcbcf2b6b62c5e641c66821506835588efa8b Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:16:39 +0100 Subject: [PATCH 6/8] null references --- src/loader/LoaderPlugin.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/loader/LoaderPlugin.js b/src/loader/LoaderPlugin.js index 982e99229..cc4e5928f 100644 --- a/src/loader/LoaderPlugin.js +++ b/src/loader/LoaderPlugin.js @@ -1010,6 +1010,8 @@ var LoaderPlugin = new Class({ this.scene = null; this.systems = null; + this.textureManager = null; + this.cacheManager = null; } }); From d258fc30e91b42a80b9c8a731fe76e40e77b5c1b Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:16:46 +0100 Subject: [PATCH 7/8] Change log udpated --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 042137c07..0d4928d4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,10 +24,19 @@ * TextureSource will now remove its respective WebGLTexture from the renderer when destroyed. * TextureSource will now automatically create a glTexture from its canvas if using one. * WebGLRenderer will now remove a GL texture from its local `nativeTextures` array when you call the `deleteTexture` method. +* The BaseCache has a new method `exists` that will return a boolean if an entry for the given key exists in the cache or not. +* Loader.File has a new argument in its constructor which is an instance of the LoaderPlugin. It stores this in the `loader` property. It also has a new property `cache` which is a reference to the cache that the file type will be stored in. +* Loader.File has a new method `hasCacheConflict` which checks if a key matching the one used by this file exists in the target Cache or not. +* Loader.File has a new method `addToCache` which will add the file to its target cache and then emit a `filecomplete` event, passing its key and a reference to itself to the listener. +* LoaderPlugin has a new property `cacheManager` which is a reference to the global game cache and is used by the File Types. +* LoaderPlugin has a new property `textureManager` which is a reference to the global Texture Manager and is used by the File Types. +* LoaderPlugin will now check to see if loading a file would cache a cache conflict or not, and prevent it if it will. +* LoaderPlugin now passes off processing of the final file data to the file itself, which will now self-add itself to its target cache. ### Bug Fixes * DataManagerPlugin would throw an error on Game.destroy if you had any Scenes in the Scene Manager had not been run. Fix #3596 (thanks @kuoruan) +* If you created a Game with no Scenes defined, and then added one via `Game.scene.add` and passed in a data object, the data would be ignored when starting the Scene. ### Examples, Documentation and TypeScript From 0f0f099326b1699d7f5e7495568a39073f666ceb Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Wed, 25 Apr 2018 17:18:16 +0100 Subject: [PATCH 8/8] eslint fixes --- src/loader/filetypes/SpriteSheetFile.js | 2 +- src/loader/filetypes/TilemapJSONFile.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/loader/filetypes/SpriteSheetFile.js b/src/loader/filetypes/SpriteSheetFile.js index c909e3d12..a46656f6b 100644 --- a/src/loader/filetypes/SpriteSheetFile.js +++ b/src/loader/filetypes/SpriteSheetFile.js @@ -33,7 +33,7 @@ var SpriteSheetFile = function (loader, key, url, config, xhrSettings) this.cache.addSpriteSheet(this.key, this.data, this.config); this.loader.emit('filecomplete', this.key, this); - } + }; return image; }; diff --git a/src/loader/filetypes/TilemapJSONFile.js b/src/loader/filetypes/TilemapJSONFile.js index b496b6e73..bf9c9c5a1 100644 --- a/src/loader/filetypes/TilemapJSONFile.js +++ b/src/loader/filetypes/TilemapJSONFile.js @@ -38,7 +38,7 @@ var TilemapJSONFile = function (loader, key, url, format, xhrSettings) this.cache.add(this.key, { format: this.tilemapFormat, data: this.data }); this.loader.emit('filecomplete', this.key, this); - } + }; return json; };