aboutsummaryrefslogtreecommitdiffstats
path: root/qt-cpp/src/tasks/wasm-start.ts
blob: 7a100c10f9ec86b065975180ab3e2c4479dbc30b (plain)
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only

import { telemetry } from 'qt-lib';
import * as vscode from 'vscode';

interface WASMStartTaskDefinition extends vscode.TaskDefinition {
  /**
   * The task name
   */
  task: string;
}

// This is a dummy terminal that does nothing.
// Since vscode.CustomExecution expects a callback which returns a
// Pseudoterminal, we need to provide one. That's why we have this dummy
// terminal class.
export class DummyTaskTerminal implements vscode.Pseudoterminal {
  private readonly _writeEmitter = new vscode.EventEmitter<string>();
  private readonly _closeEmitter = new vscode.EventEmitter<number>();

  public get onDidWrite() {
    return this._writeEmitter.event;
  }
  public get onDidClose() {
    return this._closeEmitter.event;
  }
  open() {
    this.close();
  }
  close() {
    this._closeEmitter.fire(0);
  }
}

export class WASMStartTaskProvider implements vscode.TaskProvider {
  static WASMStartType = 'Qt';
  private static getTask(taskDefinition: WASMStartTaskDefinition): vscode.Task {
    const taskCallback = async (
      callbacktaskDefinition: vscode.TaskDefinition
    ) => {
      void callbacktaskDefinition;
      const dummyTaskTerminal = new DummyTaskTerminal();
      const checkExtension = async (extensionId: string) => {
        const extension = vscode.extensions.getExtension(extensionId);
        if (extension) {
          if (!extension.isActive) {
            await extension.activate();
          }
          return true;
        } else {
          const message =
            `The extension ${extensionId} is required to debug ` +
            `Qt WebAssembly applications. Do you want to install it?`;
          void vscode.window
            .showInformationMessage(message, 'Install')
            .then((selection) => {
              if (selection === 'Install') {
                telemetry.sendAction('wasm.start.installExtension');
                const action = 'workbench.extensions.installExtension';
                const extensionName = extensionId;
                void vscode.commands.executeCommand(action, extensionName);
              }
            });
          return false;
        }
      };
      const dependentExtensions = [
        'ms-vscode.wasm-dwarf-debugging',
        'ms-vscode.live-server'
      ];
      const extensionPromises = dependentExtensions.map(checkExtension);
      const extensionResults = await Promise.all(extensionPromises);
      if (!extensionResults.includes(false)) {
        void vscode.commands.executeCommand('livePreview.runServerLoggingTask');
      }
      return Promise.resolve(dummyTaskTerminal);
    };
    const WASMStartTask = new vscode.Task(
      taskDefinition,
      vscode.TaskScope.Workspace,
      'WASM Start',
      'Qt',
      new vscode.CustomExecution(taskCallback)
    );
    return WASMStartTask;
  }
  // eslint-disable-next-line @typescript-eslint/class-methods-use-this
  public provideTasks(): vscode.Task[] {
    const result: vscode.Task[] = [];
    const taskDefinition: WASMStartTaskDefinition = {
      type: WASMStartTaskProvider.WASMStartType,
      task: 'WASMStart'
    };
    const WASMStartTask = WASMStartTaskProvider.getTask(taskDefinition);
    result.push(WASMStartTask);
    return result;
  }
  // eslint-disable-next-line @typescript-eslint/class-methods-use-this
  public resolveTask(_task: vscode.Task): vscode.Task | undefined {
    const definition: WASMStartTaskDefinition =
      _task.definition as WASMStartTaskDefinition;
    return WASMStartTaskProvider.getTask(definition);
  }
}

export const wasmStartTaskProvider = new WASMStartTaskProvider();