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

/**
 * Lightweight event & listener abstraction for a single event type.
 *
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 */

import axon from './axon.js';

// constants
const shuffleListeners = _.hasIn( window, 'phet.chipper.queryParameters' ) && phet.chipper.queryParameters.shuffleListeners;

class TinyEmitter {
  constructor() {

    // @private {Set<function>} - the listeners that will be called on emit
    this.listeners = new Set();

    // @private {Object[]} - during emit() keep track of iteration progress and guard listeners if mutated during emit()
    this.emitContexts = [];

    // @public {function|undefined} changeCount - Not defined usually because of memory usage. If defined, this will be
    // called when the listener count changes, e.g. changeCount( {number} listenersAddedQuantity ), with the number
    // being negative for listeners removed.

    // for production memory concerns; no need to keep this around.
    if ( assert ) {

      // @private {boolean} - to keep track if it has been disposed or not
      this.isDisposed = false;
    }
  }

  /**
   * Disposes an Emitter. All listeners are removed.
   * @public
   */
  dispose() {
    this.removeAllListeners();

    if ( assert ) {
      this.isDisposed = true;
    }
  }

  /**
   * Notify listeners
   * @public
   */
  emit() {
    assert && assert( !this.isDisposed, 'should not be called if disposed' );

    // Support for a query parameter that shuffles listeners, but bury behind assert so it will be stripped out on build
    // so it won't impact production performance.
    if ( assert && shuffleListeners ) {
      this.listeners = new Set( _.shuffle( Array.from( this.listeners ) ) ); // eslint-disable-line bad-sim-text
    }

    // Notify wired-up listeners, if any
    if ( this.listeners.size > 0 ) {

      const emitContext = {
        index: 0
        // listenerArray: [] // {Array<function>|undefined} assigned if a mutation is made during emit
      };
      this.emitContexts.push( emitContext );

      for ( const listener of this.listeners ) {
        listener.apply( null, arguments );
        emitContext.index++;

        // If a listener was added or removed, we cannot continue processing the mutated Set, we must switch to
        // iterate over the guarded array
        if ( emitContext.listenerArray ) {
          break;
        }
      }

      // If the listeners were guarded during emit, we bailed out on the for..of and continue iterating over the original
      // listeners in order from where we left off.
      if ( emitContext.listenerArray ) {<commit_msg>fix type expressions<commit_after>// Copyright 2015-2020, University of Colorado Boulder

/**
 * Lightweight event & listener abstraction for a single event type.
 *
 * @author <NAME> (PhET Interactive Simulations)
 * @author <NAME> (PhET Interactive Simulations)
 */

import axon from './axon.js';

// constants
const shuffleListeners = _.hasIn( window, 'phet.chipper.queryParameters' ) && phet.chipper.queryParameters.shuffleListeners;

class TinyEmitter {
  constructor() {

    // @private {Set<function>} - the listeners that will be called on emit
    this.listeners = new Set();

    // @private {Object[]} - during emit() keep track of iteration progress and guard listeners if mutated during emit()
    this.emitContexts = [];

    // @public {function|undefined} changeCount - Not defined usually because of memory usage. If defined, this will be
    // called when the listener count changes, e.g. changeCount( {number} listenersAddedQuantity ), with the number
    // being negative for listeners removed.

    // for production memory concerns; no need to keep this around.
    if ( assert ) {

      // @private {boolean} - to keep track if it has been disposed or not
      this.isDisposed = false;
    }
  }

  /**
   * Disposes an Emitter. All listeners are removed.
   * @public
   */
  dispose() {
    this.removeAllListeners();

    if ( assert ) {
      this.isDisposed = true;
    }
  }

  /**
   * Notify listeners
   * @public
   */
  emit() {
    assert && assert( !this.isDisposed, 'should not be called if disposed' );

    // Support for a query parameter that shuffles listeners, but bury behind assert so it will be stripped out on build
    // so it won't impact production performance.
    if ( assert && shuffleListeners ) {
      this.listeners = new Set( _.shuffle( Array.from( this.listeners ) ) ); // eslint-disable-line bad-sim-text
    }

    // Notify wired-up listeners, if any
    if ( this.listeners.size > 0 ) {

      const emitContext = {
        index: 0
        // listenerArray: [] // {Array.<function>|undefined} assigned if a mutation is made during emit
      };
      this.emitContexts.push( emitContext );

      for ( const listener of this.listeners ) {
        listener.apply( null, arguments );
        emitContext.index++;

        // If a listener was added or removed, we cannot continue processing the mutated Set, we must switch to
        // iterate over the guarded array
        if ( emitContext.listenerArray ) {
          break;
        }
      }

      // If the listeners were guarded during emit, we bailed out on the for..of and continue iterating over the original
      // listeners in order from where we left off.
      if ( emitContext.listenerArray ) {
{'fraction_non_alphanumeric': 0.09996331621423331, 'fraction_numerical': 0.003668378576669112, 'mean_word_length': 2.6401869158878504, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, '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': '609190', 'n_tokens_mistral': 1529, 'n_tokens_neox': 1446, 'n_words': 566}