text: /**
   * @author       Richard Davey <rich@photonstorm.com>
   * @copyright    2018 Photon Storm Ltd.
   * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
   */
  
  var Class = require('../utils/Class');
  var PluginCache = require('../plugins/PluginCache');
  
  /**
   * @classdesc
   * The Game Object Factory is a Scene plugin that allows you to quickly create many common
   * types of Game Objects and have them automatically registered with the Scene.
   *
   * Game Objects directly register themselves with the Factory and inject their own creation
   * methods into the class.
   *
   * @class GameObjectFactory
   * @memberOf Phaser.GameObjects
   * @constructor
   * @since 3.0.0
   *
   * @param {Phaser.Scene} scene - The Scene to which this Game Object Factory belongs.
   */
  var GameObjectFactory = new Class({
  
      initialize:
  
      function GameObjectFactory (scene)
      {
          /**
           * The Scene to which this Game Object Factory belongs.
           *
           * @name Phaser.GameObjects.GameObjectFactory#scene
           * @type {Phaser.Scene}
           * @protected
           * @since 3.0.0
           */
          this.scene = scene;
  
          /**
           * A reference to the Scene.Systems.
           *
           * @name Phaser.GameObjects.GameObjectFactory#systems
           * @type {Phaser.Scenes.Systems}
           * @protected
           * @since 3.0.0
           */
          this.systems = scene.sys;
  
          /**
           * A reference to the Scene Display List.
           *
           * @name Phaser.GameObjects.GameObjectFactory#displayList
           * @type {Phaser.GameObjects.DisplayList}
           * @protected
           * @since 3.0.0
           */
          this.displayList;
  
          /**
           * A reference to the Scene Update List.
           *
           * @name Phaser.GameObjects.GameObjectFactory#updateList;
           * @type {Phaser.GameObjects.UpdateList}
           * @protected
           * @since 3.0.0
           */
          this.updateList;
  
          scene.sys.events.once('boot', this.boot, this);
          scene.sys.events.on('start', this.start, this);
      },
  
      /**
       * This method is called automatically, only once, when the Scene is first created.
       * Do not invoke it directly.
       *
       * @method Phaser.GameObjects.GameObjectFactory#boot
       * @private
       * @since 3.5.1
       */
      boot: function ()
      {
          this.displayList = this.systems.displayList;
          this.updateList = this.systems.updateList;
  
          this.systems.events.once('destroy', this.destroy, this);
      },
  
      /**
       * This method is called automatically by the Scene when it is starting up.
       * It is responsible for creating local systems, properties and listening for Scene events.
       * Do not invoke it directly.
       *
       * @method Phaser.GameObjects.GameObjectFactory#start
       * @private
       * @since 3.5.0
       */
      start: function ()
      {
          this.systems.events.once('shutdown', this.shutdown, this);
      },
  
      /**
       * Adds an existing Game Object to this Scene.
       * 
       * If the Game Object renders, it will be added to the Display List.
       * If it has a `preUpdate` method, it will be added to the Update List.
       *
       * @method Phaser.GameObjects.GameObjectFactory#existing
       * @since 3.0.0
       *
       * @param {Phaser.GameObjects.GameObject} child - The child to be added to this Scene.
       *
       * @return {Phaser.GameObjects.GameObject} The Game Object that was added.
       */
      existing: function (child)
      {
          if (child.renderCanvas || child.renderWebGL)
          {
              this.displayList.add(child);
          }
  
          if (child.preUpdate)
          {
              this.updateList.add(child);
          }
  
          return child;
      },
  
      /**
       * The Scene that owns this plugin is shutting down.
       * We need to kill and reset all internal properties as well as stop listening to Scene events.
       *
       * @method Phaser.GameObjects.GameObjectFactory#shutdown
       * @private
       * @since 3.0.0
       */
      shutdown: function ()
      {
          this.systems.events.off('shutdown', this.shutdown, this);
      },
  
      /**
       * The Scene that owns this plugin is being destroyed.
       * We need to shutdown and then kill off all external references.
       *
       * @method Phaser.GameObjects.GameObjectFactory#destroy
       * @private
       * @since 3.0.0
       */
      destroy: function ()
      {
          this.shutdown();
  
          this.scene.sys.events.off('start', this.start, this);
  
          this.scene = null;
          this.systems = null;
  
          this.displayList = null;
          this.updateList = null;
      }
  
  });
  
  //  Static method called directly by the Game Object factory functions
  
  GameObjectFactory.register = function (factoryType, factoryFunction)
  {
      if (!GameObjectFactory.prototype.hasOwnProperty(factoryType))
      {
          GameObjectFactory.prototype[factoryType] = factoryFunction;
      }
  };
  
  PluginCache.register('GameObjectFactory', GameObjectFactory, 'add');
  
  module.exports = GameObjectFactory;
  