xref: /aosp_15_r20/external/pigweed/pw_ide/ts/pigweed-vscode/src/events.ts (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15import { EventEmitter } from 'vscode';
16
17import { Disposer } from './disposables';
18
19import {
20  OK,
21  RefreshCallback,
22  RefreshManager,
23  RefreshStatus,
24} from './refreshManager';
25
26/** Event emitted on extension load. */
27export const didInit = new EventEmitter<void>();
28
29/** Event emitted when the code analysis target is changed. */
30export const didChangeTarget = new EventEmitter<string>();
31
32/** Event emitted when the active files cache has been updated. */
33export const didUpdateActiveFilesCache = new EventEmitter<void>();
34
35/** Event emitted whenever the `clangd` configuration is changed. */
36export const didChangeClangdConfig = new EventEmitter<void>();
37
38/** Event emitted when the refresh manager state changes. */
39export const didChangeRefreshStatus = new EventEmitter<RefreshStatus>();
40
41/**
42 * Helper for subscribing to events.
43 *
44 * This lets you register the event callback and add the resulting handler to
45 * a disposer in one call.
46 */
47export function subscribe<T>(
48  event: EventEmitter<T>,
49  cb: (data: T) => void,
50  disposer: Disposer,
51): void {
52  disposer.add(event.event(cb));
53}
54
55/**
56 * Helper for linking refresh manager state changes to VSC events.
57 *
58 * Given a refresh manager state, it returns a tuple containing a refresh
59 * callback that fires the event, and the same status you provided. This just
60 * makes it easier to spread those arguments to the refresh manager callback
61 * register function.
62 */
63const fireDidChangeRefreshStatus = (
64  status: RefreshStatus,
65): [RefreshCallback, RefreshStatus] => {
66  const cb: RefreshCallback = () => {
67    didChangeRefreshStatus.fire(status);
68    return OK;
69  };
70
71  return [cb, status];
72};
73
74/**
75 * Link the refresh manager state machine to the VSC event system.
76 *
77 * The refresh manager needs to remain editor-agnostic so it can be used outside
78 * of VSC. It also has a more constrained event system that isn't completely
79 * represented by the VSC event system. This function links the two, such that
80 * any refresh manager state changes also trigger a VSC event that can be
81 * subscribed to by things that need to be notified or updated when the refresh
82 * manager runs, but don't need to be integrated into the refresh manager
83 * itself.
84 */
85export function linkRefreshManagerToEvents(
86  refreshManager: RefreshManager<any>,
87) {
88  refreshManager.on(...fireDidChangeRefreshStatus('idle'));
89  refreshManager.on(...fireDidChangeRefreshStatus('willRefresh'));
90  refreshManager.on(...fireDidChangeRefreshStatus('refreshing'));
91  refreshManager.on(...fireDidChangeRefreshStatus('didRefresh'));
92  refreshManager.on(...fireDidChangeRefreshStatus('abort'));
93  refreshManager.on(...fireDidChangeRefreshStatus('fault'));
94}
95