state.ts 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import { State } from 'mol-state';
  7. import { PluginStateObject as SO } from './state/objects';
  8. import { Camera } from 'mol-canvas3d/camera';
  9. import { PluginBehavior } from './behavior';
  10. import { CameraSnapshotManager } from './state/camera';
  11. import { PluginStateSnapshotManager } from './state/snapshots';
  12. import { RxEventHelper } from 'mol-util/rx-event-helper';
  13. import { Canvas3DParams } from 'mol-canvas3d/canvas3d';
  14. import { PluginCommands } from './command';
  15. export { PluginState }
  16. class PluginState {
  17. private ev = RxEventHelper.create();
  18. readonly dataState: State;
  19. readonly behaviorState: State;
  20. readonly cameraSnapshots = new CameraSnapshotManager();
  21. readonly snapshots = new PluginStateSnapshotManager();
  22. readonly behavior = {
  23. kind: this.ev.behavior<PluginState.Kind>('data'),
  24. currentObject: this.ev.behavior<State.ObjectEvent>({} as any)
  25. }
  26. setKind(kind: PluginState.Kind) {
  27. const current = this.behavior.kind.value;
  28. if (kind !== current) {
  29. this.behavior.kind.next(kind);
  30. this.behavior.currentObject.next(kind === 'data'
  31. ? this.dataState.behaviors.currentObject.value
  32. : this.behaviorState.behaviors.currentObject.value)
  33. }
  34. }
  35. getSnapshot(): PluginState.Snapshot {
  36. return {
  37. data: this.dataState.getSnapshot(),
  38. behaviour: this.behaviorState.getSnapshot(),
  39. cameraSnapshots: this.cameraSnapshots.getStateSnapshot(),
  40. canvas3d: {
  41. camera: this.plugin.canvas3d.camera.getSnapshot(),
  42. viewport: this.plugin.canvas3d.props
  43. }
  44. };
  45. }
  46. async setSnapshot(snapshot: PluginState.Snapshot) {
  47. await this.plugin.runTask(this.behaviorState.setSnapshot(snapshot.behaviour));
  48. await this.plugin.runTask(this.dataState.setSnapshot(snapshot.data));
  49. PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: snapshot.canvas3d.viewport || { } });
  50. this.cameraSnapshots.setStateSnapshot(snapshot.cameraSnapshots);
  51. this.plugin.canvas3d.camera.setState(snapshot.canvas3d.camera);
  52. this.plugin.canvas3d.requestDraw(true);
  53. }
  54. dispose() {
  55. this.ev.dispose();
  56. this.dataState.dispose();
  57. this.behaviorState.dispose();
  58. this.cameraSnapshots.dispose();
  59. }
  60. constructor(private plugin: import('./context').PluginContext) {
  61. this.dataState = State.create(new SO.Root({ }), { globalContext: plugin });
  62. this.behaviorState = State.create(new PluginBehavior.Root({ }), { globalContext: plugin });
  63. this.dataState.behaviors.currentObject.subscribe(o => {
  64. if (this.behavior.kind.value === 'data') this.behavior.currentObject.next(o);
  65. });
  66. this.behaviorState.behaviors.currentObject.subscribe(o => {
  67. if (this.behavior.kind.value === 'behavior') this.behavior.currentObject.next(o);
  68. });
  69. this.behavior.currentObject.next(this.dataState.behaviors.currentObject.value);
  70. }
  71. }
  72. namespace PluginState {
  73. export type Kind = 'data' | 'behavior'
  74. export interface Snapshot {
  75. data: State.Snapshot,
  76. behaviour: State.Snapshot,
  77. cameraSnapshots: CameraSnapshotManager.StateSnapshot,
  78. canvas3d: {
  79. camera: Camera.Snapshot,
  80. viewport: Canvas3DParams
  81. }
  82. }
  83. }