Skip to content

Commit b1ab6df

Browse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
Reimplemented sketchbook watcher.
Moved it to the frontend. Signed-off-by: Akos Kitta <[email protected]>
1 parent 9118756 commit b1ab6df

17 files changed

+147
-541
lines changed

Diff for: arduino-ide-extension/data/cli/schema/arduino-cli.schema.json

-136
This file was deleted.

Diff for: arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
181181
// Sketch list service
182182
bind(SketchesService).toDynamicValue(context => WebSocketConnectionProvider.createProxy(context.container, SketchesServicePath)).inSingletonScope();
183183
bind(SketchesServiceClientImpl).toSelf().inSingletonScope();
184+
bind(FrontendApplicationContribution).toService(SketchesServiceClientImpl);
184185

185186
// Config service
186187
bind(ConfigService).toDynamicValue(context => WebSocketConnectionProvider.createProxy(context.container, ConfigServicePath)).inSingletonScope();

Diff for: arduino-ide-extension/src/browser/contributions/sketchbook.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class Sketchbook extends SketchContribution {
2828
this.register(sketches);
2929
this.mainMenuManager.update();
3030
});
31-
this.notificationCenter.onSketchbookChanged(({ created, removed }) => {
31+
this.sketchServiceClient.onSketchbookDidChange(({ created, removed }) => {
3232
this.unregister(removed);
3333
this.register(created);
3434
this.mainMenuManager.update();

Diff for: arduino-ide-extension/src/browser/notification-center.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ export class NotificationCenter implements NotificationServiceClient, FrontendAp
2121
protected readonly libraryInstalledEmitter = new Emitter<{ item: LibraryPackage }>();
2222
protected readonly libraryUninstalledEmitter = new Emitter<{ item: LibraryPackage }>();
2323
protected readonly attachedBoardsChangedEmitter = new Emitter<AttachedBoardsChangeEvent>();
24-
protected readonly sketchbookChangedEmitter = new Emitter<{ created: Sketch[], removed: Sketch[] }>();
2524
protected readonly recentSketchesChangedEmitter = new Emitter<{ sketches: Sketch[] }>();
2625

2726
protected readonly toDispose = new DisposableCollection(
@@ -33,8 +32,7 @@ export class NotificationCenter implements NotificationServiceClient, FrontendAp
3332
this.platformUninstalledEmitter,
3433
this.libraryInstalledEmitter,
3534
this.libraryUninstalledEmitter,
36-
this.attachedBoardsChangedEmitter,
37-
this.sketchbookChangedEmitter
35+
this.attachedBoardsChangedEmitter
3836
);
3937

4038
readonly onIndexUpdated = this.indexUpdatedEmitter.event;
@@ -46,7 +44,6 @@ export class NotificationCenter implements NotificationServiceClient, FrontendAp
4644
readonly onLibraryInstalled = this.libraryInstalledEmitter.event;
4745
readonly onLibraryUninstalled = this.libraryUninstalledEmitter.event;
4846
readonly onAttachedBoardsChanged = this.attachedBoardsChangedEmitter.event;
49-
readonly onSketchbookChanged = this.sketchbookChangedEmitter.event;
5047
readonly onRecentSketchesChanged = this.recentSketchesChangedEmitter.event;
5148

5249
@postConstruct()
@@ -94,10 +91,6 @@ export class NotificationCenter implements NotificationServiceClient, FrontendAp
9491
this.attachedBoardsChangedEmitter.fire(event);
9592
}
9693

97-
notifySketchbookChanged(event: { created: Sketch[], removed: Sketch[] }): void {
98-
this.sketchbookChangedEmitter.fire(event);
99-
}
100-
10194
notifyRecentSketchesChanged(event: { sketches: Sketch[] }): void {
10295
this.recentSketchesChangedEmitter.fire(event);
10396
}

Diff for: arduino-ide-extension/src/common/protocol/config-service.ts

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export interface ConfigService {
44
getVersion(): Promise<Readonly<{ version: string, commit: string, status?: string }>>;
55
getConfiguration(): Promise<Config>;
66
setConfiguration(config: Config): Promise<void>;
7-
getConfigurationFileSchemaUri(): Promise<string>;
87
isInDataDir(uri: string): Promise<boolean>;
98
isInSketchDir(uri: string): Promise<boolean>;
109
}

Diff for: arduino-ide-extension/src/common/protocol/notification-service.ts

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export interface NotificationServiceClient {
1212
notifyLibraryInstalled(event: { item: LibraryPackage }): void;
1313
notifyLibraryUninstalled(event: { item: LibraryPackage }): void;
1414
notifyAttachedBoardsChanged(event: AttachedBoardsChangeEvent): void;
15-
notifySketchbookChanged(event: { created: Sketch[], removed: Sketch[] }): void;
1615
notifyRecentSketchesChanged(event: { sketches: Sketch[] }): void;
1716
}
1817

Diff for: arduino-ide-extension/src/common/protocol/sketches-service-client-impl.ts

+84-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import { FileService } from '@theia/filesystem/lib/browser/file-service';
55
import { MessageService } from '@theia/core/lib/common/message-service';
66
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
77
import { Sketch, SketchesService } from '../../common/protocol';
8+
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
9+
import { ConfigService } from './config-service';
10+
import { DisposableCollection, Emitter } from '@theia/core';
11+
import { FileChangeType } from '@theia/filesystem/lib/browser';
812

913
@injectable()
10-
export class SketchesServiceClientImpl {
14+
export class SketchesServiceClientImpl implements FrontendApplicationContribution {
1115

1216
@inject(FileService)
1317
protected readonly fileService: FileService;
@@ -21,6 +25,58 @@ export class SketchesServiceClientImpl {
2125
@inject(WorkspaceService)
2226
protected readonly workspaceService: WorkspaceService;
2327

28+
@inject(ConfigService)
29+
protected readonly configService: ConfigService;
30+
31+
protected toDispose = new DisposableCollection();
32+
protected sketches = new Map<string, Sketch>();
33+
protected sketchbookDidChangeEmitter = new Emitter<{ created: Sketch[], removed: Sketch[] }>();
34+
readonly onSketchbookDidChange = this.sketchbookDidChangeEmitter.event;
35+
36+
onStart(): void {
37+
this.configService.getConfiguration().then(({ sketchDirUri }) => {
38+
this.sketchService.getSketches(sketchDirUri).then(sketches => {
39+
const sketchbookUri = new URI(sketchDirUri);
40+
for (const sketch of sketches) {
41+
this.sketches.set(sketch.uri, sketch);
42+
}
43+
this.toDispose.push(this.fileService.watch(new URI(sketchDirUri), { recursive: true, excludes: [] }));
44+
this.toDispose.push(this.fileService.onDidFilesChange(async event => {
45+
for (const { type, resource } of event.changes) {
46+
// We track main sketch files changes only.
47+
if (sketchbookUri.isEqualOrParent(resource)) {
48+
const { ext } = resource.path; // TODO: add support for `.pde`.
49+
if (ext === '.ino') {
50+
if (type === FileChangeType.ADDED) {
51+
try {
52+
const toAdd = await this.sketchService.loadSketch(resource.parent.toString());
53+
if (!this.sketches.has(toAdd.uri)) {
54+
console.log(`New sketch '${toAdd.name}' was crated in sketchbook '${sketchDirUri}'.`);
55+
this.sketches.set(toAdd.uri, toAdd);
56+
this.fireSoon(toAdd, 'created');
57+
}
58+
} catch { }
59+
} else if (type === FileChangeType.DELETED) {
60+
const uri = resource.parent.toString();
61+
const toDelete = this.sketches.get(uri);
62+
if (toDelete) {
63+
console.log(`Sketch '${toDelete.name}' was removed from sketchbook '${sketchbookUri}'.`);
64+
this.sketches.delete(uri);
65+
this.fireSoon(toDelete, 'removed');
66+
}
67+
}
68+
}
69+
}
70+
}
71+
}));
72+
});
73+
});
74+
}
75+
76+
onStop(): void {
77+
this.toDispose.dispose();
78+
}
79+
2480
async currentSketch(): Promise<Sketch | undefined> {
2581
const sketches = (await Promise.all(this.workspaceService.tryGetRoots().map(({ resource }) => this.sketchService.getSketchFolder(resource.toString())))).filter(notEmpty);
2682
if (!sketches.length) {
@@ -46,4 +102,31 @@ export class SketchesServiceClientImpl {
46102
return undefined;
47103
}
48104

105+
private fireSoonHandle?: number;
106+
private bufferedSketchbookEvents: { type: 'created' | 'removed', sketch: Sketch }[] = [];
107+
108+
private fireSoon(sketch: Sketch, type: 'created' | 'removed'): void {
109+
this.bufferedSketchbookEvents.push({ type, sketch });
110+
111+
if (typeof this.fireSoonHandle === 'number') {
112+
window.clearTimeout(this.fireSoonHandle);
113+
}
114+
115+
this.fireSoonHandle = window.setTimeout(() => {
116+
const event: { created: Sketch[], removed: Sketch[] } = {
117+
created: [],
118+
removed: []
119+
};
120+
for (const { type, sketch } of this.bufferedSketchbookEvents) {
121+
if (type === 'created') {
122+
event.created.push(sketch);
123+
} else {
124+
event.removed.push(sketch);
125+
}
126+
}
127+
this.sketchbookDidChangeEmitter.fire(event);
128+
this.bufferedSketchbookEvents.length = 0;
129+
}, 100);
130+
}
131+
49132
}

Diff for: arduino-ide-extension/src/node/arduino-ide-backend-module.ts

-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import { MonitorClientProvider } from './monitor/monitor-client-provider';
2323
import { ConfigServiceImpl } from './config-service-impl';
2424
import { HostedPluginReader } from './theia/plugin-ext/plugin-reader';
2525
import { HostedPluginReader as TheiaHostedPluginReader } from '@theia/plugin-ext/lib/hosted/node/plugin-reader';
26-
import { ConfigFileValidator } from './config-file-validator';
2726
import { EnvVariablesServer as TheiaEnvVariablesServer } from '@theia/core/lib/common/env-variables';
2827
import { EnvVariablesServer } from './theia/env-variables/env-variables-server';
2928
import { NodeFileSystemExt } from './node-filesystem-ext';
@@ -43,7 +42,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
4342
rebind(TheiaBackendApplication).toService(BackendApplication);
4443

4544
// Shared config service
46-
bind(ConfigFileValidator).toSelf().inSingletonScope();
4745
bind(ConfigServiceImpl).toSelf().inSingletonScope();
4846
bind(ConfigService).toService(ConfigServiceImpl);
4947
// Note: The config service must start earlier than the daemon, hence the binding order of the BA contribution does matter.

Diff for: arduino-ide-extension/src/node/cli-config.ts

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import { join } from 'path';
21
import { RecursivePartial } from '@theia/core/lib/common/types';
32

43
export const CLI_CONFIG = 'arduino-cli.yaml';
5-
export const CLI_CONFIG_SCHEMA = 'arduino-cli.schema.json';
6-
export const CLI_CONFIG_SCHEMA_PATH = join(__dirname, '..', '..', 'data', 'cli', 'schema', CLI_CONFIG_SCHEMA);
74

85
export interface BoardManager {
96
readonly additional_urls: Array<string>;

Diff for: arduino-ide-extension/src/node/config-file-validator.ts

-60
This file was deleted.

0 commit comments

Comments
 (0)