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

mol-state: Action builder

parent cfeb2003
No related branches found
No related tags found
No related merge requests found
......@@ -81,13 +81,14 @@ const DownloadStructure = StateAction.create<PluginStateObject.Root, void, Downl
}
});
export const OpenStructure = StateAction.create<PluginStateObject.Root, void, { file: File }>({
from: [PluginStateObject.Root],
export const OpenStructure = StateAction.build({
from: PluginStateObject.Root,
params: { file: PD.File({ accept: '.cif,.bcif' }) }
})({
display: {
name: 'Open Structure',
description: 'Load a structure from file and create its default Assembly and visual'
},
params: () => ({ file: PD.File({ accept: '.cif,.bcif' }) }),
apply({ params, state }) {
const b = state.build();
const data = b.toRoot().apply(StateTransforms.Data.ReadFile, { file: params.file, isBinary: /\.bcif$/i.test(params.file.name) });
......@@ -130,8 +131,9 @@ function complexRepresentation(root: StateTreeBuilder.To<PluginStateObject.Molec
// TODO: create spheres visual
}
export const CreateComplexRepresentation = StateAction.create<PluginStateObject.Molecule.Structure, void, {}>({
from: [PluginStateObject.Molecule.Structure],
export const CreateComplexRepresentation = StateAction.build({
from: PluginStateObject.Molecule.Structure
})({
display: {
name: 'Create Complex',
description: 'Split the structure into Sequence/Water/Ligands/... '
......@@ -143,15 +145,15 @@ export const CreateComplexRepresentation = StateAction.create<PluginStateObject.
}
});
export const UpdateTrajectory = StateAction.create<PluginStateObject.Root, void, { action: 'advance' | 'reset', by?: number }>({
from: [],
export const UpdateTrajectory = StateAction.build({
params: () => ({
action: PD.Select<'advance' | 'reset'>('advance', [['advance', 'Advance'], ['reset', 'Reset']]),
by: PD.makeOptional(PD.Numeric(1, { min: -1, max: 1, step: 1 }))
})
})({
display: {
name: 'Update Trajectory'
},
params: () => ({
action: PD.Select('advance', [['advance', 'Advance'], ['reset', 'Reset']]),
by: PD.Numeric(1, { min: -1, max: 1, step: 1 }, { isOptional: true })
}),
apply({ params, state }) {
const models = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Model)
.filter(c => c.transform.transformer === StateTransforms.Model.ModelFromTrajectory));
......
......@@ -38,8 +38,7 @@ namespace StateAction {
params: P
}
export interface Definition<A extends StateObject = StateObject, T = any, P extends {} = {}> {
readonly from: StateObject.Ctor[],
export interface DefinitionBase<A extends StateObject = StateObject, T = any, P extends {} = {}> {
readonly display?: { readonly name: string, readonly description?: string },
/**
......@@ -47,12 +46,15 @@ namespace StateAction {
*/
apply(params: ApplyParams<A, P>, globalCtx: unknown): T | Task<T>,
params?(a: A, globalCtx: unknown): { [K in keyof P]: PD.Any },
/** Test if the transform can be applied to a given node */
isApplicable?(a: A, globalCtx: unknown): boolean
}
export interface Definition<A extends StateObject = StateObject, T = any, P extends {} = {}> extends DefinitionBase<A, T, P> {
readonly from: StateObject.Ctor[],
params?(a: A, globalCtx: unknown): { [K in keyof P]: PD.Any }
}
export function create<A extends StateObject, T, P extends {} = {}>(definition: Definition<A, T, P>): StateAction<A, T, P> {
const action: StateAction<A, T, P> = {
create(params) { return { action, params }; },
......@@ -74,4 +76,43 @@ namespace StateAction {
}
})
}
export namespace Builder {
type ParamDefinition<P> = { [K in keyof P]-?: PD.Base<P[K]> }
export interface Type<A extends StateObject.Ctor, P extends { }> {
from?: A | A[],
params?: ParamDefinition<P> | ((a: StateObject.From<A>, globalCtx: any) => ParamDefinition<P>)
}
export interface Root {
<A extends StateObject.Ctor, P extends { }>(info: Type<A, P>): Define<StateObject.From<A>, Params<P>>
}
type Optionals<P> = { [K in keyof P]-?: undefined extends P[K] ? K : never }[keyof P]
type NonOptionals<P> = { [K in keyof P]-?: undefined extends P[K] ? never: K }[keyof P]
type Params<P> = Pick<P, NonOptionals<P>> & Partial<Pick<P, Optionals<P>>>
export interface Define<A extends StateObject, P> {
<T>(def: DefinitionBase<A, T, P>): StateAction<A, T, P>
}
function root(info: Type<any, any>): Define<any, any> {
return def => create({
from: info.from instanceof Array
? info.from
: !!info.from ? [info.from] : [],
params: typeof info.params === 'object'
? () => info.params as any
: !!info.params
? info.params as any
: void 0,
...def
});
}
export const build: Root = (info: any) => root(info);
}
export const build = Builder.build;
}
\ No newline at end of file
......@@ -15,19 +15,18 @@ export namespace ParamDefinition {
label?: string,
description?: string,
isHidden?: boolean,
isOptional?: boolean,
}
function setInfo<T extends Info>(param: T, info?: Info): T {
if (!info) return param;
if (info.description) param.description = info.description;
if (info.label) param.label = info.label;
if (info.isOptional) param.isOptional = info.isOptional;
if (info.isHidden) param.isHidden = info.isHidden;
return param;
}
export interface Base<T> extends Info {
isOptional?: boolean,
defaultValue: T
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment