context.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 { Transformer, Transform, State } from 'mol-state';
  7. import { Canvas3D } from 'mol-canvas3d/canvas3d';
  8. import { StateTransforms } from './state/transforms';
  9. import { PluginStateObject as SO } from './state/objects';
  10. import { RxEventHelper } from 'mol-util/rx-event-helper';
  11. import { PluginState } from './state';
  12. import { PluginCommand, PluginCommands } from './command';
  13. import { Task } from 'mol-task';
  14. import { merge } from 'rxjs';
  15. import { PluginBehaviors, BuiltInPluginBehaviors } from './behavior';
  16. import { Loci, EmptyLoci } from 'mol-model/loci';
  17. import { Representation } from 'mol-repr';
  18. import { CreateStructureFromPDBe } from './state/actions/basic';
  19. export class PluginContext {
  20. private disposed = false;
  21. private ev = RxEventHelper.create();
  22. readonly state = new PluginState(this);
  23. readonly commands = new PluginCommand.Manager();
  24. readonly events = {
  25. state: {
  26. data: this.state.data.events,
  27. behavior: this.state.behavior.events,
  28. cameraSnapshots: this.state.cameraSnapshots.events,
  29. snapshots: this.state.snapshots.events,
  30. }
  31. };
  32. readonly behaviors = {
  33. state: {
  34. data: this.state.data.behaviors,
  35. behavior: this.state.behavior.behaviors
  36. },
  37. canvas: {
  38. highlightLoci: this.ev.behavior<{ loci: Loci, repr?: Representation.Any }>({ loci: EmptyLoci }),
  39. selectLoci: this.ev.behavior<{ loci: Loci, repr?: Representation.Any }>({ loci: EmptyLoci }),
  40. },
  41. command: this.commands.behaviour
  42. };
  43. readonly canvas3d: Canvas3D;
  44. initViewer(canvas: HTMLCanvasElement, container: HTMLDivElement) {
  45. try {
  46. (this.canvas3d as Canvas3D) = Canvas3D.create(canvas, container);
  47. this.canvas3d.animate();
  48. console.log('canvas3d created');
  49. return true;
  50. } catch (e) {
  51. console.error(e);
  52. return false;
  53. }
  54. }
  55. /**
  56. * This should be used in all transform related request so that it could be "spoofed" to allow
  57. * "static" access to resources.
  58. */
  59. async fetch(url: string, type: 'string' | 'binary' = 'string'): Promise<string | Uint8Array> {
  60. const req = await fetch(url, { referrerPolicy: 'origin-when-cross-origin' });
  61. return type === 'string' ? await req.text() : new Uint8Array(await req.arrayBuffer());
  62. }
  63. async runTask<T>(task: Task<T>) {
  64. return await task.run(p => console.log(p.root.progress.message), 250);
  65. }
  66. dispose() {
  67. if (this.disposed) return;
  68. this.commands.dispose();
  69. this.canvas3d.dispose();
  70. this.ev.dispose();
  71. this.state.dispose();
  72. this.disposed = true;
  73. }
  74. private initBuiltInBehavior() {
  75. BuiltInPluginBehaviors.State.registerDefault(this);
  76. BuiltInPluginBehaviors.Representation.registerDefault(this);
  77. BuiltInPluginBehaviors.Camera.registerDefault(this);
  78. }
  79. async _test_initBehaviors() {
  80. const tree = this.state.behavior.tree.build()
  81. .toRoot().apply(PluginBehaviors.Representation.HighlightLoci, { ref: PluginBehaviors.Representation.HighlightLoci.id })
  82. .toRoot().apply(PluginBehaviors.Representation.SelectLoci, { ref: PluginBehaviors.Representation.SelectLoci.id })
  83. .getTree();
  84. await this.runTask(this.state.behavior.update(tree));
  85. }
  86. _test_initDataActions() {
  87. this.state.data.actions
  88. .add(CreateStructureFromPDBe)
  89. .add(StateTransforms.Data.Download)
  90. .add(StateTransforms.Model.CreateStructureAssembly)
  91. .add(StateTransforms.Model.CreateStructure)
  92. .add(StateTransforms.Model.CreateModelFromTrajectory)
  93. .add(StateTransforms.Visuals.CreateStructureRepresentation);
  94. }
  95. applyTransform(state: State, a: Transform.Ref, transformer: Transformer, params: any) {
  96. const tree = state.tree.build().to(a).apply(transformer, params);
  97. return PluginCommands.State.Update.dispatch(this, { state, tree });
  98. }
  99. updateTransform(state: State, a: Transform.Ref, params: any) {
  100. const tree = state.build().to(a).update(params);
  101. return PluginCommands.State.Update.dispatch(this, { state, tree });
  102. }
  103. private initEvents() {
  104. merge(this.events.state.data.object.created, this.events.state.behavior.object.created).subscribe(o => {
  105. if (!SO.isBehavior(o.obj)) return;
  106. console.log('registering behavior', o.obj.label);
  107. o.obj.data.register();
  108. });
  109. merge(this.events.state.data.object.removed, this.events.state.behavior.object.removed).subscribe(o => {
  110. if (!SO.isBehavior(o.obj)) return;
  111. o.obj.data.unregister();
  112. });
  113. merge(this.events.state.data.object.updated, this.events.state.behavior.object.updated).subscribe(o => {
  114. if (o.action === 'recreate') {
  115. if (o.oldObj && SO.isBehavior(o.oldObj)) o.oldObj.data.unregister();
  116. if (o.obj && SO.isBehavior(o.obj)) o.obj.data.register();
  117. }
  118. });
  119. }
  120. constructor() {
  121. this.initEvents();
  122. this.initBuiltInBehavior();
  123. this._test_initBehaviors();
  124. this._test_initDataActions();
  125. }
  126. // logger = ;
  127. // settings = ;
  128. }