All files / src/app/components/petri petri.component.ts

78.37% Statements 29/37
66.66% Branches 8/12
66.66% Functions 10/15
76.47% Lines 26/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106                                  62x             3x 3x       3x         2x 2x   2x 2x   5x 4x 2x     2x         2x                 2x 1x 1x 1x   1x 1x       1x               2x 2x       1x 1x 1x                   18x                      
import { Component, ViewChild, ElementRef, OnInit, Input } from '@angular/core';
import { PetriNetwork, Place, Transition, PetriNode } from '../../models/petri';
import { Canvas } from '../../models/canvas';
import { ActivatedRoute } from '@angular/router';
import { NgIf, NgFor } from '@angular/common';
import { Drawer } from 'primeng/drawer';
import { ErrorComponent } from '../error/error.component';
import { HttpErrorResponse } from '@angular/common/http';
import { Device } from '../../models/devices';
import { TwinpadApiService } from '../../services/twinpad-api.service';
 
@Component({
    selector: 'app-petri',
    imports: [NgIf, NgFor, Drawer, ErrorComponent],
    templateUrl: './petri.component.html',
    styleUrl: './petri.component.scss'
})
export class PetriComponent implements OnInit{
  @Input() deviceId: string;
  @ViewChild('petriCanvas', { static: true }) petriCanvas!: ElementRef<HTMLCanvasElement>;
  petriNetwork: PetriNetwork;
  private context!: CanvasRenderingContext2D;
  canvas: Canvas;
  device_id: string;
  displayInfo: boolean = false;
  displayType: string = "";
  displayedNode: PetriNode;
  error: HttpErrorResponse;
 
  constructor(private twinpadApiService: TwinpadApiService, private route: ActivatedRoute){
 
  }
 
  ngOnInit(){
    this.petriCanvas.nativeElement.addEventListener('wheel', this.preventScroll, { passive: false });
    this.context = this.petriCanvas.nativeElement.getContext('2d')!;
 
    this.device_id = this.route.snapshot.params['device_id'] || this.deviceId;
    this.twinpadApiService.devicesBehaviorSubject$.subscribe({
      next: devices => {
        const device = devices.find(device => device.device_id === this.device_id);
        if (device !== undefined) {
          this.setupPetri(device);
        }
        else {
          this.twinpadApiService.getDevice(this.device_id).subscribe({
            next: device => {
              this.setupPetri(device);
            },
            error: error => {
              this.error = error;
            }
          });
        }
      }
    });
  }
 
  setupPetri(device: Device) {
    if (this.petriNetwork === undefined){
      this.petriNetwork = PetriNetwork.deserialize(device['petri_network']);
      this.canvas = new Canvas(this.context, this.petriNetwork);
      this.petriNetwork.selectedPlace.subscribe({
        next: (place) => {
          Eif (place !== null) {
            this.showPlaceInfo(place);
          }
        }
      });
      this.petriNetwork.selectedTransition.subscribe({
        next: (transition) => {
          if (transition !== null) {
            this.showTransitionInfo(transition);
          }
        }
      });
    }
    this.petriNetwork.tokens = device.tokens;
    this.canvas.draw();
  }
 
  showPlaceInfo(place: Place) {
    this.displayInfo = true;
    this.displayType = "place";
    this.displayedNode = place;
  }
 
  showTransitionInfo(transition: Transition) {
    this.displayInfo = true;
    this.displayType = "transition";
    this.displayedNode = transition;
  }
 
  asPlace(node: PetriNode): Place {
    return node as Place;
  }
 
  asTransition(node: PetriNode): Transition {
    return node as Transition;
  }
 
  preventScroll(event: WheelEvent) {
    event.preventDefault();
  }
}