mainThreadNotebook.ts 6.7 KB
Newer Older
R
rebornix 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { MainContext, MainThreadNotebookShape, NotebookExtensionDescription, IExtHostContext, ExtHostNotebookShape, ExtHostContext } from '../common/extHost.protocol';
R
rebornix 已提交
8
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
R
rebornix 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
import { URI } from 'vs/base/common/uri';
import { INotebookService, IMainNotebookController } from 'vs/workbench/contrib/notebook/browser/notebookService';
import { INotebook, IMetadata, ICell, IOutput } from 'vs/editor/common/modes';
import { Emitter, Event } from 'vs/base/common/event';

export class MainThreadCell implements ICell {
	private _onDidChangeOutputs = new Emitter<void>();
	onDidChangeOutputs: Event<void> = this._onDidChangeOutputs.event;

	private _outputs: IOutput[];

	public get outputs(): IOutput[] {
		return this._outputs;
	}

	public set outputs(newOutputs: IOutput[]) {
		this._outputs = newOutputs;
		this._onDidChangeOutputs.fire();
	}

	constructor(
		public handle: number,
		public source: string[],
R
rebornix 已提交
32
		public language: string,
R
rebornix 已提交
33 34 35 36 37 38 39
		public cell_type: 'markdown' | 'code',
		outputs: IOutput[]
	) {
		this._outputs = outputs;
	}
}

R
rebornix 已提交
40 41 42
export class MainThreadNotebookDocument extends Disposable implements INotebook {
	private readonly _onWillDispose: Emitter<void> = this._register(new Emitter<void>());
	public readonly onWillDispose: Event<void> = this._onWillDispose.event;
R
rebornix 已提交
43 44 45 46
	private readonly _onDidChangeCells = new Emitter<void>();
	get onDidChangeCells(): Event<void> { return this._onDidChangeCells.event; }
	private _mapping: Map<number, MainThreadCell> = new Map();
	public cells: MainThreadCell[];
R
rebornix 已提交
47
	public activeCell: MainThreadCell | undefined;
R
rebornix 已提交
48 49

	constructor(
R
rebornix 已提交
50
		private readonly _proxy: ExtHostNotebookShape,
R
rebornix 已提交
51
		public handle: number,
R
rebornix 已提交
52
		public uri: URI
R
rebornix 已提交
53
	) {
R
rebornix 已提交
54
		super();
R
rebornix 已提交
55
		this.cells = [];
R
rebornix 已提交
56 57 58 59 60 61 62 63
	}

	updateCell(cell: ICell) {
		let mcell = this._mapping.get(cell.handle);

		if (mcell) {
			mcell.outputs = cell.outputs;
		}
R
rebornix 已提交
64 65 66 67
	}

	updateCells(newCells: ICell[]) {
		// todo, handle cell insertion and deletion
R
rebornix 已提交
68 69 70

		if (this.cells.length === 0) {
			newCells.forEach(cell => {
R
rebornix 已提交
71
				let mainCell = new MainThreadCell(cell.handle, cell.source, cell.language, cell.cell_type, cell.outputs);
R
rebornix 已提交
72 73 74 75 76 77 78 79 80 81 82
				this._mapping.set(cell.handle, mainCell);
				this.cells.push(mainCell);
			});
		} else {
			newCells.forEach(newCell => {
				let cell = this._mapping.get(newCell.handle);
				if (cell) {
					cell.outputs = newCell.outputs;
				}
			});
		}
R
rebornix 已提交
83 84 85

		this._onDidChangeCells.fire();
	}
R
rebornix 已提交
86 87 88 89

	updateActiveCell(handle: number) {
		this.activeCell = this._mapping.get(handle);
	}
R
rebornix 已提交
90 91 92 93 94

	dispose() {
		this._onWillDispose.fire();
		super.dispose();
	}
R
rebornix 已提交
95 96 97 98 99 100 101
}

@extHostNamedCustomer(MainContext.MainThreadNotebook)
export class MainThreadNotebooks extends Disposable implements MainThreadNotebookShape {
	private readonly _notebookProviders = new Map<string, MainThreadNotebookController>();
	private readonly _proxy: ExtHostNotebookShape;

R
rebornix 已提交
102
	private readonly _documents: Map<number, MainThreadNotebookDocument> = new Map();
R
rebornix 已提交
103 104 105 106 107 108 109 110
	constructor(
		extHostContext: IExtHostContext,
		@INotebookService private _notebookService: INotebookService
	) {
		super();
		this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostNotebook);
	}

R
rebornix 已提交
111 112
	async $registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string): Promise<void> {
		let controller = new MainThreadNotebookController(this._proxy, this, viewType);
R
rebornix 已提交
113
		this._notebookProviders.set(viewType, controller);
R
rebornix 已提交
114
		this._notebookService.registerNotebookController(viewType, extension, controller);
R
rebornix 已提交
115
		return;
R
rebornix 已提交
116 117
	}

R
rebornix 已提交
118
	async $unregisterNotebookProvider(viewType: string): Promise<void> {
R
rebornix 已提交
119 120
		this._notebookProviders.delete(viewType);
		this._notebookService.unregisterNotebookProvider(viewType);
R
rebornix 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
		return;
	}

	async $createNotebookDocument(handle: number, resource: URI): Promise<void> {
		let document = new MainThreadNotebookDocument(this._proxy, handle, resource);
		this._documents.set(handle, document);
		return;
	}

	async $updateNotebookCells(handle: number, cells: ICell[]): Promise<void> {
		let document = this._documents.get(handle);

		if (document) {
			document.updateCells(cells);
		}
	}

	async $updateNotebookCell(handle: number, cell: ICell): Promise<void> {
		let document = this._documents.get(handle);

		if (document) {
			document.updateCell(cell);
		}
R
rebornix 已提交
144 145
	}

R
rebornix 已提交
146 147

	async $updateNotebook(viewType: string, uri: URI, notebook: INotebook): Promise<void> {
R
rebornix 已提交
148 149 150 151 152 153
		let controller = this._notebookProviders.get(viewType);

		if (controller) {
			controller.updateNotebook(uri, notebook);
		}
	}
R
rebornix 已提交
154 155 156 157
	async resolveNotebook(viewType: string, uri: URI): Promise<MainThreadNotebookDocument | undefined> {
		let handle = await this._proxy.$resolveNotebook(viewType, uri);

		if (handle !== undefined) {
R
rebornix 已提交
158 159 160 161 162 163 164
			const doc = this._documents.get(handle);

			if (doc === undefined) {
				console.log('resolve notebook from main but undefined');
			}

			return doc;
R
rebornix 已提交
165
		}
R
rebornix 已提交
166

R
rebornix 已提交
167
		return;
R
rebornix 已提交
168 169 170 171 172 173 174 175
	}

	executeNotebook(viewType: string, uri: URI): Promise<void> {
		return this._proxy.$executeNotebook(viewType, uri);
	}
}

export class MainThreadNotebookController implements IMainNotebookController {
R
rebornix 已提交
176
	private _mapping: Map<string, MainThreadNotebookDocument> = new Map();
R
rebornix 已提交
177 178

	constructor(
R
rebornix 已提交
179 180 181
		private readonly _proxy: ExtHostNotebookShape,
		private _mainThreadNotebook: MainThreadNotebooks,
		private _viewType: string
R
rebornix 已提交
182 183 184 185 186 187
	) {
	}

	async resolveNotebook(viewType: string, uri: URI): Promise<INotebook | undefined> {
		let notebook = await this._mainThreadNotebook.resolveNotebook(viewType, uri);
		if (notebook) {
R
rebornix 已提交
188 189
			this._mapping.set(uri.toString(), notebook);
			return notebook;
R
rebornix 已提交
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
		}
		return undefined;
	}

	async executeNotebook(viewType: string, uri: URI): Promise<void> {
		this._mainThreadNotebook.executeNotebook(viewType, uri);
	}

	updateNotebook(uri: URI, notebook: INotebook): void {
		let mainthreadNotebook = this._mapping.get(URI.from(uri).toString());

		if (mainthreadNotebook) {
			mainthreadNotebook.updateCells(notebook.cells);
		}
	}
R
rebornix 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220

	updateNotebookActiveCell(uri: URI, cellHandle: number): void {
		let mainthreadNotebook = this._mapping.get(URI.from(uri).toString());

		if (mainthreadNotebook) {
			mainthreadNotebook.updateActiveCell(cellHandle);
		}
	}

	executeNotebookActiveCell(uri: URI): void {
		let mainthreadNotebook = this._mapping.get(URI.from(uri).toString());

		if (mainthreadNotebook && mainthreadNotebook.activeCell) {
			this._proxy.$executeNotebookCell(this._viewType, uri, mainthreadNotebook.activeCell.handle);
		}
	}
R
rebornix 已提交
221
}