mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #2054 from chenglou/accum
[RFC] Use `accumulateInto` to save even more allocation
This commit is contained in:
@@ -23,7 +23,7 @@ var EventPluginUtils = require('EventPluginUtils');
|
||||
var EventPropagators = require('EventPropagators');
|
||||
var SyntheticEvent = require('SyntheticEvent');
|
||||
|
||||
var accumulate = require('accumulate');
|
||||
var accumulateInto = require('accumulateInto');
|
||||
var keyOf = require('keyOf');
|
||||
|
||||
var isStartish = EventPluginUtils.isStartish;
|
||||
@@ -212,7 +212,7 @@ function setResponderAndExtractTransfer(
|
||||
nativeEvent
|
||||
);
|
||||
EventPropagators.accumulateDirectDispatches(terminateEvent);
|
||||
extracted = accumulate(extracted, [grantEvent, terminateEvent]);
|
||||
extracted = accumulateInto(extracted, [grantEvent, terminateEvent]);
|
||||
responderID = wantsResponderID;
|
||||
} else {
|
||||
var rejectEvent = SyntheticEvent.getPooled(
|
||||
@@ -221,10 +221,10 @@ function setResponderAndExtractTransfer(
|
||||
nativeEvent
|
||||
);
|
||||
EventPropagators.accumulateDirectDispatches(rejectEvent);
|
||||
extracted = accumulate(extracted, rejectEvent);
|
||||
extracted = accumulateInto(extracted, rejectEvent);
|
||||
}
|
||||
} else {
|
||||
extracted = accumulate(extracted, grantEvent);
|
||||
extracted = accumulateInto(extracted, grantEvent);
|
||||
responderID = wantsResponderID;
|
||||
}
|
||||
return extracted;
|
||||
@@ -288,7 +288,7 @@ var ResponderEventPlugin = {
|
||||
nativeEvent
|
||||
);
|
||||
if (transfer) {
|
||||
extracted = accumulate(extracted, transfer);
|
||||
extracted = accumulateInto(extracted, transfer);
|
||||
}
|
||||
}
|
||||
// Now that we know the responder is set correctly, we can dispatch
|
||||
@@ -303,7 +303,7 @@ var ResponderEventPlugin = {
|
||||
nativeEvent
|
||||
);
|
||||
EventPropagators.accumulateDirectDispatches(gesture);
|
||||
extracted = accumulate(extracted, gesture);
|
||||
extracted = accumulateInto(extracted, gesture);
|
||||
}
|
||||
if (type === eventTypes.responderRelease) {
|
||||
responderID = null;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
|
||||
|
||||
var accumulate = require('accumulate');
|
||||
var accumulateInto = require('accumulateInto');
|
||||
var forEachAccumulated = require('forEachAccumulated');
|
||||
var invariant = require('invariant');
|
||||
|
||||
@@ -36,7 +36,8 @@ var LocalEventTrapMixin = {
|
||||
handlerBaseName,
|
||||
this.getDOMNode()
|
||||
);
|
||||
this._localEventListeners = accumulate(this._localEventListeners, listener);
|
||||
this._localEventListeners =
|
||||
accumulateInto(this._localEventListeners, listener);
|
||||
},
|
||||
|
||||
// trapCapturedEvent would look nearly identical. We don't implement that
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
var EventPluginRegistry = require('EventPluginRegistry');
|
||||
var EventPluginUtils = require('EventPluginUtils');
|
||||
|
||||
var accumulate = require('accumulate');
|
||||
var accumulateInto = require('accumulateInto');
|
||||
var forEachAccumulated = require('forEachAccumulated');
|
||||
var invariant = require('invariant');
|
||||
var isEventSupported = require('isEventSupported');
|
||||
@@ -236,7 +236,7 @@ var EventPluginHub = {
|
||||
nativeEvent
|
||||
);
|
||||
if (extractedEvents) {
|
||||
events = accumulate(events, extractedEvents);
|
||||
events = accumulateInto(events, extractedEvents);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,7 +252,7 @@ var EventPluginHub = {
|
||||
*/
|
||||
enqueueEvents: function(events) {
|
||||
if (events) {
|
||||
eventQueue = accumulate(eventQueue, events);
|
||||
eventQueue = accumulateInto(eventQueue, events);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
var EventConstants = require('EventConstants');
|
||||
var EventPluginHub = require('EventPluginHub');
|
||||
|
||||
var accumulate = require('accumulate');
|
||||
var accumulateInto = require('accumulateInto');
|
||||
var forEachAccumulated = require('forEachAccumulated');
|
||||
|
||||
var PropagationPhases = EventConstants.PropagationPhases;
|
||||
@@ -52,8 +52,9 @@ function accumulateDirectionalDispatches(domID, upwards, event) {
|
||||
var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
|
||||
var listener = listenerAtPhase(domID, event, phase);
|
||||
if (listener) {
|
||||
event._dispatchListeners = accumulate(event._dispatchListeners, listener);
|
||||
event._dispatchIDs = accumulate(event._dispatchIDs, domID);
|
||||
event._dispatchListeners =
|
||||
accumulateInto(event._dispatchListeners, listener);
|
||||
event._dispatchIDs = accumulateInto(event._dispatchIDs, domID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,8 +86,9 @@ function accumulateDispatches(id, ignoredDirection, event) {
|
||||
var registrationName = event.dispatchConfig.registrationName;
|
||||
var listener = getListener(id, registrationName);
|
||||
if (listener) {
|
||||
event._dispatchListeners = accumulate(event._dispatchListeners, listener);
|
||||
event._dispatchIDs = accumulate(event._dispatchIDs, id);
|
||||
event._dispatchListeners =
|
||||
accumulateInto(event._dispatchListeners, listener);
|
||||
event._dispatchIDs = accumulateInto(event._dispatchIDs, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright 2014 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @emails react-core
|
||||
* @jsx React.DOM
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
require('mock-modules')
|
||||
.dontMock('accumulateInto');
|
||||
|
||||
var accumulateInto;
|
||||
|
||||
describe('accumulateInto', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
accumulateInto = require('accumulateInto');
|
||||
});
|
||||
|
||||
it('throws if the second item is null', function() {
|
||||
expect(function() {
|
||||
accumulateInto([], null);
|
||||
}).toThrow(
|
||||
'Invariant Violation: accumulateInto(...): Accumulated items must not ' +
|
||||
'be null or undefined.'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the second item if first is null', function() {
|
||||
var a = [];
|
||||
expect(accumulateInto(null, a)).toBe(a);
|
||||
});
|
||||
|
||||
it('merges the second into the first if first item is an array', function() {
|
||||
var a = [1, 2];
|
||||
var b = [3, 4];
|
||||
accumulateInto(a, b);
|
||||
expect(a).toEqual([1, 2, 3, 4]);
|
||||
expect(b).toEqual([3, 4]);
|
||||
var c = [1];
|
||||
accumulateInto(c, 2);
|
||||
expect(c).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('returns a new array if first or both items are scalar', function() {
|
||||
var a = [2];
|
||||
expect(accumulateInto(1, a)).toEqual([1, 2]);
|
||||
expect(a).toEqual([2]);
|
||||
expect(accumulateInto(1, 2)).toEqual([1, 2]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright 2014 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @providesModule accumulateInto
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
||||
/**
|
||||
*
|
||||
* Accumulates items that must not be null or undefined into the first one. This
|
||||
* is used to conserve memory by avoiding array allocations, and thus sacrifices
|
||||
* API cleanness. Since `current` can be null before being passed in and not
|
||||
* null after this function, make sure to assign it back to `current`:
|
||||
*
|
||||
* `a = accumulateInto(a, b);`
|
||||
*
|
||||
* This API should be sparingly used. Try `accumulate` for something cleaner.
|
||||
*
|
||||
* @return {*|array<*>} An accumulation of items.
|
||||
*/
|
||||
|
||||
function accumulateInto(current, next) {
|
||||
invariant(
|
||||
next != null,
|
||||
'accumulateInto(...): Accumulated items must not be null or undefined.'
|
||||
);
|
||||
if (current == null) {
|
||||
return next;
|
||||
}
|
||||
|
||||
// Both are not empty. Warning: Never call x.concat(y) when you are not
|
||||
// certain that x is an Array (x could be a string with concat method).
|
||||
var currentIsArray = Array.isArray(current);
|
||||
var nextIsArray = Array.isArray(next);
|
||||
|
||||
if (currentIsArray && nextIsArray) {
|
||||
current.push.apply(current, next);
|
||||
return current;
|
||||
}
|
||||
|
||||
if (currentIsArray) {
|
||||
current.push(next);
|
||||
return current;
|
||||
}
|
||||
|
||||
if (nextIsArray) {
|
||||
// A bit too dangerous to mutate `next`.
|
||||
return [current].concat(next);
|
||||
}
|
||||
|
||||
return [current, next];
|
||||
}
|
||||
|
||||
module.exports = accumulateInto;
|
||||
Reference in New Issue
Block a user