complex-representation.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. * @author David Sehnal <david.sehnal@gmail.com>
  6. */
  7. import { Structure } from 'mol-model/structure';
  8. import { Task } from 'mol-task'
  9. import { Loci, EmptyLoci } from 'mol-model/loci';
  10. import { StructureRepresentation, StructureParams } from './representation';
  11. import { ComplexVisual } from './complex-visual';
  12. import { PickingId } from 'mol-geo/geometry/picking';
  13. import { MarkerAction } from 'mol-geo/geometry/marker-data';
  14. import { RepresentationContext, RepresentationParamsGetter, Representation } from 'mol-repr/representation';
  15. import { Theme, createEmptyTheme } from 'mol-theme/theme';
  16. import { ParamDefinition as PD } from 'mol-util/param-definition';
  17. import { Subject } from 'rxjs';
  18. export function ComplexRepresentation<P extends StructureParams>(label: string, ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, P>, visualCtor: () => ComplexVisual<P>): StructureRepresentation<P> {
  19. let version = 0
  20. const updated = new Subject<number>()
  21. const _state = Representation.createState()
  22. let visual: ComplexVisual<P> | undefined
  23. let _structure: Structure
  24. let _params: P
  25. let _props: PD.Values<P>
  26. let _theme = createEmptyTheme()
  27. function createOrUpdate(props: Partial<PD.Values<P>> = {}, structure?: Structure) {
  28. if (structure && structure !== _structure) {
  29. _params = getParams(ctx, structure)
  30. _structure = structure
  31. if (!_props) _props = PD.getDefaultValues(_params)
  32. }
  33. _props = Object.assign({}, _props, props)
  34. return Task.create('Creating or updating ComplexRepresentation', async runtime => {
  35. if (!visual) visual = visualCtor()
  36. const promise = visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, structure)
  37. if (promise) await promise
  38. updated.next(version++)
  39. });
  40. }
  41. function getLoci(pickingId: PickingId) {
  42. return visual ? visual.getLoci(pickingId) : EmptyLoci
  43. }
  44. function mark(loci: Loci, action: MarkerAction) {
  45. return visual ? visual.mark(loci, action) : false
  46. }
  47. function setState(state: Partial<Representation.State>) {
  48. if (state.visible !== undefined && visual) visual.setVisibility(state.visible)
  49. if (state.pickable !== undefined && visual) visual.setPickable(state.pickable)
  50. if (state.transform !== undefined && visual) visual.setTransform(state.transform)
  51. Representation.updateState(_state, state)
  52. }
  53. function setTheme(theme: Theme) {
  54. _theme = theme
  55. }
  56. function destroy() {
  57. if (visual) visual.destroy()
  58. }
  59. return {
  60. label,
  61. get groupCount() {
  62. return visual ? visual.groupCount : 0
  63. },
  64. get renderObjects() {
  65. return visual && visual.renderObject ? [ visual.renderObject ] : []
  66. },
  67. get props() { return _props },
  68. get params() { return _params },
  69. get state() { return _state },
  70. get theme() { return _theme },
  71. updated,
  72. createOrUpdate,
  73. setState,
  74. setTheme,
  75. getLoci,
  76. mark,
  77. destroy
  78. }
  79. }