Reimplemented sketchbook watcher.

Moved it to the frontend.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
Akos Kitta
2021-02-02 11:48:52 +01:00
committed by Akos Kitta
parent 911875665d
commit b1ab6df8b7
17 changed files with 147 additions and 541 deletions

View File

@@ -5,9 +5,13 @@ import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { MessageService } from '@theia/core/lib/common/message-service';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { Sketch, SketchesService } from '../../common/protocol';
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { ConfigService } from './config-service';
import { DisposableCollection, Emitter } from '@theia/core';
import { FileChangeType } from '@theia/filesystem/lib/browser';
@injectable()
export class SketchesServiceClientImpl {
export class SketchesServiceClientImpl implements FrontendApplicationContribution {
@inject(FileService)
protected readonly fileService: FileService;
@@ -21,6 +25,58 @@ export class SketchesServiceClientImpl {
@inject(WorkspaceService)
protected readonly workspaceService: WorkspaceService;
@inject(ConfigService)
protected readonly configService: ConfigService;
protected toDispose = new DisposableCollection();
protected sketches = new Map<string, Sketch>();
protected sketchbookDidChangeEmitter = new Emitter<{ created: Sketch[], removed: Sketch[] }>();
readonly onSketchbookDidChange = this.sketchbookDidChangeEmitter.event;
onStart(): void {
this.configService.getConfiguration().then(({ sketchDirUri }) => {
this.sketchService.getSketches(sketchDirUri).then(sketches => {
const sketchbookUri = new URI(sketchDirUri);
for (const sketch of sketches) {
this.sketches.set(sketch.uri, sketch);
}
this.toDispose.push(this.fileService.watch(new URI(sketchDirUri), { recursive: true, excludes: [] }));
this.toDispose.push(this.fileService.onDidFilesChange(async event => {
for (const { type, resource } of event.changes) {
// We track main sketch files changes only.
if (sketchbookUri.isEqualOrParent(resource)) {
const { ext } = resource.path; // TODO: add support for `.pde`.
if (ext === '.ino') {
if (type === FileChangeType.ADDED) {
try {
const toAdd = await this.sketchService.loadSketch(resource.parent.toString());
if (!this.sketches.has(toAdd.uri)) {
console.log(`New sketch '${toAdd.name}' was crated in sketchbook '${sketchDirUri}'.`);
this.sketches.set(toAdd.uri, toAdd);
this.fireSoon(toAdd, 'created');
}
} catch { }
} else if (type === FileChangeType.DELETED) {
const uri = resource.parent.toString();
const toDelete = this.sketches.get(uri);
if (toDelete) {
console.log(`Sketch '${toDelete.name}' was removed from sketchbook '${sketchbookUri}'.`);
this.sketches.delete(uri);
this.fireSoon(toDelete, 'removed');
}
}
}
}
}
}));
});
});
}
onStop(): void {
this.toDispose.dispose();
}
async currentSketch(): Promise<Sketch | undefined> {
const sketches = (await Promise.all(this.workspaceService.tryGetRoots().map(({ resource }) => this.sketchService.getSketchFolder(resource.toString())))).filter(notEmpty);
if (!sketches.length) {
@@ -46,4 +102,31 @@ export class SketchesServiceClientImpl {
return undefined;
}
private fireSoonHandle?: number;
private bufferedSketchbookEvents: { type: 'created' | 'removed', sketch: Sketch }[] = [];
private fireSoon(sketch: Sketch, type: 'created' | 'removed'): void {
this.bufferedSketchbookEvents.push({ type, sketch });
if (typeof this.fireSoonHandle === 'number') {
window.clearTimeout(this.fireSoonHandle);
}
this.fireSoonHandle = window.setTimeout(() => {
const event: { created: Sketch[], removed: Sketch[] } = {
created: [],
removed: []
};
for (const { type, sketch } of this.bufferedSketchbookEvents) {
if (type === 'created') {
event.created.push(sketch);
} else {
event.removed.push(sketch);
}
}
this.sketchbookDidChangeEmitter.fire(event);
this.bufferedSketchbookEvents.length = 0;
}, 100);
}
}