Skip to content

Commit ebc3e1e

Browse files
committed
Observable implementation bugfix + docs
1 parent ca0abe6 commit ebc3e1e

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

src/vs/base/common/observableImpl/autorun.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,41 @@ export function autorunHandleChanges<TChangeSummary>(
2323
return new AutorunObserver(debugName, fn, options.createEmptyChangeSummary, options.handleChange);
2424
}
2525

26+
// TODO@hediet rename to autorunWithStore
27+
export function autorunWithStore2(
28+
debugName: string,
29+
fn: (reader: IReader, store: DisposableStore) => void,
30+
): IDisposable {
31+
return autorunWithStore(fn, debugName);
32+
}
33+
34+
export function autorunWithStoreHandleChanges<TChangeSummary>(
35+
debugName: string,
36+
options: {
37+
createEmptyChangeSummary?: () => TChangeSummary;
38+
handleChange: (context: IChangeContext, changeSummary: TChangeSummary) => boolean;
39+
},
40+
fn: (reader: IReader, changeSummary: TChangeSummary, store: DisposableStore) => void
41+
): IDisposable {
42+
const store = new DisposableStore();
43+
const disposable = autorunHandleChanges(
44+
debugName,
45+
{
46+
createEmptyChangeSummary: options.createEmptyChangeSummary,
47+
handleChange: options.handleChange,
48+
},
49+
(reader, changeSummary) => {
50+
store.clear();
51+
fn(reader, changeSummary, store);
52+
}
53+
);
54+
return toDisposable(() => {
55+
disposable.dispose();
56+
store.dispose();
57+
});
58+
}
59+
60+
// TODO@hediet deprecate, rename to autorunWithStoreEx
2661
export function autorunWithStore(
2762
fn: (reader: IReader, store: DisposableStore) => void,
2863
debugName: string

src/vs/base/common/observableImpl/base.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import { IDisposable } from 'vs/base/common/lifecycle';
77
import type { derived } from 'vs/base/common/observableImpl/derived';
88
import { getLogger } from 'vs/base/common/observableImpl/logging';
99

10+
/**
11+
* Represents an observable value.
12+
* @template T The type of the value.
13+
* @template TChange The type of delta information (usually `void` and only used in advanced scenarios).
14+
*/
1015
export interface IObservable<T, TChange = unknown> {
1116
/**
1217
* Returns the current value.
@@ -248,6 +253,10 @@ export function getFunctionName(fn: Function): string | undefined {
248253
export interface ISettableObservable<T, TChange = void> extends IObservable<T, TChange>, ISettable<T, TChange> {
249254
}
250255

256+
/**
257+
* Creates an observable value.
258+
* Observers get informed when the value changes.
259+
*/
251260
export function observableValue<T, TChange = void>(name: string, initialValue: T): ISettableObservable<T, TChange> {
252261
return new ObservableValue(name, initialValue);
253262
}

src/vs/base/common/observableImpl/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ class FromEventObservableSignal extends BaseObservable<void> {
198198
}
199199
}
200200

201+
/**
202+
* Creates a signal that can be triggered to invalidate observers.
203+
*/
201204
export function observableSignal<TDelta = void>(
202205
debugName: string
203206
): IObservableSignal<TDelta> {
@@ -287,6 +290,10 @@ export function wasEventTriggeredRecently(event: Event<any>, timeoutMs: number,
287290
export function keepAlive(observable: IObservable<any>, forceRecompute?: boolean): IDisposable {
288291
const o = new KeepAliveObserver(forceRecompute ?? false);
289292
observable.addObserver(o);
293+
if (forceRecompute) {
294+
observable.reportChanges();
295+
}
296+
290297
return toDisposable(() => {
291298
observable.removeObserver(o);
292299
});

0 commit comments

Comments
 (0)