diff --git a/src/mol-state/state/builder.ts b/src/mol-state/state/builder.ts index 57e266f55d30ba18361e2dd955137382169884ca..ec0bab0c3c2e4c245a4c614b39d4fd912adc736a 100644 --- a/src/mol-state/state/builder.ts +++ b/src/mol-state/state/builder.ts @@ -69,6 +69,27 @@ namespace StateBuilder { return new To(this.state, t.ref, this.root); } + /** + * Inserts a new transform that does not change the object type and move the original children to it. + */ + insert<T extends StateTransformer<A, A, any>>(tr: T, params?: StateTransformer.Params<T>, options?: Partial<StateTransform.Options>, initialCellState?: Partial<StateObjectCell.State>): To<StateTransformer.To<T>> { + // cache the children + const children = this.state.tree.children.get(this.ref).toArray(); + + // add the new node + const t = tr.apply(this.ref, params, options); + this.state.tree.add(t, initialCellState); + + // move the original children to the new node + for (const c of children) { + this.state.tree.changeParent(c, t.ref); + } + + this.editInfo.count++; + this.editInfo.lastUpdate = t.ref; + return new To(this.state, t.ref, this.root); + } + update<T extends StateTransformer<any, A, any>>(transformer: T, params: (old: StateTransformer.Params<T>) => StateTransformer.Params<T>): Root update(params: any): Root update<T extends StateTransformer<any, A, any>>(paramsOrTransformer: T, provider?: (old: StateTransformer.Params<T>) => StateTransformer.Params<T>) { diff --git a/src/mol-state/transform.ts b/src/mol-state/transform.ts index d4acdb81a2a1a8bec45b3d4e44cccd5024518a18..57e104f3bcdd5447aead6af0e1bc46e2235d3036 100644 --- a/src/mol-state/transform.ts +++ b/src/mol-state/transform.ts @@ -48,10 +48,14 @@ namespace Transform { } } - export function withParams<T>(t: Transform, params: any): Transform { + export function withParams(t: Transform, params: any): Transform { return { ...t, params, version: UUID.create22() }; } + export function withParent(t: Transform, parent: Ref): Transform { + return { ...t, parent, version: UUID.create22() }; + } + export function createRoot(props?: Props): Transform { return create(RootRef, StateTransformer.ROOT, {}, { ref: RootRef, props }); } diff --git a/src/mol-state/tree/transient.ts b/src/mol-state/tree/transient.ts index 66a6472937d33dd796f7b12b1dc438a81dcb0994..cb75faae3a95cc200d1f18b18a2300a8622895bc 100644 --- a/src/mol-state/tree/transient.ts +++ b/src/mol-state/tree/transient.ts @@ -90,6 +90,14 @@ class TransientTree implements StateTree { this.childMutations.set(parent, set); } + changeParent(ref: StateTransform.Ref, newParent: StateTransform.Ref) { + ensurePresent(this.transforms, ref); + + const old = this.transforms.get(ref); + this.removeChild(old.parent, ref); + this.addChild(newParent, ref); + } + add(transform: StateTransform, initialState?: Partial<StateObjectCell.State>) { const ref = transform.ref;