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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 112x 3x 3x 3x 3x 3x 2x 2x 2x 2x 5x 3x 1x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 109x | import { Component, ViewChild, ElementRef, OnInit, Input, inject } from '@angular/core';
import { PetriNetwork, Place, Transition, PetriNode, PetriNetworkInterface } from '../../models/petri';
import { Canvas } from '../../models/canvas';
import { ActivatedRoute } from '@angular/router';
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';
import { EmptyPlaceholderComponent } from '../empty-placeholder/empty-placeholder.component';
@Component({
selector: 'app-petri',
imports: [Drawer, ErrorComponent, EmptyPlaceholderComponent],
templateUrl: './petri.component.html',
styleUrl: './petri.component.scss'
})
export class PetriComponent implements OnInit {
private twinpadApiService = inject(TwinpadApiService);
private route = inject(ActivatedRoute);
@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;
hideCanvas: boolean = false;
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;
this.hideCanvas = true;
}
});
}
}
});
}
setupPetri(device: Device) {
Eif (this.petriNetwork === undefined) {
Iif (device.petri_network === undefined || device.petri_network === null || PetriComponent.isPetriEmpty(device.petri_network)) {
this.hideCanvas = true;
return;
}
this.hideCanvas = false;
this.petriNetwork = PetriNetwork.deserialize(device['petri_network']);
this.canvas = new Canvas(this.context, this.petriNetwork);
this.petriNetwork.selectedPlace.subscribe({
next: (place) => {
if (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();
}
static isPetriEmpty(petriNet: PetriNetworkInterface) {
return (petriNet.input_arcs?.length ?? 0) === 0 &&
(petriNet.output_arcs?.length ?? 0) === 0 &&
(petriNet.places?.length ?? 0) === 0 &&
(petriNet.transitions?.length ?? 0) === 0;
}
}
|