This commit is contained in:
schmelczerandras 2019-09-06 08:10:56 +02:00
parent ef2d4c47ad
commit 952a3cd34c
4 changed files with 48 additions and 51 deletions

View file

@ -0,0 +1,6 @@
export abstract class Initiable {
protected constructor() {
this.initiate();
}
protected abstract initiate();
}

View file

@ -1,11 +1,9 @@
import { Node } from './node';
import { observableToBeFn } from 'rxjs/internal/testing/TestScheduler';
export abstract class InnerNode extends Node {
parent: Node;
nextVersion: this = null;
protected readonly children: Array<InnerNode> = [];
readonly children: Array<InnerNode> = [];
protected parent: Node;
private nextVersion: this = null;
get latestVersion(): this {
let version;
@ -15,16 +13,6 @@ export abstract class InnerNode extends Node {
return version;
}
protected constructor(parent: Node) {
super();
new Promise(r => r()).then(() =>
parent.addChild({
value: this
})
);
}
mutatedUpdate() {
this.parent.mutatedUpdate();
}
@ -33,30 +21,20 @@ export abstract class InnerNode extends Node {
return this.update((self: this) => this.cloneWithMap.call(self, map));
}
changeKey({ propertyName, value }: { propertyName: string; value: any }): this {
return this.update((self: this) => this.cloneWithAdd.call(self, { propertyName, value }));
}
changeKeys(props: { [propertyName: string]: any }): this {
return this.update((self: this) => this.cloneWithChangedKeys.call(self, props));
}
changeValue({ oldValue, newValue }: { oldValue: any; newValue: any }): this {
return this.update((self: this) => this.cloneWithModify.call(self, { oldValue, newValue }));
}
addChild(update: { value: InnerNode }) {
addChild(update: { child: InnerNode }) {
super.addChild.call(this.latestVersion, update);
}
changeChild(update: { oldValue: InnerNode; newValue: InnerNode }) {
super.changeChild.call(this.latestVersion, update);
super.replaceChild.call(this.latestVersion, update);
}
protected abstract cloneWithMap(map: (a: this) => void): this;
protected abstract cloneWithAdd(update: { value: any; propertyName: string }): this;
protected abstract cloneWithChangedKeys(props: { [propertyName: string]: any }): this;
protected abstract cloneWithModify(update: { oldValue: any; newValue: any }): this;
private update(cloneMethod: (self: this) => this): this {
if (this.nextVersion !== null) {
@ -72,7 +50,7 @@ export abstract class InnerNode extends Node {
child.parent = clone;
}
this.parent.changeChild({
this.parent.replaceChild({
oldValue: this,
newValue: clone
});

View file

@ -1,36 +1,32 @@
import { InnerNode } from './inner-node';
import { Unique } from './unique';
export abstract class Node {
protected static id = 0;
protected static sumCopyCount = 0;
protected abstract readonly children: Array<InnerNode>;
private id = Node.id++;
protected copyCount = 1;
abstract changeKey(update: { propertyName: string; value: any });
abstract changeValue(update: { oldValue: any; newValue: any });
constructor() {
Node.sumCopyCount++;
}
export abstract class Node extends Unique {
readonly children: Array<InnerNode>;
// TODO: fix types.
protected abstract changeKeys(props: any): this;
abstract mutatedUpdate(): void;
addChild(update: { value: InnerNode }) {
this.changeValue({
oldValue: this.children,
newValue: [...this.children, update.value]
private copyCount = 0;
protected initiate() {
super.initiate();
this.copyCount++;
}
addChild({ child }: { child: InnerNode }) {
this.changeKeys({
children: [...this.children, child]
});
}
changeChild({ oldValue, newValue }: { oldValue: InnerNode; newValue: InnerNode }) {
replaceChild({ oldValue, newValue }: { oldValue: InnerNode; newValue: InnerNode }) {
if (oldValue === newValue) {
return;
}
this.changeValue({
oldValue: this.children,
newValue: this.children.map(c => (c === oldValue ? newValue : c))
this.changeKeys({
children: this.children.map(c => (c === oldValue ? newValue : c))
});
}
@ -45,6 +41,6 @@ export abstract class Node {
public log() {
console.log(this._log());
console.log(`All in all, there are ${Node.sumCopyCount} objects.`);
console.log(`All in all, there are ${Unique.ObjectCount} objects.`);
}
}

17
src/app/store/unique.ts Normal file
View file

@ -0,0 +1,17 @@
import { Initiable } from './initiable';
export abstract class Unique extends Initiable {
protected static nextId = 0;
static get ObjectCount(): number {
return Unique.nextId;
}
get id(): number {
return this._id;
}
private _id: number;
protected initiate() {
this._id = Unique.nextId++;
}
}