Skip to content
Snippets Groups Projects
Select Git revision
  • ebf74e6580aa211e2fa384c5bd8b2998f5e72e5d
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

state.ts

Blame
  • user avatar
    David Sehnal authored
    7a838d13
    History
    state.ts 6.29 KiB
    /**
     * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author David Sehnal <david.sehnal@gmail.com>
     */
    
    import { State } from 'mol-state';
    import { PluginStateObject as SO } from './state/objects';
    import { Camera } from 'mol-canvas3d/camera';
    import { PluginBehavior } from './behavior';
    import { CameraSnapshotManager } from './state/camera';
    import { PluginStateSnapshotManager } from './state/snapshots';
    import { RxEventHelper } from 'mol-util/rx-event-helper';
    import { Canvas3DProps } from 'mol-canvas3d/canvas3d';
    import { PluginCommands } from './command';
    import { PluginAnimationManager } from './state/animation/manager';
    import { ParamDefinition as PD } from 'mol-util/param-definition';
    import { UUID } from 'mol-util';
    export { PluginState }
    
    class PluginState {
        private ev = RxEventHelper.create();
    
        readonly dataState: State;
        readonly behaviorState: State;
        readonly animation: PluginAnimationManager;
        readonly cameraSnapshots = new CameraSnapshotManager();
        readonly snapshots: PluginStateSnapshotManager;
    
        readonly behavior = {
            kind: this.ev.behavior<PluginState.Kind>('data'),
            currentObject: this.ev.behavior<State.ObjectEvent>({} as any)
        }
    
        setKind(kind: PluginState.Kind) {
            const current = this.behavior.kind.value;
            if (kind !== current) {
                this.behavior.kind.next(kind);
                this.behavior.currentObject.next(kind === 'data'
                    ? this.dataState.behaviors.currentObject.value
                    : this.behaviorState.behaviors.currentObject.value)
            }
        }
    
        getSnapshot(params?: PluginState.GetSnapshotParams): PluginState.Snapshot {
            const p = { ...PluginState.DefaultGetSnapshotParams, ...params };
            console.log(p.animation, this.animation.getSnapshot());
            return {
                id: UUID.create22(),
                data: p.data ? this.dataState.getSnapshot() : void 0,
                behaviour: p.behavior ? this.behaviorState.getSnapshot() : void 0,
                animation: p.animation ? this.animation.getSnapshot() : void 0,
                camera: p.camera ? {
                    current: this.plugin.canvas3d.camera.getSnapshot(),
                    transitionStyle: p.cameraTranstion.name,
                    transitionDurationInMs: (params && params.cameraTranstion && params.cameraTranstion.name === 'animate' && params.cameraTranstion.params.durationInMs) || void 0
                } : void 0,
                cameraSnapshots: p.cameraSnapshots ? this.cameraSnapshots.getStateSnapshot() : void 0,
                canvas3d: p.canvas3d ? {
                    props: this.plugin.canvas3d.props
                } : void 0,
                durationInMs: params && params.durationInMs
            };
        }
    
        async setSnapshot(snapshot: PluginState.Snapshot) {
            this.animation.stop();
    
            if (snapshot.behaviour) await this.plugin.runTask(this.behaviorState.setSnapshot(snapshot.behaviour));
            if (snapshot.data) await this.plugin.runTask(this.dataState.setSnapshot(snapshot.data));
            if (snapshot.canvas3d) {
                if (snapshot.canvas3d.props) await PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: snapshot.canvas3d.props || { } });
            }
            if (snapshot.cameraSnapshots) this.cameraSnapshots.setStateSnapshot(snapshot.cameraSnapshots);
            if (snapshot.animation) {
                this.animation.setSnapshot(snapshot.animation);
            }
            if (snapshot.camera) {
                await PluginCommands.Camera.SetSnapshot.dispatch(this.plugin, {
                    snapshot: snapshot.camera.current,
                    durationMs: snapshot.camera.transitionStyle === 'animate'
                        ? snapshot.camera.transitionDurationInMs
                        : void 0
                });
            }
        }
    
        dispose() {
            this.ev.dispose();
            this.dataState.dispose();
            this.behaviorState.dispose();
            this.cameraSnapshots.dispose();
            this.animation.dispose();
        }
    
        constructor(private plugin: import('./context').PluginContext) {
            this.snapshots = new PluginStateSnapshotManager(plugin);
            this.dataState = State.create(new SO.Root({ }), { globalContext: plugin });
            this.behaviorState = State.create(new PluginBehavior.Root({ }), { globalContext: plugin, rootProps: { isLocked: true } });
    
            this.dataState.behaviors.currentObject.subscribe(o => {
                if (this.behavior.kind.value === 'data') this.behavior.currentObject.next(o);
            });
            this.behaviorState.behaviors.currentObject.subscribe(o => {
                if (this.behavior.kind.value === 'behavior') this.behavior.currentObject.next(o);
            });
    
            this.behavior.currentObject.next(this.dataState.behaviors.currentObject.value);
    
            this.animation = new PluginAnimationManager(plugin);
        }
    }
    
    namespace PluginState {
        export type Kind = 'data' | 'behavior'
    
        export type CameraTransitionStyle = 'instant' | 'animate'
        export const GetSnapshotParams = {
            durationInMs: PD.Numeric(1500, { min: 100, max: 15000, step: 100 }, { label: 'Duration in ms' }),
            data: PD.Boolean(true),
            behavior: PD.Boolean(false),
            animation: PD.Boolean(true),
            canvas3d: PD.Boolean(true),
            camera: PD.Boolean(true),
            // TODO: make camera snapshots same as the StateSnapshots with "child states?"
            cameraSnapshots: PD.Boolean(false),
            cameraTranstion: PD.MappedStatic('animate', {
                animate: PD.Group({
                    durationInMs: PD.Numeric(250, { min: 100, max: 5000, step: 500 }, { label: 'Duration in ms' }),
                }),
                instant: PD.Group({ })
            }, { options: [['animate', 'Animate'], ['instant', 'Instant']] })
        };
        export type GetSnapshotParams = Partial<PD.Values<typeof GetSnapshotParams>>
        export const DefaultGetSnapshotParams = PD.getDefaultValues(GetSnapshotParams);
    
        export interface Snapshot {
            id: UUID,
            data?: State.Snapshot,
            behaviour?: State.Snapshot,
            animation?: PluginAnimationManager.Snapshot,
            camera?: {
                current: Camera.Snapshot,
                transitionStyle: CameraTransitionStyle,
                transitionDurationInMs?: number
            },
            cameraSnapshots?: CameraSnapshotManager.StateSnapshot,
            canvas3d?: {
                props?: Canvas3DProps
            },
            durationInMs?: number
        }
    }