/* jshint newcap: false */ /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2016 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * The Plugin Manager is responsible for the loading, running and unloading of Phaser Plugins. * * @class Phaser.PluginManager * @constructor * @param {Phaser.Game} game - A reference to the currently running game. */ Phaser.PluginManager = function(game) { /** * @property {Phaser.Game} game - A reference to the currently running game. */ this.game = game; /** * @property {Phaser.Plugin[]} plugins - An array of all the plugins being managed by this PluginManager. */ this.plugins = []; /** * @property {number} _len - Internal cache var. * @private */ this._len = 0; /** * @property {number} _i - Internal cache var. * @private */ this._i = 0; }; Phaser.PluginManager.prototype = { /** * Add a new Plugin into the PluginManager. * The Plugin must have 2 properties: game and parent. Plugin.game is set to the game reference the PluginManager uses, and parent is set to the PluginManager. * * @method Phaser.PluginManager#add * @param {object|Phaser.Plugin} plugin - The Plugin to add into the PluginManager. This can be a function or an existing object. * @param {...*} parameter - Additional arguments that will be passed to the Plugin.init method. * @return {Phaser.Plugin} The Plugin that was added to the manager. */ add: function (plugin) { var args = Array.prototype.slice.call(arguments, 1); var result = false; // Prototype? if (typeof plugin === 'function') { plugin = new plugin(this.game, this); } else { plugin.game = this.game; plugin.parent = this; } // Check for methods now to avoid having to do this every loop if (typeof plugin['preUpdate'] === 'function') { plugin.hasPreUpdate = true; result = true; } if (typeof plugin['update'] === 'function') { plugin.hasUpdate = true; result = true; } if (typeof plugin['postUpdate'] === 'function') { plugin.hasPostUpdate = true; result = true; } if (typeof plugin['render'] === 'function') { plugin.hasRender = true; result = true; } if (typeof plugin['postRender'] === 'function') { plugin.hasPostRender = true; result = true; } // The plugin must have at least one of the above functions to be added to the PluginManager. if (result) { if (plugin.hasPreUpdate || plugin.hasUpdate || plugin.hasPostUpdate) { plugin.active = true; } if (plugin.hasRender || plugin.hasPostRender) { plugin.visible = true; } this._len = this.plugins.push(plugin); // Allows plugins to run potentially destructive code outside of the constructor, and only if being added to the PluginManager if (typeof plugin['init'] === 'function') { plugin.init.apply(plugin, args); } return plugin; } else { return null; } }, /** * Remove a Plugin from the PluginManager. It calls Plugin.destroy on the plugin before removing it from the manager. * * @method Phaser.PluginManager#remove * @param {Phaser.Plugin} plugin - The plugin to be removed. * @param {boolean} [destroy=true] - Call destroy on the plugin that is removed? */ remove: function (plugin, destroy) { if (destroy === undefined) { destroy = true; } this._i = this._len; while (this._i--) { if (this.plugins[this._i] === plugin) { if (destroy) { plugin.destroy(); } this.plugins.splice(this._i, 1); this._len--; return; } } }, /** * Remove all Plugins from the PluginManager. It calls Plugin.destroy on every plugin before removing it from the manager. * * @method Phaser.PluginManager#removeAll */ removeAll: function() { this._i = this._len; while (this._i--) { this.plugins[this._i].destroy(); } this.plugins.length = 0; this._len = 0; }, /** * Pre-update is called at the very start of the update cycle, before any other subsystems have been updated (including Physics). * It only calls plugins who have active=true. * * @method Phaser.PluginManager#preUpdate */ preUpdate: function () { this._i = this._len; while (this._i--) { if (this.plugins[this._i].active && this.plugins[this._i].hasPreUpdate) { this.plugins[this._i].preUpdate(); } } }, /** * Update is called after all the core subsystems (Input, Tweens, Sound, etc) and the State have updated, but before the render. * It only calls plugins who have active=true. * * @method Phaser.PluginManager#update */ update: function () { this._i = this._len; while (this._i--) { if (this.plugins[this._i].active && this.plugins[this._i].hasUpdate) { this.plugins[this._i].update(); } } }, /** * PostUpdate is the last thing to be called before the world render. * In particular, it is called after the world postUpdate, which means the camera has been adjusted. * It only calls plugins who have active=true. * * @method Phaser.PluginManager#postUpdate */ postUpdate: function () { this._i = this._len; while (this._i--) { if (this.plugins[this._i].active && this.plugins[this._i].hasPostUpdate) { this.plugins[this._i].postUpdate(); } } }, /** * Render is called right after the Game Renderer completes, but before the State.render. * It only calls plugins who have visible=true. * * @method Phaser.PluginManager#render */ render: function () { this._i = this._len; while (this._i--) { if (this.plugins[this._i].visible && this.plugins[this._i].hasRender) { this.plugins[this._i].render(); } } }, /** * Post-render is called after the Game Renderer and State.render have run. * It only calls plugins who have visible=true. * * @method Phaser.PluginManager#postRender */ postRender: function () { this._i = this._len; while (this._i--) { if (this.plugins[this._i].visible && this.plugins[this._i].hasPostRender) { this.plugins[this._i].postRender(); } } }, /** * Clear down this PluginManager, calls destroy on every plugin and nulls out references. * * @method Phaser.PluginManager#destroy */ destroy: function () { this.removeAll(); this.game = null; } }; Phaser.PluginManager.prototype.constructor = Phaser.PluginManager;