property.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /**
  2. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { CustomPropertyDescriptor, Model } from '../../../mol-model/structure';
  7. import { ModelFormat } from '../../format';
  8. class FormatRegistry<T> {
  9. private map = new Map<ModelFormat['kind'], (model: Model) => T | undefined>()
  10. private applicable = new Map<ModelFormat['kind'], (model: Model) => boolean>()
  11. add(kind: ModelFormat['kind'], obtain: (model: Model) => T | undefined, applicable?: (model: Model) => boolean) {
  12. this.map.set(kind, obtain);
  13. if (applicable) this.applicable.set(kind, applicable);
  14. }
  15. remove(kind: ModelFormat['kind']) {
  16. this.map.delete(kind);
  17. this.applicable.delete(kind);
  18. }
  19. get(kind: ModelFormat['kind']) {
  20. return this.map.get(kind);
  21. }
  22. isApplicable(model: Model) {
  23. const isApplicable = this.applicable.get(model.sourceData.kind);
  24. return isApplicable ? isApplicable(model) : true;
  25. }
  26. }
  27. export { FormatPropertyProvider as FormatPropertyProvider };
  28. interface FormatPropertyProvider<T> {
  29. readonly descriptor: CustomPropertyDescriptor
  30. readonly formatRegistry: FormatRegistry<T>
  31. isApplicable(model: Model): boolean
  32. get(model: Model): T | undefined
  33. set(model: Model, value: T): void
  34. }
  35. namespace FormatPropertyProvider {
  36. export function create<T>(descriptor: CustomPropertyDescriptor): FormatPropertyProvider<T> {
  37. const { name } = descriptor;
  38. const formatRegistry = new FormatRegistry<T>();
  39. return {
  40. descriptor,
  41. formatRegistry,
  42. isApplicable(model: Model) {
  43. return formatRegistry.isApplicable(model);
  44. },
  45. get(model: Model): T | undefined {
  46. if (model._staticPropertyData[name]) return model._staticPropertyData[name];
  47. if (model.customProperties.has(descriptor)) return;
  48. const obtain = formatRegistry.get(model.sourceData.kind);
  49. if (!obtain) return;
  50. model._staticPropertyData[name] = obtain(model);
  51. model.customProperties.add(descriptor);
  52. return model._staticPropertyData[name];
  53. },
  54. set(model: Model, value: T) {
  55. model._staticPropertyData[name] = value;
  56. }
  57. };
  58. }
  59. }