diff options
Diffstat (limited to 'subprojects/frontend/src/editor/EditorStore.ts')
-rw-r--r-- | subprojects/frontend/src/editor/EditorStore.ts | 132 |
1 files changed, 119 insertions, 13 deletions
diff --git a/subprojects/frontend/src/editor/EditorStore.ts b/subprojects/frontend/src/editor/EditorStore.ts index b98f085e..9508858d 100644 --- a/subprojects/frontend/src/editor/EditorStore.ts +++ b/subprojects/frontend/src/editor/EditorStore.ts | |||
@@ -26,9 +26,13 @@ import { makeAutoObservable, observable, runInAction } from 'mobx'; | |||
26 | import { nanoid } from 'nanoid'; | 26 | import { nanoid } from 'nanoid'; |
27 | 27 | ||
28 | import type PWAStore from '../PWAStore'; | 28 | import type PWAStore from '../PWAStore'; |
29 | import GraphStore from '../graph/GraphStore'; | ||
29 | import getLogger from '../utils/getLogger'; | 30 | import getLogger from '../utils/getLogger'; |
30 | import type XtextClient from '../xtext/XtextClient'; | 31 | import type XtextClient from '../xtext/XtextClient'; |
32 | import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults'; | ||
31 | 33 | ||
34 | import EditorErrors from './EditorErrors'; | ||
35 | import GeneratedModelStore from './GeneratedModelStore'; | ||
32 | import LintPanelStore from './LintPanelStore'; | 36 | import LintPanelStore from './LintPanelStore'; |
33 | import SearchPanelStore from './SearchPanelStore'; | 37 | import SearchPanelStore from './SearchPanelStore'; |
34 | import createEditorState from './createEditorState'; | 38 | import createEditorState from './createEditorState'; |
@@ -54,13 +58,26 @@ export default class EditorStore { | |||
54 | 58 | ||
55 | readonly lintPanel: LintPanelStore; | 59 | readonly lintPanel: LintPanelStore; |
56 | 60 | ||
61 | readonly delayedErrors: EditorErrors; | ||
62 | |||
57 | showLineNumbers = false; | 63 | showLineNumbers = false; |
58 | 64 | ||
59 | disposed = false; | 65 | disposed = false; |
60 | 66 | ||
67 | analyzing = false; | ||
68 | |||
69 | semanticsError: string | undefined; | ||
70 | |||
71 | graph: GraphStore; | ||
72 | |||
73 | generatedModels = new Map<string, GeneratedModelStore>(); | ||
74 | |||
75 | selectedGeneratedModel: string | undefined; | ||
76 | |||
61 | constructor(initialValue: string, pwaStore: PWAStore) { | 77 | constructor(initialValue: string, pwaStore: PWAStore) { |
62 | this.id = nanoid(); | 78 | this.id = nanoid(); |
63 | this.state = createEditorState(initialValue, this); | 79 | this.state = createEditorState(initialValue, this); |
80 | this.delayedErrors = new EditorErrors(this); | ||
64 | this.searchPanel = new SearchPanelStore(this); | 81 | this.searchPanel = new SearchPanelStore(this); |
65 | this.lintPanel = new LintPanelStore(this); | 82 | this.lintPanel = new LintPanelStore(this); |
66 | (async () => { | 83 | (async () => { |
@@ -75,6 +92,7 @@ export default class EditorStore { | |||
75 | })().catch((error) => { | 92 | })().catch((error) => { |
76 | log.error('Failed to load XtextClient', error); | 93 | log.error('Failed to load XtextClient', error); |
77 | }); | 94 | }); |
95 | this.graph = new GraphStore(); | ||
78 | makeAutoObservable<EditorStore, 'client'>(this, { | 96 | makeAutoObservable<EditorStore, 'client'>(this, { |
79 | id: false, | 97 | id: false, |
80 | state: observable.ref, | 98 | state: observable.ref, |
@@ -213,19 +231,6 @@ export default class EditorStore { | |||
213 | this.doCommand(nextDiagnostic); | 231 | this.doCommand(nextDiagnostic); |
214 | } | 232 | } |
215 | 233 | ||
216 | get highestDiagnosticLevel(): Diagnostic['severity'] | undefined { | ||
217 | if (this.errorCount > 0) { | ||
218 | return 'error'; | ||
219 | } | ||
220 | if (this.warningCount > 0) { | ||
221 | return 'warning'; | ||
222 | } | ||
223 | if (this.infoCount > 0) { | ||
224 | return 'info'; | ||
225 | } | ||
226 | return undefined; | ||
227 | } | ||
228 | |||
229 | updateSemanticHighlighting(ranges: IHighlightRange[]): void { | 234 | updateSemanticHighlighting(ranges: IHighlightRange[]): void { |
230 | this.dispatch(setSemanticHighlighting(ranges)); | 235 | this.dispatch(setSemanticHighlighting(ranges)); |
231 | } | 236 | } |
@@ -282,8 +287,109 @@ export default class EditorStore { | |||
282 | return true; | 287 | return true; |
283 | } | 288 | } |
284 | 289 | ||
290 | analysisStarted() { | ||
291 | this.analyzing = true; | ||
292 | } | ||
293 | |||
294 | analysisCompleted(semanticAnalysisSkipped = false) { | ||
295 | this.analyzing = false; | ||
296 | if (semanticAnalysisSkipped) { | ||
297 | this.semanticsError = undefined; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | setSemanticsError(semanticsError: string) { | ||
302 | this.semanticsError = semanticsError; | ||
303 | } | ||
304 | |||
305 | setSemantics(semantics: SemanticsSuccessResult) { | ||
306 | this.semanticsError = undefined; | ||
307 | this.graph.setSemantics(semantics); | ||
308 | } | ||
309 | |||
285 | dispose(): void { | 310 | dispose(): void { |
286 | this.client?.dispose(); | 311 | this.client?.dispose(); |
312 | this.delayedErrors.dispose(); | ||
287 | this.disposed = true; | 313 | this.disposed = true; |
288 | } | 314 | } |
315 | |||
316 | startModelGeneration(randomSeed?: number): void { | ||
317 | this.client | ||
318 | ?.startModelGeneration(randomSeed) | ||
319 | ?.catch((error) => log.error('Could not start model generation', error)); | ||
320 | } | ||
321 | |||
322 | addGeneratedModel(uuid: string, randomSeed: number): void { | ||
323 | this.generatedModels.set(uuid, new GeneratedModelStore(randomSeed)); | ||
324 | this.selectGeneratedModel(uuid); | ||
325 | } | ||
326 | |||
327 | cancelModelGeneration(): void { | ||
328 | this.client | ||
329 | ?.cancelModelGeneration() | ||
330 | ?.catch((error) => log.error('Could not start model generation', error)); | ||
331 | } | ||
332 | |||
333 | selectGeneratedModel(uuid: string | undefined): void { | ||
334 | if (uuid === undefined) { | ||
335 | this.selectedGeneratedModel = uuid; | ||
336 | return; | ||
337 | } | ||
338 | if (this.generatedModels.has(uuid)) { | ||
339 | this.selectedGeneratedModel = uuid; | ||
340 | return; | ||
341 | } | ||
342 | this.selectedGeneratedModel = undefined; | ||
343 | } | ||
344 | |||
345 | deleteGeneratedModel(uuid: string | undefined): void { | ||
346 | if (uuid === undefined) { | ||
347 | return; | ||
348 | } | ||
349 | if (this.selectedGeneratedModel === uuid) { | ||
350 | let previous: string | undefined; | ||
351 | let found: string | undefined; | ||
352 | this.generatedModels.forEach((_value, key) => { | ||
353 | if (key === uuid) { | ||
354 | found = previous; | ||
355 | } | ||
356 | previous = key; | ||
357 | }); | ||
358 | this.selectGeneratedModel(found); | ||
359 | } | ||
360 | const generatedModel = this.generatedModels.get(uuid); | ||
361 | if (generatedModel !== undefined && generatedModel.running) { | ||
362 | this.cancelModelGeneration(); | ||
363 | } | ||
364 | this.generatedModels.delete(uuid); | ||
365 | } | ||
366 | |||
367 | modelGenerationCancelled(): void { | ||
368 | this.generatedModels.forEach((value) => | ||
369 | value.setError('Model generation cancelled'), | ||
370 | ); | ||
371 | } | ||
372 | |||
373 | setGeneratedModelMessage(uuid: string, message: string): void { | ||
374 | this.generatedModels.get(uuid)?.setMessage(message); | ||
375 | } | ||
376 | |||
377 | setGeneratedModelError(uuid: string, message: string): void { | ||
378 | this.generatedModels.get(uuid)?.setError(message); | ||
379 | } | ||
380 | |||
381 | setGeneratedModelSemantics( | ||
382 | uuid: string, | ||
383 | semantics: SemanticsSuccessResult, | ||
384 | ): void { | ||
385 | this.generatedModels.get(uuid)?.setSemantics(semantics); | ||
386 | } | ||
387 | |||
388 | get generating(): boolean { | ||
389 | let generating = false; | ||
390 | this.generatedModels.forEach((value) => { | ||
391 | generating = generating || value.running; | ||
392 | }); | ||
393 | return generating; | ||
394 | } | ||
289 | } | 395 | } |