arcade-physics
Version:
Use Arcade Physics without Phaser.
136 lines • 4 kB
JavaScript
;
/**
* @author Richard Davey <rich@photonstorm.com>
* @author Angry Bytes (and contributors)
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.StableSort = void 0;
/**
* The comparator function.
*
* @ignore
*
* @param {*} a - The first item to test.
* @param {*} b - The second itemt to test.
*
* @return {boolean} True if they localCompare, otherwise false.
*/
function Compare(a, b) {
return String(a).localeCompare(b);
}
/**
* Process the array contents.
*
* @ignore
*
* @param {array} array - The array to process.
* @param {function} compare - The comparison function.
*
* @return {array} - The processed array.
*/
function Process(array, compare) {
// Short-circuit when there's nothing to sort.
const len = array.length;
if (len <= 1) {
return array;
}
// Rather than dividing input, simply iterate chunks of 1, 2, 4, 8, etc.
// Chunks are the size of the left or right hand in merge sort.
// Stop when the left-hand covers all of the array.
let buffer = new Array(len);
for (let chk = 1; chk < len; chk *= 2) {
RunPass(array, compare, chk, buffer);
const tmp = array;
array = buffer;
buffer = tmp;
}
return array;
}
/**
* Run a single pass with the given chunk size.
*
* @ignore
*
* @param {array} arr - The array to run the pass on.
* @param {function} comp - The comparison function.
* @param {number} chk - The number of iterations.
* @param {array} result - The array to store the result in.
*/
function RunPass(arr, comp, chk, result) {
const len = arr.length;
let i = 0;
// Step size / double chunk size.
const dbl = chk * 2;
// Bounds of the left and right chunks.
let l, r, e;
// Iterators over the left and right chunk.
let li, ri;
// Iterate over pairs of chunks.
for (l = 0; l < len; l += dbl) {
r = l + chk;
e = r + chk;
if (r > len) {
r = len;
}
if (e > len) {
e = len;
}
// Iterate both chunks in parallel.
li = l;
ri = r;
while (true) {
// Compare the chunks.
if (li < r && ri < e) {
// This works for a regular `sort()` compatible comparator,
// but also for a simple comparator like: `a > b`
if (comp(arr[li], arr[ri]) <= 0) {
result[i++] = arr[li++];
}
else {
result[i++] = arr[ri++];
}
}
else if (li < r) {
// Nothing to compare, just flush what's left.
result[i++] = arr[li++];
}
else if (ri < e) {
result[i++] = arr[ri++];
}
else {
// Both iterators are at the chunk ends.
break;
}
}
}
}
/**
* An in-place stable array sort, because `Array#sort()` is not guaranteed stable.
*
* This is an implementation of merge sort, without recursion.
*
* Function based on the Two-Screen/stable sort 0.1.8 from https://github.com/Two-Screen/stable
*
* @function Phaser.Utils.Array.StableSort
* @since 3.0.0
*
* @param {array} array - The input array to be sorted.
* @param {function} [compare] - The comparison function.
*
* @return {array} The sorted result.
*/
const StableSort = (array, compare) => {
if (compare === undefined) {
compare = Compare;
}
const result = Process(array, compare);
// This simply copies back if the result isn't in the original array, which happens on an odd number of passes.
if (result !== array) {
RunPass(result, null, array.length, array);
}
return array;
};
exports.StableSort = StableSort;
//# sourceMappingURL=StableSort.js.map