Working through new plugin structure

This commit is contained in:
Richard Davey 2018-05-11 01:50:37 +01:00
parent ade37dd35e
commit 0a46c13f4c
4 changed files with 192 additions and 116 deletions

View file

@ -13,6 +13,7 @@
* Optimized TextureTintPipeline.drawBlitter so it skips bobs that have alpha of zero and only calls `setTexture2D` if the bob sourceIndex has changed, previously it called it for every single bob.
* Game.context used to be undefined if running in WebGL. It is now set to be the `WebGLRenderingContext` during WebGLRenderer.init. If you provided your own custom context, it is set to this instead.
* Game.onStepCallback has been removed.
### Bug Fixes

View file

@ -447,39 +447,25 @@ var Config = new Class({
// Plugins
/**
* @const {any} Phaser.Boot.Config#defaultPlugins - The plugins installed into every Scene (in addition to CoreScene and Global).
*/
this.defaultPlugins = Plugins.DefaultScene;
/**
* @const {any} Phaser.Boot.Config#installPlugins - [description]
*/
this.installPlugins = { global: [], scene: [], files: [] };
var plugins = GetValue(config, 'plugins', null);
/*
* Allows `plugins` property to either be an array, in which case it just replaces
* the default plugins like previously.
* the default plugins like previously, or a config object.
*
* plugins: {
* install: [
* ModPlayerPlugin,
* WireFramePlugin
* ],
* filetypes: [
* MODFile
* OBJFile,
* ],
* default: [], OR
* defaultMerge: {
* 'ModPlayer': 'mod'
* 'ModPlayer'
* }
* }
*
* If an object, it checks for an 'install' property,
*/
var plugins = GetValue(config, 'plugins', null);
var defaultPlugins = Plugins.DefaultScene;
if (plugins)
{
// Old 3.7 array format?
@ -489,19 +475,29 @@ var Config = new Class({
}
else if (IsPlainObject(plugins))
{
this.installPlugins.global = GetFastValue(plugins, 'install', []);
// this.installPlugins.global = GetFastValue(plugins, 'install', []);
if (Array.isArray(plugins.default))
{
this.defaultPlugins = plugins.default;
defaultPlugins = plugins.default;
}
else if (Array.isArray(plugins.defaultMerge))
{
this.defaultPlugins = this.defaultPlugins.concat(plugins.defaultMerge);
defaultPlugins = defaultPlugins.concat(plugins.defaultMerge);
}
}
}
/**
* @const {any} Phaser.Boot.Config#defaultPlugins - The plugins installed into every Scene (in addition to CoreScene and Global).
*/
this.defaultPlugins = defaultPlugins;
/**
* @const {any} Phaser.Boot.Config#installPlugins - [description]
*/
this.installPlugins = GetValue(config, 'plugins.install', []);
// Default / Missing Images
var pngPrefix = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg';

View file

@ -6,6 +6,13 @@
var Class = require('../utils/Class');
// A Scene Level Plugin is installed into every Scene and belongs to that Scene.
// It can listen for Scene events and respond to them.
// It can map itself to a Scene property, or into the Scene Systems, or both.
//
// A Global Plugin is installed just once into the Game owned Plugin Manager.
// It can listen for Game events and respond to them.
/**
* @classdesc
* [description]
@ -21,19 +28,20 @@ var Plugin = new Class({
initialize:
function Plugin (key, game)
function Plugin (key, pluginManager)
{
/**
* All plugins _must_ set a key property. It's a unique string which is used by the
* PluginManager to register this plugin, return it and invoke it.
* It must be unique within the scope of the game instance.
*
* The unique (within this game instance) name of this plugin within the Plugin Manager.
* This is set by the developer in their game config, although you should provide a default value.
*
* @name Phaser.Plugins.Plugin#key
* @type {string}
* @since 3.8.0
*/
this.key = key;
this.pluginManager = pluginManager;
/**
* [description]
*
@ -41,94 +49,127 @@ var Plugin = new Class({
* @type {Phaser.Game}
* @since 3.8.0
*/
this.game = game;
this.game = pluginManager.game;
this.active = true;
// this.sceneConfig =
// The Scene that owns this plugin, if any
this.scene;
// Scene Systems (if any)
this.systems;
if (game.isBooted)
{
this.gameBoot();
}
else
{
game.events.once('boot', this.gameBoot, this);
}
},
/**
* [description]
* Called when the Game boots. Or, if already booted, called immediately by the PluginManager.
*
* @method Phaser.Plugins.Plugin#gameBoot
* @method Phaser.Plugins.Plugin#init
* @since 3.8.0
*/
gameBoot: function ()
init: function ()
{
console.log('gameBoot');
this.game.events.on('pause', this.gamePause, this);
this.game.events.on('resume', this.gameResume, this);
this.game.events.on('resize', this.gameResize, this);
this.game.events.once('destroy', this.gameDestroy, this);
console.log('Plugin.init');
},
gamePause: function ()
/**
* Called when the Game pauses.
*
* @method Phaser.Plugins.Plugin#pauseGame
* @since 3.8.0
*/
pauseGame: function ()
{
// Game instance has paused
},
gameResume: function ()
/**
* Called when the Game resumes from a paused state.
*
* @method Phaser.Plugins.Plugin#resumeGame
* @since 3.8.0
*/
resumeGame: function ()
{
// Game instance has resumed from a paused state
},
gameResize: function (newWidth, newHeight)
/**
* Called when the Game resizes.
*
* @method Phaser.Plugins.Plugin#resize
* @since 3.8.0
*/
resize: function (newWidth, newHeight)
{
// Game instance has been resized
},
step: function (time, delta)
{
// Called automatically by the PluginManager, invoked from the Game.step
// Do any continuous processing or updating that you need in here
// Not called if Plugin.active = false
},
/**
* Game instance has been destroyed.
* Called when the Game steps.
* Called automatically by the PluginManager, invoked from the Game.step.
* Do any continuous processing or updating that you need in here.
* Not called if Plugin.active = false
*
* @method Phaser.Plugins.Plugin#gameDestroy
* @method Phaser.Plugins.Plugin#step
* @since 3.8.0
*/
gameDestroy: function ()
step: function (time, delta)
{
this.game = null;
this.scene = null;
this.systems = null;
},
// Scene Level ...
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
* It's only called if this is a Scene Plugin.
*
* @method Phaser.Time.Clock#boot
* @private
* @since 3.5.1
* @method Phaser.Plugins.Plugin#sceneBoot
* @since 3.8.0
*/
boot: function ()
sceneBoot: function (scene)
{
if (this.systems)
{
this.systems.events.once('destroy', this.destroy, this);
}
this.scene = scene;
this.systems = scene.sys;
var eventEmitter = scene.sys.events;
eventEmitter.once('destroy', this.sceneDestroy, this);
// Listening to the following events is entirely optional, although we would recommend cleanly shutting down and destroying at least.
// If you don't need any of these events then remove the listeners and the relevant methods too.
eventEmitter.on('start', this.start, this);
eventEmitter.on('preupdate', this.preUpdate, this);
eventEmitter.on('update', this.update, this);
eventEmitter.on('postupdate', this.postUpdate, this);
eventEmitter.on('pause', this.pause, this);
eventEmitter.on('resume', this.resume, this);
eventEmitter.on('sleep', this.sleep, this);
eventEmitter.on('wake', this.wake, this);
eventEmitter.on('shutdown', this.shutdown, this);
eventEmitter.on('destroy', this.destroy, this);
},
/**
* Game instance has been destroyed.
* You must release everything in here, all references, all objects, free it all up.
*
* @method Phaser.Plugins.Plugin#destroy
* @since 3.8.0
*/
destroy: function ()
{
this.game = null;
this.scene = null;
this.systems = null;
},

View file

@ -5,9 +5,15 @@
*/
var Class = require('../utils/Class');
var EventEmitter = require('eventemitter3');
var IsPlainObject = require('../utils/object/IsPlainObject');
var GetFastValue = require('../utils/object/GetFastValue');
// Contains the plugins that Phaser uses globally and locally.
// These are the source objects, not instantiated.
var corePlugins = {};
// Contains the plugins that the dev has loaded into their game
var plugins = {};
/**
@ -25,10 +31,14 @@ var plugins = {};
*/
var PluginManager = new Class({
Extends: EventEmitter,
initialize:
function PluginManager (game)
{
EventEmitter.call(this);
/**
* [description]
*
@ -38,10 +48,13 @@ var PluginManager = new Class({
*/
this.game = game;
// Plugins currently running and managed by this Plugin Manager
// These are Game instance specific
// Plugins currently running and managed by this Plugin Manager.
// These are Game instance specific.
this.activePlugins = [];
// Plugins that should be installed into Scenes
this.scenePlugins = [];
if (game.isBooted)
{
this.boot();
@ -63,17 +76,15 @@ var PluginManager = new Class({
this.game.events.once('destroy', this.destroy, this);
// Any plugins to install?
/*
var list = this.game.config.installPlugins;
if (list)
{
for (var key in list)
{
this.add(key, list[key]);
// this.register(key, list[key]);
}
}
*/
},
/**
@ -87,7 +98,7 @@ var PluginManager = new Class({
*/
installGlobal: function (sys, globalPlugins)
{
var game = sys.game;
var game = this.game;
var scene = sys.scene;
var map = sys.settings.map;
@ -130,12 +141,12 @@ var PluginManager = new Class({
{
var pluginKey = scenePlugins[i];
if (!plugins[pluginKey])
if (!corePlugins[pluginKey])
{
continue;
}
var source = plugins[pluginKey];
var source = corePlugins[pluginKey];
var plugin = new source.plugin(scene);
@ -156,38 +167,80 @@ var PluginManager = new Class({
},
/**
* Register a plugin with the PluginManager. This is the same as calling the
* static function, but is available via the game pluginManager instance.
* Registers a plugin with the PluginManager.
*
* Key is a reference used to get the plugin from the plugins object (i.e. InputPlugin)
* Plugin is the object to instantiate to create the plugin
* Mapping is what the plugin is injected into the Scene.Systems as (i.e. input)
* Key is a reference used to get the plugin from the plugins object (i.e. MyPlugin)
* Plugin is the function to instantiate to create a plugin instance.
*
* @method Phaser.Plugins.PluginManager#register
* @since 3.8.0
*
* @param {string} key - [description]
* @param {object} plugin - [description]
* @param {string} mapping - [description]
* @param {function} plugin - [description]
*/
register: function (key, plugin, mapping)
register: function (key, plugin, start, isScenePlugin)
{
plugins[key] = { plugin: plugin, mapping: mapping };
if (start === undefined) { start = false; }
if (isScenePlugin === undefined) { isScenePlugin = false; }
if (typeof plugin !== 'function')
{
console.warn('Invalid Plugin: ' + key);
return;
}
if (plugins.hasOwnProperty(key))
{
console.warn('Plugin key in use: ' + key);
return;
}
// Add it to the plugin store
plugins[key] = plugin;
if (start)
{
this.start(key);
}
if (isScenePlugin)
{
}
return this;
},
add: function (plugin)
start: function (key)
{
var instance = new plugin(this.game);
var instance;
var plugin = this.get(key);
var key = instance.key;
if (plugin)
{
instance = new plugin(this);
plugins[key] = { plugin: plugin };
this.activePlugins.push(instance);
this.activePlugins.push(instance);
}
return instance;
},
setScenePlugin: function (scene)
{
},
addGameObject: function ()
{
},
addFileType: function ()
{
},
/**
* [description]
*
@ -200,22 +253,7 @@ var PluginManager = new Class({
*/
get: function (key)
{
return (plugins[key]) ? plugins[key].plugin : null;
},
update: function (time, delta)
{
var activePlugins = this.activePlugins;
for (var i = 0; i < activePlugins.length; i++)
{
var plugin = activePlugins[i];
if (plugin.active)
{
plugin.step(time, delta);
}
}
return (plugins.hasOwnProperty(key)) ? plugins[key] : null;
},
/**
@ -245,7 +283,7 @@ var PluginManager = new Class({
});
/**
* Static method called directly by the Plugins
* Static method called directly by the Core internal Plugins.
* Key is a reference used to get the plugin from the plugins object (i.e. InputPlugin)
* Plugin is the object to instantiate to create the plugin
* Mapping is what the plugin is injected into the Scene.Systems as (i.e. input)
@ -259,7 +297,7 @@ var PluginManager = new Class({
*/
PluginManager.register = function (key, plugin, mapping)
{
plugins[key] = { plugin: plugin, mapping: mapping };
corePlugins[key] = { plugin: plugin, mapping: mapping };
};
module.exports = PluginManager;