<commit_before>// Copyright 2015-2018, University of Colorado Boulder

/**
 * Object pooling trait, for cases where creating new objects is expensive, and we'd rather mark some objects as able
 * to be reused (i.e. 'in the pool'). This provides a pool of objects for each type it is invoked on. It allows for
 * getting "new" objects that can either be constructed OR pulled in from a pool, and requires that the objects are
 * essentially able to "re-run" the constructor. Then when putting the object back in the pool, references should be
 * released, so memory isn't leaked.
 *
 * @author <NAME> <<EMAIL>>
 */

define( function( require ) {
  'use strict';

  var extend = require( 'PHET_CORE/extend' );
  var phetCore = require( 'PHET_CORE/phetCore' );

  var ExperimentalPoolable = {
    /**
     * Changes the given type (and its prototype) to support object pooling.
     * @public
     *
     * @param {function} type - The constructor for the type
     * @param {Object} [options]
     */
    mixInto: function( type, options ) {
      options = _.extend( {
        // {Array.<*>} - If an object needs to be created without a direct call (say, to fill the pool initially), these
        // are the arguments that will be passed into the constructor
        defaultArguments: [],

        // {function} - The function to call on the objects to reinitialize them (that is either the constructor, or
        // acts like the constructor).
        initialize: type,

        // {number} - A limit for the pool size (so we don't leak memory by growing the pool faster than we take things
        // from it).
        maxSize: 100,

        // {number} - The initial size of the pool. To fill it, objects will be created with the default arguments.
        initialSize: 0,

        // {boolean} - If true, when constructing the default arguments will always be used (and then initialized with
        // the initializer) instead of just providing the arguments straight to the constructor.
        useDefaultConstruction: false
      }, options );

      assert && assert( Array.isArray( options.defaultArguments ) );
      assert && assert( typeof options.maxSize === 'number' && options.maxSize >= 0 );
      assert && assert( typeof options.initialSize === 'number' && options.initialSize >= 0 );

      // {Array.<type>} - The actual array we store things in. Always push/pop.
      var pool = [];

      // {function} - There is a madness to this craziness. We'd want to use the method noted at
      // https://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible, but the type is
      // not provided in the arguments array below. By calling bind on itself, we're able to get a version of bind that
      // inserts the constructor as the first argument of the .apply called later so we don't create garbage by having
      // to pack `arguments` into an array AND THEN concatenate it with a new first element (the type itself).
      var partialConstructor = Function.prototype.bind.bind( type, type );

      // {function} - Basically our type constructor, but with the default arguments included already.
      var DefaultConstructor = partialConstructor.apply( null, options.defaultArguments );

      var initialize = options.initialize;<commit_msg>More assertions for pooling, see https://github.com/phetsims/phet-core/issues/35<commit_after>// Copyright 2015-2018, University of Colorado Boulder

/**
 * Object pooling trait, for cases where creating new objects is expensive, and we'd rather mark some objects as able
 * to be reused (i.e. 'in the pool'). This provides a pool of objects for each type it is invoked on. It allows for
 * getting "new" objects that can either be constructed OR pulled in from a pool, and requires that the objects are
 * essentially able to "re-run" the constructor. Then when putting the object back in the pool, references should be
 * released, so memory isn't leaked.
 *
 * @author <NAME> <<EMAIL>>
 */

define( function( require ) {
  'use strict';

  var extend = require( 'PHET_CORE/extend' );
  var phetCore = require( 'PHET_CORE/phetCore' );

  var ExperimentalPoolable = {
    /**
     * Changes the given type (and its prototype) to support object pooling.
     * @public
     *
     * @param {function} type - The constructor for the type
     * @param {Object} [options]
     */
    mixInto: function( type, options ) {
      options = _.extend( {
        // {Array.<*>} - If an object needs to be created without a direct call (say, to fill the pool initially), these
        // are the arguments that will be passed into the constructor
        defaultArguments: [],

        // {function} - The function to call on the objects to reinitialize them (that is either the constructor, or
        // acts like the constructor).
        initialize: type,

        // {number} - A limit for the pool size (so we don't leak memory by growing the pool faster than we take things
        // from it).
        maxSize: 100,

        // {number} - The initial size of the pool. To fill it, objects will be created with the default arguments.
        initialSize: 0,

        // {boolean} - If true, when constructing the default arguments will always be used (and then initialized with
        // the initializer) instead of just providing the arguments straight to the constructor.
        useDefaultConstruction: false
      }, options );

      assert && assert( Array.isArray( options.defaultArguments ) );
      assert && assert( typeof options.maxSize === 'number' && options.maxSize >= 0 );
      assert && assert( typeof options.initialSize === 'number' && options.initialSize >= 0 );
      assert && assert( typeof options.initialize === 'function' );
      assert && assert( typeof options.useDefaultConstruction === 'boolean' );

      // {Array.<type>} - The actual array we store things in. Always push/pop.
      var pool = [];

      // {function} - There is a madness to this craziness. We'd want to use the method noted at
      // https://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible, but the type is
      // not provided in the arguments array below. By calling bind on itself, we're able to get a version of bind that
      // inserts the constructor as the first argument of the .apply called later so we don't create garbage by having
      // to pack `arguments` into an array AND THEN concatenate it with a new first element (the type itself).
      var partialConstructor = Function.prototype.bind.bind( type, type );

      // {function} - Basically our type constructor, but with the default arguments included already.
      var DefaultConstructor = partialConstructor.apply( null, options.defaultArguments );

      var initialize = options.initialize;
{'fraction_non_alphanumeric': 0.09165687426556991, 'fraction_numerical': 0.006462984723854289, 'mean_word_length': 2.895308924485126, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2457283', 'n_tokens_mistral': 1773, 'n_tokens_neox': 1674, 'n_words': 818}