提交 ab17bb71 编写于 作者: J Johannes Rieken

add a new lifecycle event `Restoring` which is set when the editors/viewlets...

add a new lifecycle event `Restoring` which is set when the editors/viewlets are being restored (start). also in the lifecycle service replace `onDidChangePhase` with `when`
上级 b94569fe
......@@ -47,8 +47,9 @@ export enum StartupKind {
export enum LifecyclePhase {
Starting = 1,
Running = 2,
ShuttingDown = 3
Restoring = 2,
Running = 3,
ShuttingDown = 4
}
/**
......@@ -70,9 +71,10 @@ export interface ILifecycleService {
readonly phase: LifecyclePhase;
/**
* An event that fire when the lifecycle phase has changed
* Returns a promise that resolves when a certain lifecycle phase
* has started.
*/
readonly onDidChangePhase: Event<LifecyclePhase>;
when(phase: LifecyclePhase): Thenable<void>;
/**
* Fired before shutdown happens. Allows listeners to veto against the
......@@ -92,8 +94,8 @@ export interface ILifecycleService {
export const NullLifecycleService: ILifecycleService = {
_serviceBrand: null,
phase: LifecyclePhase.Running,
when() { return Promise.resolve(); },
startupKind: StartupKind.NewWindow,
onDidChangePhase: Event.None,
onWillShutdown: Event.None,
onShutdown: Event.None
};
......@@ -127,4 +129,4 @@ export function handleVetos(vetos: (boolean | TPromise<boolean>)[], onError: (er
}
return TPromise.join(promises).then(() => lazyValue);
}
\ No newline at end of file
}
......@@ -70,11 +70,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
protected createTextEditorModel(value: string | IRawTextSource, resource?: URI, modeId?: string): TPromise<EditorModel> {
const firstLineText = this.getFirstLineText(value);
const mode = this.getOrCreateMode(this.modeService, modeId, firstLineText);
// To avoid flickering, give the mode at most 50ms to load. If the mode doesn't load in 50ms, proceed creating the model with a mode promise
return TPromise.any<any>([TPromise.timeout(50), mode]).then(() => {
return this.doCreateTextEditorModel(value, mode, resource);
});
return TPromise.as(this.doCreateTextEditorModel(value, mode, resource));
}
private doCreateTextEditorModel(value: string | IRawTextSource, mode: TPromise<IMode>, resource: URI): EditorModel {
......@@ -166,4 +162,4 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
super.dispose();
}
}
\ No newline at end of file
}
......@@ -165,7 +165,7 @@ export class WorkbenchShell {
const [instantiationService, serviceCollection] = this.initServiceCollection(parent.getHTMLElement());
// Workbench
this.workbench = instantiationService.createInstance(Workbench, parent.getHTMLElement(), workbenchContainer.getHTMLElement(), this.configuration, serviceCollection);
this.workbench = instantiationService.createInstance(Workbench, parent.getHTMLElement(), workbenchContainer.getHTMLElement(), this.configuration, serviceCollection, this.lifecycleService);
this.workbench.startup({
onWorkbenchStarted: (info: IWorkbenchStartedInfo) => {
......
......@@ -79,7 +79,8 @@ import { ProgressService2 } from 'vs/workbench/services/progress/browser/progres
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ILifecycleService, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
import { ShutdownReason, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { LifecycleService } from 'vs/workbench/services/lifecycle/electron-browser/lifecycleService';
import { IWindowService, IWindowConfiguration as IWindowSettings, IWindowConfiguration, IPath } from 'vs/platform/windows/common/windows';
import { IMessageService } from 'vs/platform/message/common/message';
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
......@@ -217,10 +218,10 @@ export class Workbench implements IPartService {
container: HTMLElement,
configuration: IWindowConfiguration,
serviceCollection: ServiceCollection,
private lifecycleService: LifecycleService,
@IInstantiationService private instantiationService: IInstantiationService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IStorageService private storageService: IStorageService,
@ILifecycleService private lifecycleService: ILifecycleService,
@IMessageService private messageService: IMessageService,
@IConfigurationService private configurationService: WorkspaceService,
@ITelemetryService private telemetryService: ITelemetryService,
......@@ -339,6 +340,7 @@ export class Workbench implements IPartService {
const editorRestoreClock = time('restore:editors');
const restoredEditors: string[] = [];
compositeAndEditorPromises.push(this.resolveEditorsToOpen().then(inputs => {
this.lifecycleService.phase = LifecyclePhase.Restoring;
let editorOpenPromise: TPromise<IEditor[]>;
if (inputs.length) {
editorOpenPromise = this.editorService.openEditors(inputs.map(input => { return { input, position: EditorPosition.ONE }; }));
......
......@@ -17,7 +17,6 @@ import { ReportPerformanceIssueAction } from 'vs/workbench/electron-browser/acti
import { TPromise } from 'vs/base/common/winjs.base';
import { join } from 'path';
import { localize } from 'vs/nls';
import { toPromise, filterEvent } from 'vs/base/common/event';
import { readdir } from 'vs/base/node/pfs';
import { stopProfiling } from 'vs/base/node/profiler';
......@@ -33,8 +32,8 @@ class StartupProfiler implements IWorkbenchContribution {
) {
// wait for everything to be ready
TPromise.join<any>([
lifecycleService.when(LifecyclePhase.Running),
extensionService.onReady(),
toPromise(filterEvent(lifecycleService.onDidChangePhase, phase => phase === LifecyclePhase.Running)),
]).then(() => {
this._stopProfiling();
});
......
......@@ -33,7 +33,6 @@ import { IWindowService } from 'vs/platform/windows/common/windows';
import { Action } from 'vs/base/common/actions';
import { IDisposable } from 'vs/base/common/lifecycle';
import { mark, time } from 'vs/base/common/performance';
import { toPromise, filterEvent } from 'vs/base/common/event';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions'));
......@@ -100,12 +99,12 @@ export class ExtensionService implements IExtensionService {
this._extensionHostProcessCustomers = [];
this._extensionHostProcessProxy = null;
toPromise(filterEvent(lifecycleService.onDidChangePhase, phase => phase === LifecyclePhase.Running)).then(() => {
lifecycleService.when(LifecyclePhase.Restoring).then(() => {
// delay extension host creation and extension scanning
// until after the editors/panels are restored
this._startExtensionHostProcess([]);
this._scanAndHandleExtensions();
});
this._startExtensionHostProcess([]);
this._scanAndHandleExtensions();
}
public restartExtensionHost(): void {
......
......@@ -13,6 +13,8 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
import { ipcRenderer as ipc } from 'electron';
import Event, { Emitter } from 'vs/base/common/event';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { mark } from 'vs/base/common/performance';
import { Barrier } from 'vs/workbench/services/extensions/node/barrier';
export class LifecycleService implements ILifecycleService {
......@@ -20,12 +22,12 @@ export class LifecycleService implements ILifecycleService {
public _serviceBrand: any;
private readonly _onDidChangePhase = new Emitter<LifecyclePhase>();
private readonly _onWillShutdown = new Emitter<ShutdownEvent>();
private readonly _onShutdown = new Emitter<ShutdownReason>();
private readonly _startupKind: StartupKind;
private _phase: LifecyclePhase = LifecyclePhase.Starting;
private _phaseWhen = new Map<LifecyclePhase, Barrier>();
constructor(
@IMessageService private _messageService: IMessageService,
......@@ -50,18 +52,36 @@ export class LifecycleService implements ILifecycleService {
}
public set phase(value: LifecyclePhase) {
if (this._phase !== value) {
this._phase = value;
this._onDidChangePhase.fire(value);
if (value < this.phase) {
throw new Error('Lifecycle cannot go backwards');
}
if (this._phase === value) {
return;
}
this._phase = value;
mark(`LifecyclePhase/${LifecyclePhase[value]}`);
if (this._phaseWhen.has(this._phase)) {
this._phaseWhen.get(this._phase).open();
this._phaseWhen.delete(this._phase);
}
}
public get startupKind(): StartupKind {
return this._startupKind;
public when(phase: LifecyclePhase): Thenable<any> {
if (phase <= this._phase) {
return Promise.resolve();
}
let barrier = this._phaseWhen.get(phase);
if (!barrier) {
barrier = new Barrier();
this._phaseWhen.set(phase, barrier);
}
return barrier.wait();
}
public get onDidChangePhase(): Event<LifecyclePhase> {
return this._onDidChangePhase.event;
public get startupKind(): StartupKind {
return this._startupKind;
}
public get onWillShutdown(): Event<ShutdownEvent> {
......
......@@ -60,6 +60,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res
import { IPosition } from 'vs/editor/common/core/position';
import { ICommandAction } from 'vs/platform/actions/common/actions';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
import { notImplemented } from 'vs/base/common/errors';
export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, void 0);
......@@ -1008,10 +1009,12 @@ export class TestLifecycleService implements ILifecycleService {
public phase: LifecyclePhase;
public startupKind: StartupKind;
private _onDidChangePhase = new Emitter<LifecyclePhase>();
private _onWillShutdown = new Emitter<ShutdownEvent>();
private _onShutdown = new Emitter<ShutdownReason>();
when(): Thenable<void> {
throw notImplemented();
};
public fireShutdown(reason = ShutdownReason.QUIT): void {
this._onShutdown.fire(reason);
......@@ -1021,10 +1024,6 @@ export class TestLifecycleService implements ILifecycleService {
this._onWillShutdown.fire(event);
}
public get onDidChangePhase(): Event<LifecyclePhase> {
return this._onDidChangePhase.event;
}
public get onWillShutdown(): Event<ShutdownEvent> {
return this._onWillShutdown.event;
}
......@@ -1250,4 +1249,4 @@ export class TestHashService implements IHashService {
export function getRandomTestPath(tmpdir: string, ...segments: string[]): string {
return paths.join(tmpdir, ...segments, generateUuid());
}
\ No newline at end of file
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册