Skip to content
Snippets Groups Projects
Commit 05b8abc2 authored by David Sehnal's avatar David Sehnal
Browse files

mol-state: added Transform.tag, refactoring

parent e958ae17
No related branches found
No related tags found
No related merge requests found
......@@ -91,21 +91,24 @@ export class _test_CreateTransform extends React.Component<{ plugin: PluginConte
}
export class _test_UpdateTransform extends React.Component<{ plugin: PluginContext, state: State, nodeRef: Transform.Ref }, { params: any }> {
private getTransform() {
return this.props.state.tree.nodes.get(this.props.nodeRef)!;
private getCell(ref?: string) {
return this.props.state.cells.get(ref || this.props.nodeRef)!;
}
private getParamDef() {
const def = this.getTransform().transformer.definition;
if (!def.params || !def.params.controls) return void 0;
const src = this.props.state.select(q => q.byRef(this.props.nodeRef).ancestorOfType(def.from))[0];
// StateSelection.ancestorOfType(this.props.nodeRef, def.from).select(this.props.plugin.state.data)[0];
private getDefParams() {
const cell = this.getCell();
if (!cell) return { };
return cell.transform.params;
}
console.log(src, def.from);
private getParamDef() {
const cell = this.getCell();
const def = cell.transform.transformer.definition;
if (!cell.sourceRef || !def.params || !def.params.controls) return void 0;
const src = this.getCell(cell.sourceRef);
if (!src || !src.obj) return void 0;
return def.params.controls(src.obj, this.props.plugin);
}
......@@ -119,10 +122,11 @@ export class _test_UpdateTransform extends React.Component<{ plugin: PluginConte
// if (t) this.setState({ params: t.value.params });
// }
state = { params: this.getTransform() ? this.getTransform().params : { } };
state = { params: this.getDefParams() };
render() {
const transform = this.getTransform();
const cell = this.getCell();
const transform = cell.transform;
if (!transform || transform.ref === Transform.RootRef) {
return <div />;
}
......
......@@ -36,12 +36,14 @@ namespace StateObject {
}
interface StateObjectCell {
ref: Transform.Ref,
transform: Transform,
// Which object was used as a parent to create data in this cell
sourceRef: Transform.Ref | undefined,
version: string
status: StateObjectCell.Status,
state: unknown,
errorText?: string,
obj?: StateObject
}
......
......@@ -109,11 +109,11 @@ class State {
const root = tree.root;
(this.cells as Map<Transform.Ref, StateObjectCell>).set(root.ref, {
ref: root.ref,
transform: root,
sourceRef: void 0,
obj: rootObject,
status: 'ok',
version: root.version,
state: { ...StateObjectCell.DefaultState }
version: root.version
});
this.globalContext = params && params.globalContext;
......@@ -216,11 +216,11 @@ function _initCellsVisitor(transform: Transform, _: any, ctx: UpdateContext) {
if (ctx.cells.has(transform.ref)) return;
const obj: StateObjectCell = {
ref: transform.ref,
transform,
sourceRef: void 0,
status: 'pending',
version: UUID.create(),
errorText: void 0,
state: { ...StateObjectCell.DefaultState, ...transform.cellState }
errorText: void 0
};
ctx.cells.set(transform.ref, obj);
......@@ -250,15 +250,16 @@ function doError(ctx: UpdateContext, ref: Ref, errorText: string) {
}
}
function findAncestor(tree: StateTree, cells: State.Cells, root: Ref, types: { type: StateObject.Type }[]): StateObject {
function findAncestor(tree: StateTree, cells: State.Cells, root: Ref, types: { type: StateObject.Type }[]): StateObjectCell | undefined {
let current = tree.nodes.get(root)!;
while (true) {
current = tree.nodes.get(current.parent)!;
const cell = cells.get(current.ref)!;
if (!cell.obj) return void 0;
for (const t of types) if (cell.obj.type === t.type) return cells.get(current.ref)!;
if (current.ref === Transform.RootRef) {
return cells.get(Transform.RootRef)!.obj!;
return void 0;
}
const obj = cells.get(current.ref)!.obj!;
for (const t of types) if (obj.type === t.type) return cells.get(current.ref)!.obj!;
}
}
......@@ -289,23 +290,30 @@ async function updateSubtree(ctx: UpdateContext, root: Ref) {
}
async function updateNode(ctx: UpdateContext, currentRef: Ref) {
const { oldTree, tree, cells } = ctx;
const { oldTree, tree } = ctx;
const transform = tree.nodes.get(currentRef);
const parent = findAncestor(tree, cells, currentRef, transform.transformer.definition.from);
const parentCell = findAncestor(tree, ctx.cells, currentRef, transform.transformer.definition.from);
if (!parentCell) {
throw new Error(`No suitable parent found for '${currentRef}'`);
}
const parent = parentCell.obj!;
const current = ctx.cells.get(currentRef)!;
current.sourceRef = parentCell.transform.ref;
// console.log('parent', transform.transformer.id, transform.transformer.definition.from[0].type, parent ? parent.ref : 'undefined')
if (!oldTree.nodes.has(currentRef) || !cells.has(currentRef)) {
if (!oldTree.nodes.has(currentRef)) {
// console.log('creating...', transform.transformer.id, oldTree.nodes.has(currentRef), objects.has(currentRef));
const obj = await createObject(ctx, currentRef, transform.transformer, parent, transform.params);
const cell = cells.get(currentRef)!;
cell.obj = obj;
cell.version = transform.version;
current.obj = obj;
current.version = transform.version;
return { action: 'created', obj };
} else {
const current = cells.get(currentRef)!;
const oldParams = oldTree.nodes.get(currentRef)!.params;
const updateKind = current.status === 'ok' || current.ref === Transform.RootRef
const updateKind = current.status === 'ok' || current.transform.ref === Transform.RootRef
? await updateObject(ctx, currentRef, transform.transformer, parent, current.obj!, oldParams, transform.params)
: Transformer.UpdateResult.Recreate;
......
......@@ -123,8 +123,8 @@ namespace StateSelection {
const set = new Set<string>();
const ret: StateObjectCell[] = [];
for (const n of q(state)) {
if (!set.has(n.ref)) {
set.add(n.ref);
if (!set.has(n.transform.ref)) {
set.add(n.transform.ref);
ret.push(n);
}
}
......@@ -151,7 +151,7 @@ namespace StateSelection {
export function subtree(b: Selector) {
return flatMap(b, (n, s) => {
const nodes = [] as string[];
StateTree.doPreOrder(s.tree, s.tree.nodes.get(n.ref), nodes, (x, _, ctx) => { ctx.push(x.ref) });
StateTree.doPreOrder(s.tree, s.tree.nodes.get(n.transform.ref), nodes, (x, _, ctx) => { ctx.push(x.ref) });
return nodes.map(x => s.cells.get(x)!);
});
}
......@@ -160,7 +160,7 @@ namespace StateSelection {
export function children(b: Selector) {
return flatMap(b, (n, s) => {
const nodes: StateObjectCell[] = [];
s.tree.children.get(n.ref).forEach(c => nodes.push(s.cells.get(c!)!));
s.tree.children.get(n.transform.ref).forEach(c => nodes.push(s.cells.get(c!)!));
return nodes;
});
}
......@@ -169,10 +169,10 @@ namespace StateSelection {
export function ofType(b: Selector, t: StateObject.Type) { return filter(b, n => n.obj ? n.obj.type === t : false); }
registerModifier('ancestorOfType', ancestorOfType);
export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s, n.ref, types))); }
export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s, n.transform.ref, types))); }
registerModifier('parent', parent);
export function parent(b: Selector) { return unique(mapEntity(b, (n, s) => s.cells.get(s.tree.nodes.get(n.ref)!.parent))); }
export function parent(b: Selector) { return unique(mapEntity(b, (n, s) => s.cells.get(s.tree.nodes.get(n.transform.ref)!.parent))); }
function findAncestorOfType({ tree, cells }: State, root: string, types: StateObject.Ctor[]): StateObjectCell | undefined {
let current = tree.nodes.get(root)!, len = types.length;
......
......@@ -14,7 +14,8 @@ export interface Transform<A extends StateObject = StateObject, B extends StateO
readonly params: P,
readonly ref: Transform.Ref,
readonly version: string,
readonly cellState?: Partial<StateObjectCell.State>
readonly cellState?: Partial<StateObjectCell.State>,
readonly tag?: string
}
export namespace Transform {
......@@ -22,7 +23,7 @@ export namespace Transform {
export const RootRef = '-=root=-' as Ref;
export interface Options { ref?: Ref, cellState?: Partial<StateObjectCell.State> }
export interface Options { ref?: Ref, tag?: string, cellState?: Partial<StateObjectCell.State> }
export function create<A extends StateObject, B extends StateObject, P>(parent: Ref, transformer: Transformer<A, B, P>, params?: P, options?: Options): Transform<A, B, P> {
const ref = options && options.ref ? options.ref : UUID.create() as string as Ref;
......@@ -32,7 +33,8 @@ export namespace Transform {
params: params || {} as any,
ref,
version: UUID.create(),
cellState: options && options.cellState
cellState: options && options.cellState,
tag: options && options.tag
}
}
......@@ -50,7 +52,8 @@ export namespace Transform {
params: any,
ref: string,
version: string,
cellState?: Partial<StateObjectCell.State>
cellState?: Partial<StateObjectCell.State>,
tag?: string
}
function _id(x: any) { return x; }
......@@ -64,7 +67,8 @@ export namespace Transform {
params: pToJson(t.params),
ref: t.ref,
version: t.version,
cellState: t.cellState
cellState: t.cellState,
tag: t.tag
};
}
......@@ -79,7 +83,8 @@ export namespace Transform {
params: pFromJson(t.params),
ref: t.ref as Ref,
version: t.version,
cellState: t.cellState
cellState: t.cellState,
tag: t.tag
};
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment