issue-5-product-gamesystems #10
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
<app-product-state-editor [gamesystem]="gamesystem" (onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-state-editor>
|
<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>
|
||||||
|
@ -2,12 +2,18 @@ import {Component, EventEmitter, Input, Output} from '@angular/core';
|
|||||||
import {ProductGamesystem} from "../../../game-model/gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "../../../game-model/gamesystems/ProductGamesystem";
|
||||||
import {ProductStateEditorComponent} from "../state-editor/product-state-editor/product-state-editor.component";
|
import {ProductStateEditorComponent} from "../state-editor/product-state-editor/product-state-editor.component";
|
||||||
import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem";
|
||||||
|
import {
|
||||||
|
ProductTransitionEditorComponent
|
||||||
|
} from "../transition-editor/product-transition-editor/product-transition-editor.component";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-product-gamesystem-editor',
|
selector: 'app-product-gamesystem-editor',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
ProductStateEditorComponent
|
ProductStateEditorComponent,
|
||||||
|
ProductTransitionEditorComponent
|
||||||
],
|
],
|
||||||
templateUrl: './product-gamesystem-editor.component.html',
|
templateUrl: './product-gamesystem-editor.component.html',
|
||||||
styleUrl: './product-gamesystem-editor.component.scss'
|
styleUrl: './product-gamesystem-editor.component.scss'
|
||||||
|
@ -17,6 +17,7 @@ import {NgForOf, NgIf} from "@angular/common";
|
|||||||
import {ProductState} from "../../../../game-model/gamesystems/ProductState";
|
import {ProductState} from "../../../../game-model/gamesystems/ProductState";
|
||||||
import {MatIcon} from "@angular/material/icon";
|
import {MatIcon} from "@angular/material/icon";
|
||||||
import {Gamesystem} from "../../../../game-model/gamesystems/Gamesystem";
|
import {Gamesystem} from "../../../../game-model/gamesystems/Gamesystem";
|
||||||
|
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-product-state-editor',
|
selector: 'app-product-state-editor',
|
||||||
@ -67,38 +68,13 @@ export class ProductStateEditorComponent implements OnInit{
|
|||||||
protected readonly SimpleState = SimpleState;
|
protected readonly SimpleState = SimpleState;
|
||||||
|
|
||||||
getLeafState(state: State<any>, i: number) {
|
getLeafState(state: State<any>, i: number) {
|
||||||
return this.computeLeafStates(state)[i];
|
return LeafGamesystemCalculator.calcLeafStates(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clickOnInnerState(leafIndex: number) {
|
clickOnInnerState(leafIndex: number) {
|
||||||
const leaf_gamesystems = this.computeLeafGamesystems(this.gamesystem!);
|
const leaf_gamesystems = LeafGamesystemCalculator.calcLeafGeamesystems(this.gamesystem!);
|
||||||
const clicked_gamesystem = leaf_gamesystems[leafIndex];
|
const clicked_gamesystem = leaf_gamesystems[leafIndex];
|
||||||
this.openGamesystemEditorEmitter.emit(clicked_gamesystem);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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>
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -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];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -135,9 +135,6 @@ export class ProductGamesystem extends Gamesystem<ProductState, ProductTransitio
|
|||||||
return binary_productState!;
|
return binary_productState!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
|
addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
|
||||||
this.innerGamesystems.push(gamesystem);
|
this.innerGamesystems.push(gamesystem);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user