mainThreadNotebook.ts 6.4 KB
Newer Older
R
rebornix 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/*---------------------------------------------------------------------------------------------
 *  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';
import { Disposable } from 'vs/base/common/lifecycle';
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[],
		public cell_type: 'markdown' | 'code',
		outputs: IOutput[]
	) {
		this._outputs = outputs;
	}
}

R
rebornix 已提交
39
export class MainThreadNotebookDocument implements INotebook {
R
rebornix 已提交
40 41 42 43 44

	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 已提交
45
	public activeCell: MainThreadCell | undefined;
R
rebornix 已提交
46 47

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

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

		if (mcell) {
			mcell.outputs = cell.outputs;
		}
R
rebornix 已提交
61 62 63 64
	}

	updateCells(newCells: ICell[]) {
		// todo, handle cell insertion and deletion
R
rebornix 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

		if (this.cells.length === 0) {
			newCells.forEach(cell => {
				let mainCell = new MainThreadCell(cell.handle, cell.source, cell.cell_type, cell.outputs);
				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 已提交
80 81 82

		this._onDidChangeCells.fire();
	}
R
rebornix 已提交
83 84 85 86

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

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

R
rebornix 已提交
94
	private readonly _documents: Map<number, MainThreadNotebookDocument> = new Map();
R
rebornix 已提交
95 96 97 98 99 100 101 102
	constructor(
		extHostContext: IExtHostContext,
		@INotebookService private _notebookService: INotebookService
	) {
		super();
		this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostNotebook);
	}

R
rebornix 已提交
103 104
	async $registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string): Promise<void> {
		let controller = new MainThreadNotebookController(this._proxy, this, viewType);
R
rebornix 已提交
105
		this._notebookProviders.set(viewType, controller);
R
rebornix 已提交
106
		this._notebookService.registerNotebookController(viewType, extension, controller);
R
rebornix 已提交
107
		return;
R
rebornix 已提交
108 109
	}

R
rebornix 已提交
110
	async $unregisterNotebookProvider(viewType: string): Promise<void> {
R
rebornix 已提交
111 112
		this._notebookProviders.delete(viewType);
		this._notebookService.unregisterNotebookProvider(viewType);
R
rebornix 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
		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 已提交
136 137
	}

R
rebornix 已提交
138 139

	async $updateNotebook(viewType: string, uri: URI, notebook: INotebook): Promise<void> {
R
rebornix 已提交
140 141 142 143 144 145
		let controller = this._notebookProviders.get(viewType);

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

		if (handle !== undefined) {
R
rebornix 已提交
150 151 152 153 154 155 156
			const doc = this._documents.get(handle);

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

			return doc;
R
rebornix 已提交
157
		}
R
rebornix 已提交
158

R
rebornix 已提交
159
		return;
R
rebornix 已提交
160 161 162 163 164 165 166 167
	}

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

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

	constructor(
R
rebornix 已提交
171 172 173
		private readonly _proxy: ExtHostNotebookShape,
		private _mainThreadNotebook: MainThreadNotebooks,
		private _viewType: string
R
rebornix 已提交
174 175 176 177 178 179
	) {
	}

	async resolveNotebook(viewType: string, uri: URI): Promise<INotebook | undefined> {
		let notebook = await this._mainThreadNotebook.resolveNotebook(viewType, uri);
		if (notebook) {
R
rebornix 已提交
180 181
			this._mapping.set(uri.toString(), notebook);
			return notebook;
R
rebornix 已提交
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
		}
		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 已提交
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212

	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 已提交
213
}