life-towers/src/app/store/inner-node.ts
Andras Schmelczer 3101c973eb Fix bugs
2019-09-07 21:17:34 +02:00

89 lines
2.1 KiB
TypeScript

import { Node, NodeState } from './node';
export interface InnerNodeState extends NodeState {
dummy: any;
}
export class InnerNode extends Node implements InnerNodeState {
readonly dummy = 3;
parent: Node;
private nextVersion: this = null;
readonly children: Array<InnerNode>;
constructor(children: Array<InnerNode> = []) {
super(children);
this.children = children;
}
get latestVersion(): this {
let version;
for (version = this; version.nextVersion !== null; version = version.nextVersion) {
// pass
}
return version;
}
addChildren(children: Array<InnerNode>): this {
return super.addChildren.call(this.latestVersion, children);
}
replaceChild(update: { oldValue: InnerNode; newValue: InnerNode }): this {
return super.replaceChild.call(this.latestVersion, update);
}
changeKeys<T extends NodeState>(props: Partial<T>): this {
if (this.nextVersion !== null) {
this.latestVersion.changeKeys(props);
}
let shouldClone = false;
for (const prop in props) {
// @ts-ignore
if (props.hasOwnProperty(prop) && props[prop] !== this[prop]) {
shouldClone = true;
break;
}
}
if (!shouldClone) {
return;
}
const clone = this.cloneWithChangedKeys(props);
clone.children.forEach(c => (c.parent = clone));
this.nextVersion = clone;
this.parent.replaceChild({
oldValue: this,
newValue: clone
});
return clone;
}
protected onAfterClone() {}
protected cloneWithChangedKeys<T extends NodeState>(props: Partial<T>): this {
const insides = Object.getOwnPropertyDescriptors(this);
for (const key in props) {
if (props.hasOwnProperty(key)) {
if (insides.hasOwnProperty(key)) {
insides[key].value = props[key];
} else {
// @ts-ignore
insides[key] = {
value: props[key]
};
}
}
}
const clone = Object.create(Object.getPrototypeOf(this), insides);
clone.setUniqueness();
clone.onAfterClone();
return clone;
}
}