UNPKG

3.23 kBJavaScriptView Raw
1/**
2 * Copyright (c) 2013-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 *
8 */
9
10'use strict';
11
12var _prodInvariant = require('./reactProdInvariant');
13
14var invariant = require('fbjs/lib/invariant');
15
16/**
17 * Static poolers. Several custom versions for each potential number of
18 * arguments. A completely generic pooler is easy to implement, but would
19 * require accessing the `arguments` object. In each of these, `this` refers to
20 * the Class itself, not an instance. If any others are needed, simply add them
21 * here, or in their own files.
22 */
23var oneArgumentPooler = function (copyFieldsFrom) {
24 var Klass = this;
25 if (Klass.instancePool.length) {
26 var instance = Klass.instancePool.pop();
27 Klass.call(instance, copyFieldsFrom);
28 return instance;
29 } else {
30 return new Klass(copyFieldsFrom);
31 }
32};
33
34var twoArgumentPooler = function (a1, a2) {
35 var Klass = this;
36 if (Klass.instancePool.length) {
37 var instance = Klass.instancePool.pop();
38 Klass.call(instance, a1, a2);
39 return instance;
40 } else {
41 return new Klass(a1, a2);
42 }
43};
44
45var threeArgumentPooler = function (a1, a2, a3) {
46 var Klass = this;
47 if (Klass.instancePool.length) {
48 var instance = Klass.instancePool.pop();
49 Klass.call(instance, a1, a2, a3);
50 return instance;
51 } else {
52 return new Klass(a1, a2, a3);
53 }
54};
55
56var fourArgumentPooler = function (a1, a2, a3, a4) {
57 var Klass = this;
58 if (Klass.instancePool.length) {
59 var instance = Klass.instancePool.pop();
60 Klass.call(instance, a1, a2, a3, a4);
61 return instance;
62 } else {
63 return new Klass(a1, a2, a3, a4);
64 }
65};
66
67var standardReleaser = function (instance) {
68 var Klass = this;
69 !(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;
70 instance.destructor();
71 if (Klass.instancePool.length < Klass.poolSize) {
72 Klass.instancePool.push(instance);
73 }
74};
75
76var DEFAULT_POOL_SIZE = 10;
77var DEFAULT_POOLER = oneArgumentPooler;
78
79/**
80 * Augments `CopyConstructor` to be a poolable class, augmenting only the class
81 * itself (statically) not adding any prototypical fields. Any CopyConstructor
82 * you give this may have a `poolSize` property, and will look for a
83 * prototypical `destructor` on instances.
84 *
85 * @param {Function} CopyConstructor Constructor that can be used to reset.
86 * @param {Function} pooler Customizable pooler.
87 */
88var addPoolingTo = function (CopyConstructor, pooler) {
89 // Casting as any so that flow ignores the actual implementation and trusts
90 // it to match the type we declared
91 var NewKlass = CopyConstructor;
92 NewKlass.instancePool = [];
93 NewKlass.getPooled = pooler || DEFAULT_POOLER;
94 if (!NewKlass.poolSize) {
95 NewKlass.poolSize = DEFAULT_POOL_SIZE;
96 }
97 NewKlass.release = standardReleaser;
98 return NewKlass;
99};
100
101var PooledClass = {
102 addPoolingTo: addPoolingTo,
103 oneArgumentPooler: oneArgumentPooler,
104 twoArgumentPooler: twoArgumentPooler,
105 threeArgumentPooler: threeArgumentPooler,
106 fourArgumentPooler: fourArgumentPooler
107};
108
109module.exports = PooledClass;
\No newline at end of file