Visualize SimpleGamesystems in GamesystemOverview
All checks were successful
E2E Testing / test (push) Successful in 1m23s

This commit is contained in:
Sebastian Böckelmann 2024-02-06 20:56:21 +01:00
parent 55ccd3faaf
commit f55e8dde3d
7 changed files with 108 additions and 14 deletions

View File

@ -23,7 +23,7 @@
</mat-menu> </mat-menu>
</div> </div>
<app-script-account-overview *ngIf="openContent == ModelComponentType.SCRIPTACCOUNT" #scriptAccountOverview [gameModel]="gameModel" (onOpenScriptAccount)="openModelComponent($event)"></app-script-account-overview> <app-script-account-overview *ngIf="openContent == ModelComponentType.SCRIPTACCOUNT" #scriptAccountOverview [gameModel]="gameModel" (onOpenScriptAccount)="openModelComponent($event)"></app-script-account-overview>
<app-gamescript-overview *ngIf="openContent == ModelComponentType.GAMESYTEM" #gamesystemOverview></app-gamescript-overview> <app-gamescript-overview *ngIf="openContent == ModelComponentType.GAMESYTEM" #gamesystemOverview [gameModel]="gameModel"></app-gamescript-overview>
</mat-drawer> </mat-drawer>
<div class="example-sidenav-content"> <div class="example-sidenav-content">

View File

@ -14,6 +14,7 @@ import {MatDialog} from "@angular/material/dialog";
import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component"; import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component";
import {ScriptAccount} from "./game-model/scriptAccounts/ScriptAccount"; import {ScriptAccount} from "./game-model/scriptAccounts/ScriptAccount";
import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component"; import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component";
import {SimpleGamesystem} from "./game-model/gamesystems/SimpleGamesystem";
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@ -82,6 +83,12 @@ export class AppComponent implements OnInit{
this.gameModel = new GameModel("No More"); this.gameModel = new GameModel("No More");
this.gameModel.addScriptAccount("Temperature"); this.gameModel.addScriptAccount("Temperature");
this.gameModel.addScriptAccount("Luftfeuchtigkeit"); this.gameModel.addScriptAccount("Luftfeuchtigkeit");
const weather = new SimpleGamesystem("Weather");
const season = new SimpleGamesystem("Season");
this.gameModel.addGamesystem(weather)
this.gameModel.addGamesystem(season);
} }
openScriptAccountsOverview() { openScriptAccountsOverview() {

View File

@ -29,6 +29,7 @@ import {ModelComponentEditorComponent} from "./editor/model-component-editor/mod
import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component"; import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component";
import {MatDialogActions, MatDialogContent, MatDialogTitle} from "@angular/material/dialog"; import {MatDialogActions, MatDialogContent, MatDialogTitle} from "@angular/material/dialog";
import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component"; import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component";
import {MatTree, MatTreeModule} from "@angular/material/tree";
// AoT requires an exported function for factories // AoT requires an exported function for factories
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
@ -40,7 +41,8 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
EditorComponent, EditorComponent,
ScriptAccountEditorComponent, ScriptAccountEditorComponent,
ModelComponentEditorComponent, ModelComponentEditorComponent,
DeleteConfirmationDialogComponent DeleteConfirmationDialogComponent,
GamescriptOverviewComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -80,7 +82,7 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
MatDialogContent, MatDialogContent,
MatDialogActions, MatDialogActions,
MatMiniFabButton, MatMiniFabButton,
GamescriptOverviewComponent, MatTreeModule,
], ],
providers: [], providers: [],
bootstrap: [AppComponent] bootstrap: [AppComponent]

View File

@ -1,12 +1,14 @@
export abstract class Gamesystem<S, T> { import {SimpleGamesystem} from "./SimpleGamesystem";
gamesystemName: string import {ProductGamesystem} from "./ProductGamesystem";
gamesystemDescription: string import {ModelComponent} from "../ModelComponent";
import {ModelComponentType} from "../ModelComponentType";
export abstract class Gamesystem<S, T> extends ModelComponent{
states: S[] = []; states: S[] = [];
transitions: T[] = []; transitions: T[] = [];
constructor(gamesystemName: string) { constructor(gamesystemName: string) {
this.gamesystemName = gamesystemName; super(gamesystemName, "", ModelComponentType.GAMESYTEM);
this.gamesystemDescription = "";
} }
abstract createState(label: string, description: string): S|undefined; abstract createState(label: string, description: string): S|undefined;
@ -26,4 +28,8 @@ export abstract class Gamesystem<S, T> {
} }
save() {
}
} }

View File

@ -4,10 +4,11 @@ import {ProductTransition} from "./ProductTransition";
import {State} from "./State"; import {State} from "./State";
import {Transition} from "./Transition"; import {Transition} from "./Transition";
import {SimpleState} from "./SimpleState"; import {SimpleState} from "./SimpleState";
import {SimpleGamesystem} from "./SimpleGamesystem";
export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> { export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> {
innerGamesystems: Gamesystem<State<any>, Transition<any>>[] = []; innerGamesystems: SimpleGamesystem[] = [];
parentGamesystem: ProductGamesystem | undefined parentGamesystem: ProductGamesystem | undefined
createState(label: string, description: string): ProductState | undefined { createState(label: string, description: string): ProductState | undefined {

View File

@ -1 +1,18 @@
<p>gamescript-overview works!</p> <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
{{node.name}}
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'Toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
{{node.name}}
</mat-tree-node>
</mat-tree>

View File

@ -1,12 +1,73 @@
import { Component } from '@angular/core'; import {Component, Input, OnInit} from '@angular/core';
import {Gamesystem} from "../../game-model/gamesystems/Gamesystem";
import {State} from "../../game-model/gamesystems/State";
import {Transition} from "../../game-model/gamesystems/Transition";
import {ProductGamesystem} from "../../game-model/gamesystems/ProductGamesystem";
import {FlatTreeControl} from "@angular/cdk/tree";
import {
MatTree,
MatTreeFlatDataSource,
MatTreeFlattener,
MatTreeNode, MatTreeNodeDef,
MatTreeNodePadding, MatTreeNodeToggle
} from "@angular/material/tree";
import {MatIcon} from "@angular/material/icon";
import {MatIconButton} from "@angular/material/button";
import {SimpleGamesystem} from "../../game-model/gamesystems/SimpleGamesystem";
import {GameModel} from "../../game-model/GameModel";
interface FlatNode {
expandable: boolean,
name: string,
level: number
}
@Component({ @Component({
selector: 'app-gamescript-overview', selector: 'app-gamescript-overview',
standalone: true,
imports: [],
templateUrl: './gamescript-overview.component.html', templateUrl: './gamescript-overview.component.html',
styleUrl: './gamescript-overview.component.scss' styleUrl: './gamescript-overview.component.scss'
}) })
export class GamescriptOverviewComponent { export class GamescriptOverviewComponent implements OnInit {
@Input('gameModel') gameModel: GameModel | undefined
ngOnInit() {
this.dataSource.data = this.gameModel!.gamesystems;
}
private _transformer = (node: Gamesystem<State<any>, Transition<any>>, level: number) => {
return {
expandable: this.isProductGamesystem(node) && !!(node as ProductGamesystem).innerGamesystems && (node as ProductGamesystem).innerGamesystems.length > 0,
name: node.componentName,
level: level
}
}
treeControl = new FlatTreeControl<FlatNode>(
node => node.level,
node => node.expandable
)
treeFlattener = new MatTreeFlattener(
this._transformer,
node => node.level,
node => node.expandable,
node => this.isSimpleGamesystem(node)? []: (node as ProductGamesystem).innerGamesystems
);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
constructor() {
}
hasChild = (_: number, node: FlatNode) => node.expandable;
isSimpleGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
return gamesystem instanceof SimpleGamesystem;
}
isProductGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
return gamesystem instanceof ProductGamesystem;
}
} }