@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
92 lines (73 loc) • 2.33 kB
JavaScript
import { isArrayEqualStrict } from "../../collection/array/isArrayEqualStrict.js";
import { isArraysEqualWithComparator } from "../../collection/array/isArraysEqualWithComparator.js";
/**
* @template A,B
* @param {A} a
* @param {B} b
* @param {function(a:A, b:B):boolean} [value_equality_function] allows you to insert custom element comparison function
* @param {*} [value_equality_function_context]
* @returns {boolean}
*/
export function objectDeepEquals(
a, b,
value_equality_function = objectDeepEquals,
value_equality_function_context = null
) {
if (a === b) {
// identity shortcut
return true;
}
const tA = typeof a;
const tB = typeof b;
if (tA !== tB) {
return false;
}
if (tA !== "object") {
// primitive types, identity equality already checked
return false;
}
if (a === null || b === null) {
// we know that A and B are not the same, so if one of them is a null - there is no possible equality
return false;
}
if (Array.isArray(a)) {
// special fast path for arrays
if (!Array.isArray(b)) {
// one is an array, the other is not
return false;
}
return isArraysEqualWithComparator(a, b, value_equality_function, value_equality_function_context);
}
// try equals function
if (
typeof a.equals === "function"
&& typeof b.equals === "function"
) {
return a.equals(b);
}
const keys_a = Object.keys(a);
const keys_b = Object.keys(b);
// sort keys to eliminate ordering concerns
keys_a.sort();
keys_b.sort();
if (!isArrayEqualStrict(keys_a, keys_b)) {
// different fields
return false;
}
const key_count = keys_a.length;
for (let i = 0; i < key_count; i++) {
const key = keys_a[i];
const a_value = a[key];
const b_value = b[key];
const values_are_equal = value_equality_function.call(
value_equality_function_context,
a_value,
b_value
);
if (!values_are_equal) {
return false;
}
}
// looks like we have equality
return true;
}