wip: ipc api
This commit is contained in:
parent
ee541af5df
commit
68117af61a
|
@ -74,6 +74,7 @@ import './mainThreadAuthentication';
|
|||
import './mainThreadTimeline';
|
||||
import './mainThreadTesting';
|
||||
import './mainThreadSecretState';
|
||||
import './mainThreadIPC';
|
||||
|
||||
export class ExtensionPoints implements IWorkbenchContribution {
|
||||
|
||||
|
|
65
src/vs/workbench/api/browser/mainThreadIPC.ts
Normal file
65
src/vs/workbench/api/browser/mainThreadIPC.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { ExtHostContext, IExtHostContext, MainContext, MainThreadIPCShape, IPCHandle, ExtHostIPCShape } from '../common/extHost.protocol';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadIPC)
|
||||
export class MainThreadIPC implements MainThreadIPCShape {
|
||||
|
||||
private static Handles = 0;
|
||||
|
||||
private readonly emitter = new Emitter<{ handle: IPCHandle, message: VSBuffer }>();
|
||||
private readonly disposables = new Map<IPCHandle, IDisposable>();
|
||||
private proxy: ExtHostIPCShape | undefined;
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
if (!environmentService.options?.ipcProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.proxy = extHostContext.getProxy(ExtHostContext.ExtHostIPC);
|
||||
}
|
||||
|
||||
async $register(extensionId: ExtensionIdentifier): Promise<IPCHandle | undefined> {
|
||||
if (!this.proxy) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ipc = await this.environmentService.options?.ipcProvider?.getMessagePassingProtocol(extensionId.value);
|
||||
|
||||
if (!ipc) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const handle = MainThreadIPC.Handles++;
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
ipc.onDidReceiveMessage(message => this.proxy!.$sendMessage(handle, VSBuffer.wrap(message)), undefined, disposables);
|
||||
Event.chain(this.emitter.event)
|
||||
.filter(e => e.handle === handle)
|
||||
.map(({ message }) => message.buffer)
|
||||
.event(message => ipc.sendMessage(message), undefined, disposables);
|
||||
|
||||
this.disposables.set(handle, disposables);
|
||||
return handle;
|
||||
}
|
||||
|
||||
async $sendMessage(handle: IPCHandle, message: VSBuffer): Promise<void> {
|
||||
this.emitter.fire({ handle, message });
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.emitter.dispose();
|
||||
}
|
||||
}
|
|
@ -92,6 +92,7 @@ import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNoteboo
|
|||
import { ExtHostInteractive } from 'vs/workbench/api/common/extHostInteractive';
|
||||
import { combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ExtHostIPC } from 'vs/workbench/api/common/extHostIPC';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
|
||||
|
@ -177,6 +178,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
const extHostWebviewViews = rpcProtocol.set(ExtHostContext.ExtHostWebviewViews, new ExtHostWebviewViews(rpcProtocol, extHostWebviews));
|
||||
const extHostTesting = rpcProtocol.set(ExtHostContext.ExtHostTesting, new ExtHostTesting(rpcProtocol, extHostCommands));
|
||||
const extHostUriOpeners = rpcProtocol.set(ExtHostContext.ExtHostUriOpeners, new ExtHostUriOpeners(rpcProtocol));
|
||||
const extHostIPC = rpcProtocol.set(ExtHostContext.ExtHostIPC, new ExtHostIPC(rpcProtocol));
|
||||
rpcProtocol.set(ExtHostContext.ExtHostInteractive, new ExtHostInteractive(rpcProtocol, extHostNotebook, extHostDocumentsAndEditors, extHostCommands));
|
||||
|
||||
// Check that no named customers are missing
|
||||
|
@ -760,6 +762,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
getInlineCompletionItemController<T extends vscode.InlineCompletionItem>(provider: vscode.InlineCompletionItemProvider<T>): vscode.InlineCompletionController<T> {
|
||||
checkProposedApiEnabled(extension, 'inlineCompletions');
|
||||
return InlineCompletionController.get(provider);
|
||||
},
|
||||
getMessagePassingProtocol() {
|
||||
checkProposedApiEnabled(extension, 'ipc');
|
||||
return extHostIPC.getMessagePassingProtocol(extension);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ export interface MainThreadTextEditorsShape extends IDisposable {
|
|||
}
|
||||
|
||||
export interface MainThreadTreeViewsShape extends IDisposable {
|
||||
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean, dragAndDropMimeTypes: string[] | undefined}): Promise<void>;
|
||||
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean, dragAndDropMimeTypes: string[] | undefined }): Promise<void>;
|
||||
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem; }): Promise<void>;
|
||||
$reveal(treeViewId: string, itemInfo: { item: ITreeItem, parentChain: ITreeItem[] } | undefined, options: IRevealOptions): Promise<void>;
|
||||
$setMessage(treeViewId: string, message: string): void;
|
||||
|
@ -2195,6 +2195,17 @@ export interface MainThreadTestingShape {
|
|||
$finishedExtensionTestRun(runId: string): void;
|
||||
}
|
||||
|
||||
export type IPCHandle = number;
|
||||
|
||||
export interface ExtHostIPCShape {
|
||||
$sendMessage(handle: IPCHandle, message: VSBuffer): Promise<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadIPCShape {
|
||||
$register(extensionId: ExtensionIdentifier): Promise<IPCHandle | undefined>;
|
||||
$sendMessage(handle: IPCHandle, message: VSBuffer): Promise<void>;
|
||||
}
|
||||
|
||||
// --- proxy identifiers
|
||||
|
||||
export const MainContext = {
|
||||
|
@ -2253,7 +2264,8 @@ export const MainContext = {
|
|||
MainThreadTheming: createMainId<MainThreadThemingShape>('MainThreadTheming'),
|
||||
MainThreadTunnelService: createMainId<MainThreadTunnelServiceShape>('MainThreadTunnelService'),
|
||||
MainThreadTimeline: createMainId<MainThreadTimelineShape>('MainThreadTimeline'),
|
||||
MainThreadTesting: createMainId<MainThreadTestingShape>('MainThreadTesting')
|
||||
MainThreadTesting: createMainId<MainThreadTestingShape>('MainThreadTesting'),
|
||||
MainThreadIPC: createMainId<MainThreadIPCShape>('MainThreadIPC'),
|
||||
};
|
||||
|
||||
export const ExtHostContext = {
|
||||
|
@ -2308,4 +2320,5 @@ export const ExtHostContext = {
|
|||
ExtHostTimeline: createMainId<ExtHostTimelineShape>('ExtHostTimeline'),
|
||||
ExtHostTesting: createMainId<ExtHostTestingShape>('ExtHostTesting'),
|
||||
ExtHostTelemetry: createMainId<ExtHostTelemetryShape>('ExtHostTelemetry'),
|
||||
ExtHostIPC: createMainId<ExtHostIPCShape>('ExtHostIPC'),
|
||||
};
|
||||
|
|
49
src/vs/workbench/api/common/extHostIPC.ts
Normal file
49
src/vs/workbench/api/common/extHostIPC.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { ExtHostIPCShape, IPCHandle, MainContext, MainThreadIPCShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { MessagePassingProtocol } from 'vscode';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export class ExtHostIPC implements ExtHostIPCShape {
|
||||
|
||||
private readonly emitter = new Emitter<{ handle: IPCHandle, message: VSBuffer }>();
|
||||
private proxy: MainThreadIPCShape;
|
||||
|
||||
constructor(@IExtHostRpcService rpc: IExtHostRpcService) {
|
||||
this.proxy = rpc.getProxy(MainContext.MainThreadIPC);
|
||||
}
|
||||
|
||||
async getMessagePassingProtocol(extension: IExtensionDescription): Promise<MessagePassingProtocol | undefined> {
|
||||
const handle = await this.proxy.$register(extension.identifier);
|
||||
|
||||
if (handle === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const onDidReceiveMessage = Event.chain(this.emitter.event)
|
||||
.filter(e => e.handle === handle)
|
||||
.map(({ message }) => message.buffer)
|
||||
.event;
|
||||
|
||||
return {
|
||||
onDidReceiveMessage,
|
||||
sendMessage: (message) => {
|
||||
this.proxy.$sendMessage(handle, VSBuffer.wrap(message));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async $sendMessage(handle: IPCHandle, message: VSBuffer): Promise<void> {
|
||||
this.emitter.fire({ handle, message });
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.emitter.dispose();
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ export const allApiProposals = Object.freeze({
|
|||
fsChunks: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.fsChunks.d.ts',
|
||||
inlayHints: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.inlayHints.d.ts',
|
||||
inlineCompletions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.inlineCompletions.d.ts',
|
||||
ipc: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.ipc.d.ts',
|
||||
languageStatus: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.languageStatus.d.ts',
|
||||
notebookCellExecutionState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCellExecutionState.d.ts',
|
||||
notebookConcatTextDocument: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookConcatTextDocument.d.ts',
|
||||
|
|
|
@ -337,6 +337,17 @@ interface ISettingsSyncOptions {
|
|||
enablementHandler?(enablement: boolean): void;
|
||||
}
|
||||
|
||||
export type Message = Uint8Array;
|
||||
|
||||
export interface IMessagePassingProtocol {
|
||||
readonly onDidReceiveMessage: Event<Message>;
|
||||
sendMessage(message: Message): void;
|
||||
}
|
||||
|
||||
export interface IIPCProvider {
|
||||
getMessagePassingProtocol(extensionId: string): Promise<IMessagePassingProtocol | undefined>;
|
||||
}
|
||||
|
||||
interface IWorkbenchConstructionOptions {
|
||||
|
||||
//#region Connection related configuration
|
||||
|
@ -525,6 +536,13 @@ interface IWorkbenchConstructionOptions {
|
|||
//#endregion
|
||||
|
||||
|
||||
//#region IPC
|
||||
|
||||
readonly ipcProvider?: IIPCProvider;
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region Development options
|
||||
|
||||
readonly developmentOptions?: IDevelopmentOptions;
|
||||
|
|
18
src/vscode-dts/vscode.proposed.ipc.d.ts
vendored
Normal file
18
src/vscode-dts/vscode.proposed.ipc.d.ts
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
export type Message = Uint8Array;
|
||||
|
||||
export interface MessagePassingProtocol {
|
||||
readonly onDidReceiveMessage: Event<Message>;
|
||||
sendMessage(message: Message): void;
|
||||
}
|
||||
|
||||
export namespace window {
|
||||
export function getMessagePassingProtocol(): Thenable<MessagePassingProtocol | undefined>;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue