Simple Visualization of ProductTransitions
All checks were successful
E2E Testing / test (push) Successful in 1m29s

This commit is contained in:
Sebastian Böckelmann 2024-02-16 17:29:19 +01:00
parent 78c992564e
commit fff4b6214f
9 changed files with 198 additions and 31 deletions

View File

@ -0,0 +1,35 @@
import {Gamesystem} from "../../../game-model/gamesystems/Gamesystem";
import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem";
import {ProductGamesystem} from "../../../game-model/gamesystems/ProductGamesystem";
import {State} from "../../../game-model/gamesystems/State";
import {ProductState} from "../../../game-model/gamesystems/ProductState";
import {SimpleState} from "../../../game-model/gamesystems/SimpleState";
export class LeafGamesystemCalculator {
static calcLeafGeamesystems(gamesystem: Gamesystem<any, any>) {
if(gamesystem instanceof SimpleGamesystem) {
return [gamesystem];
} else {
const product_gamesystem = gamesystem as ProductGamesystem;
const leaf_gamesystems: SimpleGamesystem[] = [];
product_gamesystem.innerGamesystems.forEach(innerGamesystem => {
LeafGamesystemCalculator.calcLeafGeamesystems(innerGamesystem).forEach(leafGamesystem => leaf_gamesystems.push(leafGamesystem))
})
return leaf_gamesystems;
}
}
static calcLeafStates(state: State<any>) {
if(state instanceof SimpleState) {
return [state];
} else {
const productState = state as ProductState;
const leafStates: SimpleState[] = [];
productState.innerStates.forEach(innerState => {
LeafGamesystemCalculator.calcLeafStates(innerState).forEach(leafState => leafStates.push(leafState));
})
return leafStates;
}
}
}

View File

@ -1 +1,2 @@
<app-product-state-editor [gamesystem]="gamesystem" (onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-state-editor>
<app-product-transition-editor [gamesystem]="gamesystem" (onOpenGamesystem)="onOpenGamesystemEditor($event)"></app-product-transition-editor>

View File

@ -2,12 +2,18 @@ import {Component, EventEmitter, Input, Output} from '@angular/core';
import {ProductGamesystem} from "../../../game-model/gamesystems/ProductGamesystem";
import {ProductStateEditorComponent} from "../state-editor/product-state-editor/product-state-editor.component";
import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem";
import {
ProductTransitionEditorComponent
} from "../transition-editor/product-transition-editor/product-transition-editor.component";
@Component({
selector: 'app-product-gamesystem-editor',
standalone: true,
imports: [
ProductStateEditorComponent
ProductStateEditorComponent,
ProductTransitionEditorComponent
],
templateUrl: './product-gamesystem-editor.component.html',
styleUrl: './product-gamesystem-editor.component.scss'

View File

@ -17,6 +17,7 @@ import {NgForOf, NgIf} from "@angular/common";
import {ProductState} from "../../../../game-model/gamesystems/ProductState";
import {MatIcon} from "@angular/material/icon";
import {Gamesystem} from "../../../../game-model/gamesystems/Gamesystem";
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
@Component({
selector: 'app-product-state-editor',
@ -67,38 +68,13 @@ export class ProductStateEditorComponent implements OnInit{
protected readonly SimpleState = SimpleState;
getLeafState(state: State<any>, i: number) {
return this.computeLeafStates(state)[i];
}
computeLeafStates(state: State<any>) {
if(state instanceof SimpleState) {
return [state];
} else {
const productState = state as ProductState;
const leafStates: SimpleState[] = [];
productState.innerStates.forEach(innerState => {
this.computeLeafStates(innerState).forEach(leafState => leafStates.push(leafState));
})
return leafStates;
}
return LeafGamesystemCalculator.calcLeafStates(state)[i];
}
clickOnInnerState(leafIndex: number) {
const leaf_gamesystems = this.computeLeafGamesystems(this.gamesystem!);
const leaf_gamesystems = LeafGamesystemCalculator.calcLeafGeamesystems(this.gamesystem!);
const clicked_gamesystem = leaf_gamesystems[leafIndex];
this.openGamesystemEditorEmitter.emit(clicked_gamesystem);
}
computeLeafGamesystems(gamesystem: Gamesystem<any, any>) {
if(gamesystem instanceof SimpleGamesystem) {
return [gamesystem];
} else {
const product_gamesystem = gamesystem as ProductGamesystem;
const leaf_gamesystems: SimpleGamesystem[] = [];
product_gamesystem.innerGamesystems.forEach(innerGamesystem => {
this.computeLeafGamesystems(innerGamesystem).forEach(leafGamesystem => leaf_gamesystems.push(leafGamesystem))
})
return leaf_gamesystems;
}
}
}

View File

@ -0,0 +1,42 @@
<table mat-table [dataSource]="dataSource">
<ng-container *ngFor="let col of displayedColumns; let i = index" [matColumnDef]="col.internalName">
<th mat-header-cell *matHeaderCellDef>{{col.displayedName}}</th>
<td mat-cell *matCellDef="let transition">
{{getLeafStateByIndex(transition, i).stateLabel}}
</td>
</ng-container>
<ng-container matColumnDef="header-row-sec-group">
<th
mat-header-cell
*matHeaderCellDef
[style.text-align]="'center'"
[attr.colspan]="numberLeafSystems"
class="start-end-col"
>
Starting State
</th>
</ng-container>
<ng-container matColumnDef="header-row-third-group">
<th
mat-header-cell
*matHeaderCellDef
[style.text-align]="'center'"
[attr.colspan]="numberLeafSystems"
>
Ending State
</th>
</ng-container>
<ng-container *ngIf="displayedColumns.length">
<tr
mat-header-row
*matHeaderRowDef="['header-row-sec-group', 'header-row-third-group']"
></tr>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columns;sticky:true"></tr>
<tr mat-row *matRowDef="let row; columns: columns;"></tr>
</table>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ProductTransitionEditorComponent } from './product-transition-editor.component';
describe('ProductTransitionEditorComponent', () => {
let component: ProductTransitionEditorComponent;
let fixture: ComponentFixture<ProductTransitionEditorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ProductTransitionEditorComponent]
})
.compileComponents();
fixture = TestBed.createComponent(ProductTransitionEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,87 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {ProductGamesystem} from "../../../../game-model/gamesystems/ProductGamesystem";
import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem";
import {
MatCell, MatCellDef,
MatColumnDef,
MatHeaderCell,
MatHeaderCellDef, MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef,
MatTable,
MatTableDataSource
} from "@angular/material/table";
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
import {NgForOf, NgIf} from "@angular/common";
import {ProductTransition} from "../../../../game-model/gamesystems/ProductTransition";
import {ProductState} from "../../../../game-model/gamesystems/ProductState";
class DisplayedColumnName {
displayedName: string
internalName: string
constructor(displayedName: string, internalName: string) {
this.displayedName = displayedName;
this.internalName = internalName;
}
}
@Component({
selector: 'app-product-transition-editor',
standalone: true,
imports: [
MatTable,
NgForOf,
MatColumnDef,
MatHeaderCell,
MatHeaderCellDef,
MatCell,
MatCellDef,
NgIf,
MatHeaderRow,
MatRow,
MatHeaderRowDef,
MatRowDef
],
templateUrl: './product-transition-editor.component.html',
styleUrl: './product-transition-editor.component.scss'
})
export class ProductTransitionEditorComponent implements OnInit{
@Input() gamesystem: ProductGamesystem | undefined
@Output() onOpenGamesystem = new EventEmitter<SimpleGamesystem>();
dataSource = new MatTableDataSource();
displayedColumns: DisplayedColumnName[] = [];
columns: string[] = [];
numberLeafSystems: number = -1;
ngOnInit() {
if(this.gamesystem != undefined) {
const leafGamesystems: SimpleGamesystem[] = LeafGamesystemCalculator.calcLeafGeamesystems(this.gamesystem);
this.displayedColumns = leafGamesystems.map(leafGamesystem => new DisplayedColumnName(leafGamesystem.componentName, leafGamesystem.componentName + "-start"));
this.displayedColumns = this.displayedColumns.concat( leafGamesystems.map(leafGamesystem => new DisplayedColumnName(leafGamesystem.componentName, leafGamesystem.componentName + "-end")));
this.numberLeafSystems = leafGamesystems.length;
this.columns = this.displayedColumns.map(column => column.internalName)
this.dataSource.data = this.gamesystem.transitions;
}
}
getLeafStateByIndex(transition: ProductTransition, leafIndex: number) {
let state: ProductState;
let index = leafIndex;
if(leafIndex < this.numberLeafSystems) {
state = transition.startingState
} else {
state = transition.endingState;
index = leafIndex - this.numberLeafSystems;
}
const leafStates = LeafGamesystemCalculator.calcLeafStates(state);
console.log(leafStates)
return leafStates[index];
}
}

View File

@ -135,9 +135,6 @@ export class ProductGamesystem extends Gamesystem<ProductState, ProductTransitio
return binary_productState!;
}
addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
this.innerGamesystems.push(gamesystem);
}