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

mol-state: coarser StateAction syntax

parent ec1dc600
Branches
Tags
No related merge requests found
...@@ -60,7 +60,7 @@ const DownloadStructure = StateAction.create<PluginStateObject.Root, void, Downl ...@@ -60,7 +60,7 @@ const DownloadStructure = StateAction.create<PluginStateObject.Root, void, Downl
description: 'Load a structure from PDBe and create its default Assembly and visual' description: 'Load a structure from PDBe and create its default Assembly and visual'
}, },
params: () => ({ source: PD.Mapped('bcif-static', ObtainStructureHelpers.SourceOptions, ObtainStructureHelpers.getControls) }), params: () => ({ source: PD.Mapped('bcif-static', ObtainStructureHelpers.SourceOptions, ObtainStructureHelpers.getControls) }),
apply({ params, state }) { run({ params, state }) {
const b = state.build(); const b = state.build();
// const query = MolScriptBuilder.struct.generator.atomGroups({ // const query = MolScriptBuilder.struct.generator.atomGroups({
...@@ -85,12 +85,10 @@ export const OpenStructure = StateAction.build({ ...@@ -85,12 +85,10 @@ export const OpenStructure = StateAction.build({
display: { name: 'Open Structure', description: 'Load a structure from file and create its default Assembly and visual' }, display: { name: 'Open Structure', description: 'Load a structure from file and create its default Assembly and visual' },
from: PluginStateObject.Root, from: PluginStateObject.Root,
params: { file: PD.File({ accept: '.cif,.bcif' }) } params: { file: PD.File({ accept: '.cif,.bcif' }) }
})({ })(({ params, state }) => {
apply({ params, state }) { const b = state.build();
const b = state.build(); const data = b.toRoot().apply(StateTransforms.Data.ReadFile, { file: params.file, isBinary: /\.bcif$/i.test(params.file.name) });
const data = b.toRoot().apply(StateTransforms.Data.ReadFile, { file: params.file, isBinary: /\.bcif$/i.test(params.file.name) }); return state.update(createStructureTree(data));
return state.update(createStructureTree(data));
}
}); });
function createStructureTree(b: StateTreeBuilder.To<PluginStateObject.Data.Binary | PluginStateObject.Data.String>): StateTree { function createStructureTree(b: StateTreeBuilder.To<PluginStateObject.Data.Binary | PluginStateObject.Data.String>): StateTree {
...@@ -125,18 +123,16 @@ function complexRepresentation(root: StateTreeBuilder.To<PluginStateObject.Molec ...@@ -125,18 +123,16 @@ function complexRepresentation(root: StateTreeBuilder.To<PluginStateObject.Molec
sizeTheme: { name: 'uniform', params: PD.getDefaultValues(UniformSizeThemeParams) }, sizeTheme: { name: 'uniform', params: PD.getDefaultValues(UniformSizeThemeParams) },
}) })
root.apply(StateTransforms.Model.StructureComplexElement, { type: 'spheres' }); root.apply(StateTransforms.Model.StructureComplexElement, { type: 'spheres' });
// TODO: create spheres visual // TODO: create spheres visual
} }
export const CreateComplexRepresentation = StateAction.build({ export const CreateComplexRepresentation = StateAction.build({
display: { name: 'Create Complex', description: 'Split the structure into Sequence/Water/Ligands/... ' }, display: { name: 'Create Complex', description: 'Split the structure into Sequence/Water/Ligands/... ' },
from: PluginStateObject.Molecule.Structure from: PluginStateObject.Molecule.Structure
})({ })(({ ref, state }) => {
apply({ ref, state }) { const root = state.build().to(ref);
const root = state.build().to(ref); complexRepresentation(root);
complexRepresentation(root); return state.update(root.getTree());
return state.update(root.getTree());
}
}); });
export const UpdateTrajectory = StateAction.build({ export const UpdateTrajectory = StateAction.build({
...@@ -145,32 +141,30 @@ export const UpdateTrajectory = StateAction.build({ ...@@ -145,32 +141,30 @@ export const UpdateTrajectory = StateAction.build({
action: PD.Select<'advance' | 'reset'>('advance', [['advance', 'Advance'], ['reset', 'Reset']]), action: PD.Select<'advance' | 'reset'>('advance', [['advance', 'Advance'], ['reset', 'Reset']]),
by: PD.makeOptional(PD.Numeric(1, { min: -1, max: 1, step: 1 })) by: PD.makeOptional(PD.Numeric(1, { min: -1, max: 1, step: 1 }))
} }
})({ })(({ params, state }) => {
apply({ params, state }) { const models = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Model)
const models = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Model) .filter(c => c.transform.transformer === StateTransforms.Model.ModelFromTrajectory));
.filter(c => c.transform.transformer === StateTransforms.Model.ModelFromTrajectory));
const update = state.build();
const update = state.build();
if (params.action === 'reset') {
for (const m of models) {
update.to(m.transform.ref).update(StateTransforms.Model.ModelFromTrajectory,
() => ({ modelIndex: 0 }));
}
} else {
for (const m of models) {
const parent = StateSelection.findAncestorOfType(state.tree, state.cells, m.transform.ref, [PluginStateObject.Molecule.Trajectory]);
if (!parent || !parent.obj) continue;
const traj = parent.obj as PluginStateObject.Molecule.Trajectory;
update.to(m.transform.ref).update(StateTransforms.Model.ModelFromTrajectory,
old => {
let modelIndex = (old.modelIndex + params.by!) % traj.data.length;
if (modelIndex < 0) modelIndex += traj.data.length;
return { modelIndex };
});
}
}
return state.update(update); if (params.action === 'reset') {
for (const m of models) {
update.to(m.transform.ref).update(StateTransforms.Model.ModelFromTrajectory,
() => ({ modelIndex: 0 }));
}
} else {
for (const m of models) {
const parent = StateSelection.findAncestorOfType(state.tree, state.cells, m.transform.ref, [PluginStateObject.Molecule.Trajectory]);
if (!parent || !parent.obj) continue;
const traj = parent.obj as PluginStateObject.Molecule.Trajectory;
update.to(m.transform.ref).update(StateTransforms.Model.ModelFromTrajectory,
old => {
let modelIndex = (old.modelIndex + params.by!) % traj.data.length;
if (modelIndex < 0) modelIndex += traj.data.length;
return { modelIndex };
});
}
} }
return state.update(update);
}); });
\ No newline at end of file
...@@ -42,7 +42,7 @@ namespace StateAction { ...@@ -42,7 +42,7 @@ namespace StateAction {
/** /**
* Apply an action that modifies the State specified in Params. * Apply an action that modifies the State specified in Params.
*/ */
apply(params: ApplyParams<A, P>, globalCtx: unknown): T | Task<T>, run(params: ApplyParams<A, P>, globalCtx: unknown): T | Task<T>,
/** Test if the transform can be applied to a given node */ /** Test if the transform can be applied to a given node */
isApplicable?(a: A, globalCtx: unknown): boolean isApplicable?(a: A, globalCtx: unknown): boolean
...@@ -69,7 +69,7 @@ namespace StateAction { ...@@ -69,7 +69,7 @@ namespace StateAction {
from: def.from, from: def.from,
display: def.display, display: def.display,
params: def.params as Transformer.Definition<Transformer.From<T>, any, Transformer.Params<T>>['params'], params: def.params as Transformer.Definition<Transformer.From<T>, any, Transformer.Params<T>>['params'],
apply({ cell, state, params }) { run({ cell, state, params }) {
const tree = state.build().to(cell.transform.ref).apply(transformer, params); const tree = state.build().to(cell.transform.ref).apply(transformer, params);
return state.update(tree); return state.update(tree);
} }
...@@ -88,7 +88,7 @@ namespace StateAction { ...@@ -88,7 +88,7 @@ namespace StateAction {
} }
export interface Define<A extends StateObject, P> { export interface Define<A extends StateObject, P> {
<T>(def: DefinitionBase<A, T, P>): StateAction<A, T, P>, <T>(def: DefinitionBase<A, T, P> | DefinitionBase<A, T, P>['run']): StateAction<A, T, P>,
} }
function root(info: Type<any, any>): Define<any, any> { function root(info: Type<any, any>): Define<any, any> {
...@@ -106,7 +106,9 @@ namespace StateAction { ...@@ -106,7 +106,9 @@ namespace StateAction {
: !!info.params : !!info.params
? info.params as any ? info.params as any
: void 0, : void 0,
...def ...(typeof def === 'function'
? { run: def }
: def)
}); });
} }
......
...@@ -104,7 +104,7 @@ class State { ...@@ -104,7 +104,7 @@ class State {
if (!cell) throw new Error(`'${ref}' does not exist.`); if (!cell) throw new Error(`'${ref}' does not exist.`);
if (cell.status !== 'ok') throw new Error(`Action cannot be applied to a cell with status '${cell.status}'`); if (cell.status !== 'ok') throw new Error(`Action cannot be applied to a cell with status '${cell.status}'`);
return runTask(action.definition.apply({ ref, cell, a: cell.obj!, params, state: this }, this.globalContext), ctx); return runTask(action.definition.run({ ref, cell, a: cell.obj!, params, state: this }, this.globalContext), ctx);
}); });
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment