2018-07-15 14:04:27 +00:00
|
|
|
import * as plugins from './lik.plugins';
|
2020-02-06 11:11:16 +00:00
|
|
|
import { FastMap } from './lik.fastmap';
|
2016-07-31 12:36:28 +00:00
|
|
|
|
2020-05-27 23:50:07 +00:00
|
|
|
export const uni = (prefix: string = 'uni') => {
|
2020-07-12 00:44:50 +00:00
|
|
|
return `${prefix}xxxxxxxxxxx`.replace(/[xy]/g, (c) => {
|
2020-05-27 23:50:07 +00:00
|
|
|
const r = (Math.random() * 16) | 0;
|
|
|
|
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
|
|
return v.toString(16);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-08-08 15:29:44 +00:00
|
|
|
export interface IObjectmapForEachFunction<T> {
|
2018-01-27 17:11:11 +00:00
|
|
|
(itemArg: T): void;
|
2016-09-21 11:44:11 +00:00
|
|
|
}
|
2016-08-08 14:00:14 +00:00
|
|
|
|
2016-08-08 15:29:44 +00:00
|
|
|
export interface IObjectmapFindFunction<T> {
|
2018-01-27 17:11:11 +00:00
|
|
|
(itemArg: T): boolean;
|
2016-09-21 11:44:11 +00:00
|
|
|
}
|
2016-07-31 12:36:28 +00:00
|
|
|
|
2020-11-24 19:11:42 +00:00
|
|
|
export interface IObjectMapEventData<T> {
|
|
|
|
operation: 'add' | 'remove';
|
|
|
|
payload: T;
|
|
|
|
}
|
|
|
|
|
2016-07-30 22:54:46 +00:00
|
|
|
/**
|
|
|
|
* allows keeping track of objects
|
|
|
|
*/
|
2020-05-04 00:09:20 +00:00
|
|
|
export class ObjectMap<T> {
|
2020-02-06 11:11:16 +00:00
|
|
|
private fastMap = new FastMap<T>();
|
2017-06-17 12:44:55 +00:00
|
|
|
|
2019-11-27 23:15:13 +00:00
|
|
|
// events
|
2020-11-24 19:11:42 +00:00
|
|
|
public eventSubject = new plugins.smartrx.rxjs.Subject<IObjectMapEventData<T>>();
|
2019-11-27 23:15:13 +00:00
|
|
|
|
2017-06-17 12:44:55 +00:00
|
|
|
/**
|
|
|
|
* returns a new instance
|
|
|
|
*/
|
2018-01-27 17:11:11 +00:00
|
|
|
constructor() {
|
2017-06-17 12:44:55 +00:00
|
|
|
// nothing here
|
|
|
|
}
|
|
|
|
|
2020-02-06 11:11:16 +00:00
|
|
|
/**
|
|
|
|
* adds an object mapped to a string
|
|
|
|
* the string must be unique
|
|
|
|
*/
|
2020-02-06 15:31:58 +00:00
|
|
|
addMappedUnique(uniqueKeyArg: string, objectArg: T) {
|
|
|
|
this.fastMap.addToMap(uniqueKeyArg, objectArg);
|
2020-02-06 11:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* fastest way to get an object from the map
|
|
|
|
* @param uniqueKey
|
|
|
|
*/
|
2020-02-06 15:31:58 +00:00
|
|
|
public getMappedUnique(uniqueKeyArg: string) {
|
|
|
|
return this.fastMap.getByKey(uniqueKeyArg);
|
|
|
|
}
|
2020-02-06 11:11:16 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* remove key
|
|
|
|
* @param functionArg
|
|
|
|
*/
|
2020-02-06 15:31:58 +00:00
|
|
|
public removeMappedUnique(uniqueKey: string) {
|
|
|
|
const object = this.getMappedUnique(uniqueKey);
|
|
|
|
}
|
2020-02-06 11:11:16 +00:00
|
|
|
|
2017-06-17 12:44:55 +00:00
|
|
|
/**
|
|
|
|
* add object to Objectmap
|
2017-07-05 12:29:08 +00:00
|
|
|
* returns false if the object is already in the map
|
|
|
|
* returns true if the object was added successfully
|
2017-06-17 12:44:55 +00:00
|
|
|
*/
|
2020-02-06 15:31:58 +00:00
|
|
|
public add(objectArg: T): string {
|
|
|
|
// lets search for an existing unique key
|
|
|
|
for (const keyArg of this.fastMap.getKeys()) {
|
|
|
|
const object = this.fastMap.getByKey(keyArg);
|
|
|
|
if (object === objectArg) {
|
|
|
|
return keyArg;
|
|
|
|
}
|
2017-07-05 12:29:08 +00:00
|
|
|
}
|
2020-02-06 15:31:58 +00:00
|
|
|
|
|
|
|
// otherwise lets create it
|
2020-05-27 23:50:07 +00:00
|
|
|
const uniqueKey = uni('key');
|
2020-02-06 15:31:58 +00:00
|
|
|
this.addMappedUnique(uniqueKey, objectArg);
|
2020-11-24 19:11:42 +00:00
|
|
|
this.eventSubject.next({
|
|
|
|
operation: 'add',
|
|
|
|
payload: objectArg
|
|
|
|
});
|
2020-02-06 15:31:58 +00:00
|
|
|
return uniqueKey;
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* like .add but adds an whole array of objects
|
|
|
|
*/
|
2018-11-23 19:33:44 +00:00
|
|
|
public addArray(objectArrayArg: T[]) {
|
2020-02-06 15:31:58 +00:00
|
|
|
for (const item of objectArrayArg) {
|
2018-01-27 17:11:11 +00:00
|
|
|
this.add(item);
|
2016-08-08 14:00:14 +00:00
|
|
|
}
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* check if object is in Objectmap
|
|
|
|
*/
|
2020-02-06 15:31:58 +00:00
|
|
|
public checkForObject(objectArg: T): boolean {
|
|
|
|
return !!this.getKeyForObject(objectArg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get key for object
|
2020-02-07 16:32:58 +00:00
|
|
|
* @param findFunction
|
2020-02-06 15:31:58 +00:00
|
|
|
*/
|
|
|
|
public getKeyForObject(objectArg: T) {
|
|
|
|
let foundKey: string = null;
|
|
|
|
for (const keyArg of this.fastMap.getKeys()) {
|
|
|
|
if (!foundKey && this.fastMap.getByKey(keyArg) === objectArg) {
|
|
|
|
foundKey = keyArg;
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return foundKey;
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* find object
|
|
|
|
*/
|
2020-02-06 15:31:58 +00:00
|
|
|
public find(findFunction: IObjectmapFindFunction<T>): T {
|
|
|
|
for (const keyArg of this.fastMap.getKeys()) {
|
|
|
|
if (findFunction(this.fastMap.getByKey(keyArg))) {
|
|
|
|
return this.getMappedUnique(keyArg);
|
|
|
|
}
|
2016-11-19 22:08:54 +00:00
|
|
|
}
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* finds a specific element and then removes it
|
|
|
|
*/
|
2018-11-23 19:33:44 +00:00
|
|
|
public findOneAndRemove(findFunction: IObjectmapFindFunction<T>): T {
|
|
|
|
const foundElement = this.find(findFunction);
|
2017-06-17 12:44:55 +00:00
|
|
|
if (foundElement) {
|
2018-01-27 17:11:11 +00:00
|
|
|
this.remove(foundElement);
|
2016-07-30 22:54:46 +00:00
|
|
|
}
|
2018-01-27 17:11:11 +00:00
|
|
|
return foundElement;
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* run function for each item in Objectmap
|
|
|
|
*/
|
2018-11-23 19:33:44 +00:00
|
|
|
public async forEach(functionArg: IObjectmapForEachFunction<T>) {
|
2020-02-06 15:31:58 +00:00
|
|
|
for (const keyArg of this.fastMap.getKeys()) {
|
|
|
|
await functionArg(this.fastMap.getByKey(keyArg));
|
2017-08-27 18:01:06 +00:00
|
|
|
}
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gets an object in the Observablemap and removes it, so it can't be retrieved again
|
|
|
|
*/
|
2018-11-23 19:33:44 +00:00
|
|
|
public getOneAndRemove(): T {
|
2020-02-06 15:31:58 +00:00
|
|
|
const keys = this.fastMap.getKeys();
|
2020-02-07 16:32:58 +00:00
|
|
|
if (keys.length === 0) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
const keyToUse = keys[0];
|
|
|
|
const removedItem = this.fastMap.removeFromMap(keyToUse);
|
2020-11-24 19:11:42 +00:00
|
|
|
this.eventSubject.next({
|
|
|
|
operation: 'remove',
|
|
|
|
payload: removedItem
|
|
|
|
});
|
2020-02-07 16:32:58 +00:00
|
|
|
return removedItem;
|
|
|
|
}
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns a cloned array of all the objects currently in the Objectmap
|
|
|
|
*/
|
2019-03-15 22:50:39 +00:00
|
|
|
public getArray(): T[] {
|
2018-11-23 19:33:44 +00:00
|
|
|
const returnArray: any[] = [];
|
2020-02-06 15:31:58 +00:00
|
|
|
for (const keyArg of this.fastMap.getKeys()) {
|
|
|
|
returnArray.push(this.fastMap.getByKey(keyArg));
|
2018-11-23 19:33:44 +00:00
|
|
|
}
|
|
|
|
return returnArray;
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* check if Objectmap ist empty
|
|
|
|
*/
|
2018-11-23 19:33:44 +00:00
|
|
|
public isEmpty(): boolean {
|
2020-02-06 15:31:58 +00:00
|
|
|
return this.fastMap.getKeys().length === 0;
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* remove object from Objectmap
|
|
|
|
*/
|
2020-02-06 15:31:58 +00:00
|
|
|
public remove(objectArg: T): T {
|
|
|
|
if (this.checkForObject(objectArg)) {
|
|
|
|
const keyArg = this.getKeyForObject(objectArg);
|
|
|
|
const removedObject = this.fastMap.removeFromMap(keyArg);
|
2020-11-24 19:11:42 +00:00
|
|
|
this.eventSubject.next({
|
|
|
|
operation: 'remove',
|
|
|
|
payload: removedObject
|
|
|
|
});
|
2020-02-06 15:31:58 +00:00
|
|
|
return removedObject;
|
2016-11-19 22:08:54 +00:00
|
|
|
}
|
2020-02-06 15:31:58 +00:00
|
|
|
return null;
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* wipe Objectmap
|
|
|
|
*/
|
2018-11-23 19:33:44 +00:00
|
|
|
public wipe() {
|
2020-02-06 15:31:58 +00:00
|
|
|
for (const keyArg of this.fastMap.getKeys()) {
|
|
|
|
this.fastMap.removeFromMap(keyArg);
|
|
|
|
}
|
2017-06-17 12:44:55 +00:00
|
|
|
}
|
2020-05-04 00:09:20 +00:00
|
|
|
|
|
|
|
/**
|
2020-05-25 13:18:53 +00:00
|
|
|
* returns a new Objectmap that includes
|
2020-05-04 00:09:20 +00:00
|
|
|
*/
|
|
|
|
public concat(objectMapArg: ObjectMap<T>) {
|
|
|
|
const concattedObjectMap = new ObjectMap<T>();
|
|
|
|
concattedObjectMap.fastMap.addAllFromOther(this.fastMap);
|
|
|
|
concattedObjectMap.fastMap.addAllFromOther(objectMapArg.fastMap);
|
|
|
|
return concattedObjectMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* tries to merge another Objectmap
|
|
|
|
* Note: uniqueKeyCollisions will cause overwrite
|
|
|
|
* @param objectMapArg
|
|
|
|
*/
|
|
|
|
public addAllFromOther(objectMapArg: ObjectMap<T>) {
|
|
|
|
this.fastMap.addAllFromOther(objectMapArg.fastMap);
|
|
|
|
}
|
2016-09-21 11:44:11 +00:00
|
|
|
}
|