UNPKG

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