Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-ng/display/src/lib/services/geometry-post-processing.service.ts is written in an unsupported language. File is not indexed.

0001 import { Injectable, Injector, inject } from '@angular/core';
0002 import {
0003   GEOMETRY_POST_PROCESSORS,
0004   GeometryPostProcessContext,
0005   GeometryPostProcessor,
0006   orderGeometryPostProcessors,
0007 } from '@dexvis/firebird-ng/api';
0008 
0009 /** A post-processor that could not run, with the reason. */
0010 export interface GeometryPostProcessFailure {
0011   id: string;
0012   error: unknown;
0013 }
0014 
0015 /**
0016  * Runs the registered geometry post-processors (`withGeometryPostProcessor`)
0017  * on a freshly loaded geometry, in their declared order. Each processor
0018  * class loads on the first geometry load and is instantiated once, through a
0019  * child injector so `inject()` works in its constructor.
0020  *
0021  * A failing processor does not stop the others or the load: the geometry
0022  * shows without that processor's changes, and the failure is returned for
0023  * the caller to report.
0024  */
0025 @Injectable({ providedIn: 'root' })
0026 export class GeometryPostProcessingService {
0027   private readonly injector = inject(Injector);
0028   private readonly registrations = inject(GEOMETRY_POST_PROCESSORS, { optional: true }) ?? [];
0029   private processors: Promise<Array<{ id: string; processor: GeometryPostProcessor | null; error?: unknown }>> | null = null;
0030 
0031   /** Runs every processor on `context`; resolves with the failures. */
0032   async process(context: GeometryPostProcessContext): Promise<GeometryPostProcessFailure[]> {
0033     const failures: GeometryPostProcessFailure[] = [];
0034     for (const { id, processor, error } of await this.resolveProcessors()) {
0035       if (!processor) {
0036         failures.push({ id, error });
0037         continue;
0038       }
0039       try {
0040         await processor.process(context);
0041       } catch (processError) {
0042         failures.push({ id, error: processError });
0043       }
0044     }
0045     return failures;
0046   }
0047 
0048   private resolveProcessors() {
0049     this.processors ??= (async () => {
0050       // An `after` cycle is a registration mistake: report it once per
0051       // processor and run none of them instead of guessing an order
0052       let ordered;
0053       try {
0054         ordered = orderGeometryPostProcessors(this.registrations);
0055       } catch (error) {
0056         return this.registrations.map(registration => ({ id: registration.id, processor: null, error }));
0057       }
0058       return Promise.all(ordered.map(async registration => {
0059         try {
0060           const processorClass = await registration.load();
0061           const child = Injector.create({ providers: [processorClass], parent: this.injector });
0062           return { id: registration.id, processor: child.get(processorClass) };
0063         } catch (error) {
0064           return { id: registration.id, processor: null, error };
0065         }
0066       }));
0067     })();
0068     return this.processors;
0069   }
0070 }