WIP
This commit is contained in:
parent
ef2d4c47ad
commit
952a3cd34c
4 changed files with 46 additions and 49 deletions
6
src/app/store/initiable.ts
Normal file
6
src/app/store/initiable.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export abstract class Initiable {
|
||||||
|
protected constructor() {
|
||||||
|
this.initiate();
|
||||||
|
}
|
||||||
|
protected abstract initiate();
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
import { Node } from './node';
|
import { Node } from './node';
|
||||||
import { observableToBeFn } from 'rxjs/internal/testing/TestScheduler';
|
|
||||||
|
|
||||||
export abstract class InnerNode extends Node {
|
export abstract class InnerNode extends Node {
|
||||||
parent: Node;
|
readonly children: Array<InnerNode> = [];
|
||||||
nextVersion: this = null;
|
protected parent: Node;
|
||||||
|
private nextVersion: this = null;
|
||||||
protected readonly children: Array<InnerNode> = [];
|
|
||||||
|
|
||||||
get latestVersion(): this {
|
get latestVersion(): this {
|
||||||
let version;
|
let version;
|
||||||
|
|
@ -15,16 +13,6 @@ export abstract class InnerNode extends Node {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected constructor(parent: Node) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
new Promise(r => r()).then(() =>
|
|
||||||
parent.addChild({
|
|
||||||
value: this
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutatedUpdate() {
|
mutatedUpdate() {
|
||||||
this.parent.mutatedUpdate();
|
this.parent.mutatedUpdate();
|
||||||
}
|
}
|
||||||
|
|
@ -33,30 +21,20 @@ export abstract class InnerNode extends Node {
|
||||||
return this.update((self: this) => this.cloneWithMap.call(self, map));
|
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 {
|
changeKeys(props: { [propertyName: string]: any }): this {
|
||||||
return this.update((self: this) => this.cloneWithChangedKeys.call(self, props));
|
return this.update((self: this) => this.cloneWithChangedKeys.call(self, props));
|
||||||
}
|
}
|
||||||
|
|
||||||
changeValue({ oldValue, newValue }: { oldValue: any; newValue: any }): this {
|
addChild(update: { child: InnerNode }) {
|
||||||
return this.update((self: this) => this.cloneWithModify.call(self, { oldValue, newValue }));
|
|
||||||
}
|
|
||||||
|
|
||||||
addChild(update: { value: InnerNode }) {
|
|
||||||
super.addChild.call(this.latestVersion, update);
|
super.addChild.call(this.latestVersion, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeChild(update: { oldValue: InnerNode; newValue: InnerNode }) {
|
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 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 cloneWithChangedKeys(props: { [propertyName: string]: any }): this;
|
||||||
protected abstract cloneWithModify(update: { oldValue: any; newValue: any }): this;
|
|
||||||
|
|
||||||
private update(cloneMethod: (self: this) => this): this {
|
private update(cloneMethod: (self: this) => this): this {
|
||||||
if (this.nextVersion !== null) {
|
if (this.nextVersion !== null) {
|
||||||
|
|
@ -72,7 +50,7 @@ export abstract class InnerNode extends Node {
|
||||||
child.parent = clone;
|
child.parent = clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parent.changeChild({
|
this.parent.replaceChild({
|
||||||
oldValue: this,
|
oldValue: this,
|
||||||
newValue: clone
|
newValue: clone
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,32 @@
|
||||||
import { InnerNode } from './inner-node';
|
import { InnerNode } from './inner-node';
|
||||||
|
import { Unique } from './unique';
|
||||||
|
|
||||||
export abstract class Node {
|
export abstract class Node extends Unique {
|
||||||
protected static id = 0;
|
readonly children: Array<InnerNode>;
|
||||||
protected static sumCopyCount = 0;
|
// TODO: fix types.
|
||||||
protected abstract readonly children: Array<InnerNode>;
|
protected abstract changeKeys(props: any): this;
|
||||||
private id = Node.id++;
|
|
||||||
protected copyCount = 1;
|
|
||||||
|
|
||||||
abstract changeKey(update: { propertyName: string; value: any });
|
|
||||||
abstract changeValue(update: { oldValue: any; newValue: any });
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
Node.sumCopyCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract mutatedUpdate(): void;
|
abstract mutatedUpdate(): void;
|
||||||
|
|
||||||
addChild(update: { value: InnerNode }) {
|
private copyCount = 0;
|
||||||
this.changeValue({
|
|
||||||
oldValue: this.children,
|
protected initiate() {
|
||||||
newValue: [...this.children, update.value]
|
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) {
|
if (oldValue === newValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changeValue({
|
this.changeKeys({
|
||||||
oldValue: this.children,
|
children: this.children.map(c => (c === oldValue ? newValue : c))
|
||||||
newValue: this.children.map(c => (c === oldValue ? newValue : c))
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,6 +41,6 @@ export abstract class Node {
|
||||||
|
|
||||||
public log() {
|
public log() {
|
||||||
console.log(this._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
17
src/app/store/unique.ts
Normal 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue