You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
3.2 KiB
109 lines
3.2 KiB
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = require('./reactProdInvariant'); |
|
|
|
var invariant = require('fbjs/lib/invariant'); |
|
|
|
/** |
|
* Static poolers. Several custom versions for each potential number of |
|
* arguments. A completely generic pooler is easy to implement, but would |
|
* require accessing the `arguments` object. In each of these, `this` refers to |
|
* the Class itself, not an instance. If any others are needed, simply add them |
|
* here, or in their own files. |
|
*/ |
|
var oneArgumentPooler = function (copyFieldsFrom) { |
|
var Klass = this; |
|
if (Klass.instancePool.length) { |
|
var instance = Klass.instancePool.pop(); |
|
Klass.call(instance, copyFieldsFrom); |
|
return instance; |
|
} else { |
|
return new Klass(copyFieldsFrom); |
|
} |
|
}; |
|
|
|
var twoArgumentPooler = function (a1, a2) { |
|
var Klass = this; |
|
if (Klass.instancePool.length) { |
|
var instance = Klass.instancePool.pop(); |
|
Klass.call(instance, a1, a2); |
|
return instance; |
|
} else { |
|
return new Klass(a1, a2); |
|
} |
|
}; |
|
|
|
var threeArgumentPooler = function (a1, a2, a3) { |
|
var Klass = this; |
|
if (Klass.instancePool.length) { |
|
var instance = Klass.instancePool.pop(); |
|
Klass.call(instance, a1, a2, a3); |
|
return instance; |
|
} else { |
|
return new Klass(a1, a2, a3); |
|
} |
|
}; |
|
|
|
var fourArgumentPooler = function (a1, a2, a3, a4) { |
|
var Klass = this; |
|
if (Klass.instancePool.length) { |
|
var instance = Klass.instancePool.pop(); |
|
Klass.call(instance, a1, a2, a3, a4); |
|
return instance; |
|
} else { |
|
return new Klass(a1, a2, a3, a4); |
|
} |
|
}; |
|
|
|
var standardReleaser = function (instance) { |
|
var Klass = this; |
|
!(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0; |
|
instance.destructor(); |
|
if (Klass.instancePool.length < Klass.poolSize) { |
|
Klass.instancePool.push(instance); |
|
} |
|
}; |
|
|
|
var DEFAULT_POOL_SIZE = 10; |
|
var DEFAULT_POOLER = oneArgumentPooler; |
|
|
|
/** |
|
* Augments `CopyConstructor` to be a poolable class, augmenting only the class |
|
* itself (statically) not adding any prototypical fields. Any CopyConstructor |
|
* you give this may have a `poolSize` property, and will look for a |
|
* prototypical `destructor` on instances. |
|
* |
|
* @param {Function} CopyConstructor Constructor that can be used to reset. |
|
* @param {Function} pooler Customizable pooler. |
|
*/ |
|
var addPoolingTo = function (CopyConstructor, pooler) { |
|
// Casting as any so that flow ignores the actual implementation and trusts |
|
// it to match the type we declared |
|
var NewKlass = CopyConstructor; |
|
NewKlass.instancePool = []; |
|
NewKlass.getPooled = pooler || DEFAULT_POOLER; |
|
if (!NewKlass.poolSize) { |
|
NewKlass.poolSize = DEFAULT_POOL_SIZE; |
|
} |
|
NewKlass.release = standardReleaser; |
|
return NewKlass; |
|
}; |
|
|
|
var PooledClass = { |
|
addPoolingTo: addPoolingTo, |
|
oneArgumentPooler: oneArgumentPooler, |
|
twoArgumentPooler: twoArgumentPooler, |
|
threeArgumentPooler: threeArgumentPooler, |
|
fourArgumentPooler: fourArgumentPooler |
|
}; |
|
|
|
module.exports = PooledClass; |