complex-representation.ts 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. await visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, structure)
  37. updated.next(version++)
  38. });
  39. }
  40. function getLoci(pickingId: PickingId) {
  41. return visual ? visual.getLoci(pickingId) : EmptyLoci
  42. }
  43. function mark(loci: Loci, action: MarkerAction) {
  44. return visual ? visual.mark(loci, action) : false
  45. }
  46. function setState(state: Partial<Representation.State>) {
  47. if (state.visible !== undefined && visual) visual.setVisibility(state.visible)
  48. if (state.pickable !== undefined && visual) visual.setPickable(state.pickable)
  49. Representation.updateState(_state, state)
  50. }
  51. function setTheme(theme: Theme) {
  52. _theme = theme
  53. }
  54. function destroy() {
  55. if (visual) visual.destroy()
  56. }
  57. return {
  58. label,
  59. get groupCount() {
  60. return visual ? visual.groupCount : 0
  61. },
  62. get renderObjects() {
  63. return visual && visual.renderObject ? [ visual.renderObject ] : []
  64. },
  65. get props() { return _props },
  66. get params() { return _params },
  67. get state() { return _state },
  68. get theme() { return _theme },
  69. updated,
  70. createOrUpdate,
  71. setState,
  72. setTheme,
  73. getLoci,
  74. mark,
  75. destroy
  76. }
  77. }