in packages/redux-dynamic-modules-core/src/Utils/RefCounter.ts [18:93]
export function getObjectRefCounter<T>(
equals: (a: T, b: T) => boolean,
retained?: (a: T) => boolean
): IRefCounter<T> {
if (!equals) {
equals = (a, b) => a === b;
}
if(!retained) {
retained = () => false;
}
const objects: T[] = [];
const counts: number[] = [];
return {
/**
* Gets ref count of given T
*/
getCount: (obj: T): number => {
if (obj === undefined || obj === null) {
return 0;
}
let index = objects.findIndex(o => o && equals(o, obj));
if (index === -1) {
return 0;
}
return counts[index];
},
/**
* Add given T or increments ref count
*/
add: (obj: T): void => {
if (obj === undefined || obj === null) {
return;
}
let index = objects.findIndex(o => o && equals(o, obj));
let count = 1;
if (index === -1) {
index = objects.length;
objects.push(obj);
} else {
count = counts[index] + 1;
}
// If item is retained then keep it for inifinty
if (retained(obj)) {
count = Infinity;
}
counts[index] = count;
},
/**
* Decreases ref count for given T, if refcount reaches to zero removes the T and returns true
*/
remove: (obj: T): boolean => {
if (retained(obj)) {
return false;
}
let index = objects.findIndex(o => o && equals(o, obj));
if (index === -1) {
return false;
}
if (counts[index] === 1) {
delete objects[index];
delete counts[index];
return true;
}
counts[index] = counts[index] - 1;
return false;
},
};
}