Skip to content

Commit

Permalink
Add Event.defer with hidden experimental setting
Browse files Browse the repository at this point in the history
Part of #161622
  • Loading branch information
Tyriar committed Oct 11, 2022
1 parent ae34e8d commit e2b58d6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/vs/base/common/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,44 @@ export namespace Event {
}
}

// TODO: This boolean will go away once it's stable
/**
* Whether to enable the {@link Event.defer}.
*/
// eslint-disable-next-line prefer-const
export let enableDefer: boolean = false;

/**
* Given an event, returns another event which defers the listener to a later task via a shared `setTimeout`. This
* is useful for deferring non-critical work (eg. general UI updates) to ensure it does not block critical work (eg.
* latency of keypress to text rendered).
*
* *NOTE* when using this it's important to consider race conditions that could arise when using related deferred
* and non-deferred events.
*/
export function defer<T>(event: Event<T>): Event<T> {
const listeners: { listener: (e: T) => any; thisArgs?: any; disposables?: IDisposable[] | DisposableStore }[] = [];
let primaryListener: IDisposable | undefined;
return (listener, thisArgs = null, disposables?) => {
listeners.push({ listener, thisArgs, disposables });
if (!primaryListener) {
primaryListener = event(e => {
if (enableDefer) {
setTimeout(() => {
for (const l of listeners) {
l.listener.call(l.thisArgs, e);
}
}, 0);
} else {
for (const l of listeners) {
l.listener.call(l.thisArgs, e);
}
}
});
}
return primaryListener;
};
}

/**
* Given an event, returns another event which only fires once.
Expand Down
27 changes: 27 additions & 0 deletions src/vs/workbench/contrib/performance/browser/inputLatency.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';

export class InputLatencyContrib extends Disposable implements IWorkbenchContribution {
constructor(
@IConfigurationService private readonly _configurationService: IConfigurationService
) {
super();
this._register(_configurationService.onDidChangeConfiguration(() => this._refresh()));
this._refresh();
}

private _refresh() {
const value = this._configurationService.getValue<boolean>('performance.inputLatency') || false;
if (Event.enableDefer !== value) {
console.warn('Event.enableDefer = ', value);
Event.enableDefer = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { PerfviewContrib, PerfviewInput } from 'vs/workbench/contrib/performance
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { InstantiationService, Trace } from 'vs/platform/instantiation/common/instantiationService';
import { EventProfiling } from 'vs/base/common/event';
import { InputLatencyContrib } from 'vs/workbench/contrib/performance/browser/inputLatency';

// -- startup performance view

Expand All @@ -39,6 +40,14 @@ Registry.as<IEditorFactoryRegistry>(EditorExtensions.EditorFactory).registerEdit
);


// -- input latency reduction experiment

Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench).registerWorkbenchContribution(
InputLatencyContrib,
LifecyclePhase.Ready
);


registerAction2(class extends Action2 {

constructor() {
Expand Down

0 comments on commit e2b58d6

Please sign in to comment.