export { Base, Root };

/**
 * A pool for recycling (re-using) objects.
 *
 * It could be used to improve performance by reducing memory re-allocation.
 *
 */
let Base = ( ParentClass = Object ) => class PadInfoCalculator extends ParentClass {
  
  /**
   * @param {Class} objectClass
   *   The class for all newly created objects.
   *
   * @param {function} pfnSetAsConstructor
   *   A function works as its constructor. Before .get_or_create_by() returns a recycled object, its .pfnSetAsConstructor() method
   * will be called to re-initilaize it.
   */
  constructor( objectClass, pfnSetAsConstructor ) {
    this.objectClass = objectClass;
    this.pfnSetAsConstructor = pfnSetAsConstructor;

    this.recycledObjects = new Set(); // Using set for handling object be recycled multiple times.
  }

  /**
   * @return {number}
   *   Return the quantity of recycled objects.
   */
  get size() {
    return this.recycledObjects.size;
  }

  /**
   *
   * @return {object}
   *   An obeject which is an instance of this.ObjectClass. If it is newly created, all RestArgs will be passed into its constructor.
   * If it is re-used (i.e. from recycled) object, all RestArgs will be passed into its .pfnSetAsConstructor() method.
   */
  get_or_create_by( ...restArgs ) {
    let returnedObject;
    if ( this.recycledObjects.size > 0 ) {
      let values = this.recycledObjects.values();
      returnedObject = values.next().value;          // Get the first object.
      this.recycledObjects.delete( returnedObject ); // Removed from list.
      this.pfnSetAsConstructor.apply( returnedObject, restArgs );
    } else {
      returnedObject = new ( this.objectClass )( ...restArgs );
    }
    return returnedObject;
  }

  /**
   * @param {Object} 
   *   The object (which should be an instance of this.ObjectClass) to be recycled.
   */
  recycle( objectToBeRecycled ) {
    this.recycledObjects.add( objectToBeRecycled );
  }

  /**
   * Discard all recycled objects.
   */
  clear() {
    this.recycledObjects.clear();
  }

  /**
   * @return {iterator)
   *   Return an iterator object that contains all recycled objects.
   */
  * values() {
    yield* this.recycledObjects.values();
  }

}


/**
 * Almost the same as Base class except its parent class is fixed to Object. In other words, caller can not
 * specify the parent class of ObjectPool.Root (so it is named "Root" which can not have parent class).
 */
class Root extends Base() {
}


@@ -703,31 +703,91 @@
    this.
-recycledO
+objectArray = new Array(); // For fetching efficientlys.%0A    this.o
 bject
-s
+Set
  = new S
@@ -799,27 +799,17 @@
  // 
-Using set for handl
+For check
 ing 
@@ -815,19 +815,16 @@
  object 
-be 
 recycled
@@ -1355,164 +1355,81 @@
 his.
-recycledObjects.size %3E 0 ) %7B%0A      let values = this.recycledObjects.values();%0A      returnedObject = values.next().value;          // Get the first object.
+objectArray.length %3E 0 ) %7B%0A      returnedObject = this.objectArray.pop();
 %0A   
@@ -1436,31 +1436,25 @@
    this.
-recycledO
+o
 bject
-s
+Set
 .delete(
@@ -1492,11 +1492,10 @@
 rom 
-li
 s
+e
 t.%0A 
@@ -1830,36 +1830,112 @@
 ) %7B%0A    
-this.recycledO
+if ( !this.objectSet.has( objectToBeRecycled ) ) %7B // Avoiding duplicately.%0A      this.o
 bject
-s
+Set
 .add( ob
@@ -1954,16 +1954,73 @@
 cled );%0A
+      this.objectArray.push( objectToBeRecycled );%0A    %7D%0A
   %7D%0A%0A  /
@@ -2088,31 +2088,58 @@
 his.
-recycledObjects.clear()
+objectSet.clear();%0A    this.objectArray.length = 0
 ;%0A  

Update ObjectPool.js