utils.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { BaseObservable, transaction, ConvenientObservable, getFunctionName } from './base.js';
  6. import { getLogger } from './logging.js';
  7. export function constObservable(value) {
  8. return new ConstObservable(value);
  9. }
  10. class ConstObservable extends ConvenientObservable {
  11. constructor(value) {
  12. super();
  13. this.value = value;
  14. }
  15. get debugName() {
  16. return this.toString();
  17. }
  18. get() {
  19. return this.value;
  20. }
  21. addObserver(observer) {
  22. // NO OP
  23. }
  24. removeObserver(observer) {
  25. // NO OP
  26. }
  27. toString() {
  28. return `Const: ${this.value}`;
  29. }
  30. }
  31. export function observableFromEvent(event, getValue) {
  32. return new FromEventObservable(event, getValue);
  33. }
  34. export class FromEventObservable extends BaseObservable {
  35. constructor(event, getValue) {
  36. super();
  37. this.event = event;
  38. this.getValue = getValue;
  39. this.hasValue = false;
  40. this.handleEvent = (args) => {
  41. var _a;
  42. const newValue = this.getValue(args);
  43. const didChange = !this.hasValue || this.value !== newValue;
  44. (_a = getLogger()) === null || _a === void 0 ? void 0 : _a.handleFromEventObservableTriggered(this, { oldValue: this.value, newValue, change: undefined, didChange });
  45. if (didChange) {
  46. this.value = newValue;
  47. if (this.hasValue) {
  48. transaction((tx) => {
  49. for (const o of this.observers) {
  50. tx.updateObserver(o, this);
  51. o.handleChange(this, undefined);
  52. }
  53. }, () => {
  54. const name = this.getDebugName();
  55. return 'Event fired' + (name ? `: ${name}` : '');
  56. });
  57. }
  58. this.hasValue = true;
  59. }
  60. };
  61. }
  62. getDebugName() {
  63. return getFunctionName(this.getValue);
  64. }
  65. get debugName() {
  66. const name = this.getDebugName();
  67. return 'From Event' + (name ? `: ${name}` : '');
  68. }
  69. onFirstObserverAdded() {
  70. this.subscription = this.event(this.handleEvent);
  71. }
  72. onLastObserverRemoved() {
  73. this.subscription.dispose();
  74. this.subscription = undefined;
  75. this.hasValue = false;
  76. this.value = undefined;
  77. }
  78. get() {
  79. if (this.subscription) {
  80. if (!this.hasValue) {
  81. this.handleEvent(undefined);
  82. }
  83. return this.value;
  84. }
  85. else {
  86. // no cache, as there are no subscribers to keep it updated
  87. return this.getValue(undefined);
  88. }
  89. }
  90. }
  91. (function (observableFromEvent) {
  92. observableFromEvent.Observer = FromEventObservable;
  93. })(observableFromEvent || (observableFromEvent = {}));
  94. export function observableSignalFromEvent(debugName, event) {
  95. return new FromEventObservableSignal(debugName, event);
  96. }
  97. class FromEventObservableSignal extends BaseObservable {
  98. constructor(debugName, event) {
  99. super();
  100. this.debugName = debugName;
  101. this.event = event;
  102. this.handleEvent = () => {
  103. transaction((tx) => {
  104. for (const o of this.observers) {
  105. tx.updateObserver(o, this);
  106. o.handleChange(this, undefined);
  107. }
  108. }, () => this.debugName);
  109. };
  110. }
  111. onFirstObserverAdded() {
  112. this.subscription = this.event(this.handleEvent);
  113. }
  114. onLastObserverRemoved() {
  115. this.subscription.dispose();
  116. this.subscription = undefined;
  117. }
  118. get() {
  119. // NO OP
  120. }
  121. }
  122. export function observableSignal(debugName) {
  123. return new ObservableSignal(debugName);
  124. }
  125. class ObservableSignal extends BaseObservable {
  126. constructor(debugName) {
  127. super();
  128. this.debugName = debugName;
  129. }
  130. trigger(tx, change) {
  131. if (!tx) {
  132. transaction(tx => {
  133. this.trigger(tx, change);
  134. }, () => `Trigger signal ${this.debugName}`);
  135. return;
  136. }
  137. for (const o of this.observers) {
  138. tx.updateObserver(o, this);
  139. o.handleChange(this, change);
  140. }
  141. }
  142. get() {
  143. // NO OP
  144. }
  145. }