From d5f593a8248b856ff53da6b21aeede86a6cd9aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Mon, 5 Feb 2024 20:44:39 +0100 Subject: [PATCH 01/24] Datastructure for Gamesystems and Create and Remove SimpleStates and Transitions --- .../gamesystems/SimpleGamesystem.spec.ts | 104 ++++++++++++++++++ src/app/game-model/GameModel.ts | 10 +- src/app/game-model/gamesystems/Gamesystem.ts | 23 +++- .../gamesystems/ProductGamesystem.ts | 7 ++ .../game-model/gamesystems/ProductState.ts | 7 ++ .../gamesystems/ProductTransition.ts | 6 + .../gamesystems/SimpleGamesystem.ts | 45 ++++++++ src/app/game-model/gamesystems/SimpleState.ts | 6 + .../gamesystems/SimpleTransition.ts | 6 + src/app/game-model/gamesystems/State.ts | 30 +++++ src/app/game-model/gamesystems/Transition.ts | 15 +++ 11 files changed, 252 insertions(+), 7 deletions(-) create mode 100644 e2e/game-model/gamesystems/SimpleGamesystem.spec.ts create mode 100644 src/app/game-model/gamesystems/ProductGamesystem.ts create mode 100644 src/app/game-model/gamesystems/ProductState.ts create mode 100644 src/app/game-model/gamesystems/ProductTransition.ts create mode 100644 src/app/game-model/gamesystems/SimpleGamesystem.ts create mode 100644 src/app/game-model/gamesystems/SimpleState.ts create mode 100644 src/app/game-model/gamesystems/SimpleTransition.ts create mode 100644 src/app/game-model/gamesystems/State.ts create mode 100644 src/app/game-model/gamesystems/Transition.ts diff --git a/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts new file mode 100644 index 0000000..504bc30 --- /dev/null +++ b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts @@ -0,0 +1,104 @@ +import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright'; +import { test, expect } from '@playwright/test'; +import * as PATH from 'path'; +import {GameModel} from "../../../src/app/game-model/GameModel"; +import {Gamesystem} from "../../src/app/game-model/gamesystems/Gamesystem"; +import {ScriptAccount} from "../../../src/app/game-model/scriptAccounts/ScriptAccount"; +import {ModelComponentType} from "../../../src/app/game-model/ModelComponentType"; +import {SimpleGamesystem} from "../../../src/app/game-model/gamesystems/SimpleGamesystem"; +import exp = require("node:constants"); +import {end} from "electron-debug"; + +test.describe('Test SimpleGamesystem', () => { + + test("Create SimpleState", async () => { + const gamesystem = new SimpleGamesystem(); + let state = gamesystem.createState("Test", "Test2"); + expect(state.stateLabel).toEqual("Test"); + expect(state.stateDescription).toEqual("Test2"); + expect(state.incomingTransitions.length).toEqual(0); + expect(state.outgoingTransitions.length).toEqual(0); + expect(gamesystem.states.includes(state)).toBeTruthy(); + + state = gamesystem.createState(null, null); + expect(state).toBeUndefined(); + expect(gamesystem.states.includes(state)).toBeFalsy(); + + state = gamesystem.createState(null, "test2"); + expect(state).toBeUndefined() + expect(gamesystem.states.includes(state)).toBeFalsy(); + + state = gamesystem.createState("test2", null); + expect(state).toBeDefined(); + expect(state.stateLabel).toEqual("test2"); + expect(state.stateDescription).toEqual(""); + expect(gamesystem.states.includes(state)).toBeTruthy(); + + state = gamesystem.createState(undefined, "State"); + expect(state).toBeUndefined(); + expect(gamesystem.states.includes(state)).toBeFalsy(); + + state = gamesystem.createState("Test3", undefined); + expect(state).toBeDefined(); + expect(state.stateLabel).toEqual("Test3"); + expect(state.stateDescription).toEqual(""); + expect(gamesystem.states.includes(state)).toBeTruthy(); + + state = gamesystem.createState("", ""); + expect(state).toBeDefined(); + expect(state.stateLabel).toEqual(""); + expect(state.stateDescription).toEqual(""); + expect(gamesystem.states.includes(state)).toBeTruthy(); + + state = gamesystem.createState("Test3", ""); + expect(state).toBeUndefined(); + expect(gamesystem.states.includes(state)).toBeFalsy(); + }) + + test("Create SimpleTransition", async () => { + const gamesystem = new SimpleGamesystem(); + const startingState = gamesystem.createState("StartingState", "")!; + const endingState = gamesystem.createState("EndingState", "")! + + let transition = gamesystem.createTransition(startingState, endingState); + expect(transition).toBeDefined(); + expect(transition.startingState).toEqual(startingState); + expect(transition.endingState).toEqual(endingState); + expect(startingState.outgoingTransitions.includes(transition)).toBeTruthy(); + expect(endingState.incomingTransitions.includes(transition)).toBeTruthy(); + expect(gamesystem.transitions.includes(transition)).toBeTruthy(); + + transition = gamesystem.createTransition(null, null); + expect(transition).toBeUndefined(); + + transition = gamesystem.createTransition(null, endingState); + expect(transition).toBeUndefined(); + + transition = gamesystem.createTransition(undefined, undefined); + expect(transition).toBeUndefined(); + + transition = gamesystem.createTransition(undefined, endingState); + expect(transition).toBeUndefined(); + + transition = gamesystem.createTransition(startingState, null); + expect(transition).toBeUndefined(); + + transition = gamesystem.createTransition(startingState, undefined); + expect(transition).toBeUndefined(); + + transition = gamesystem.createTransition(startingState, startingState); + expect(transition).toBeUndefined(); + + transition = gamesystem.createTransition(startingState, endingState); + expect(transition).toBeUndefined(); + + }) + + test("Remove SimpleState", async () => { + + }) + + test("Remove SimpleTransition", async () => { + + }) +}); diff --git a/src/app/game-model/GameModel.ts b/src/app/game-model/GameModel.ts index a061db3..b8cec69 100644 --- a/src/app/game-model/GameModel.ts +++ b/src/app/game-model/GameModel.ts @@ -4,7 +4,7 @@ import {ScriptAccount} from "./scriptAccounts/ScriptAccount"; export class GameModel { private readonly _gameModelName: string - private _gamesystems: Gamesystem[] = []; + private _gamesystems: Gamesystem[] = []; private _scriptAccounts: ScriptAccount[] = []; constructor(gameModelName: string) { @@ -13,22 +13,20 @@ export class GameModel { get gameModelName(): string { return this._gameModelName; } - - - get gamesystems(): Gamesystem[] { + get gamesystems(): Gamesystem[] { return this._gamesystems; } get scriptAccounts(): ScriptAccount[] { return this._scriptAccounts; } - addGamesystem(gamesystem: Gamesystem) { + addGamesystem(gamesystem: Gamesystem) { if(!this.gamesystems.includes(gamesystem)) { this._gamesystems.push(gamesystem); } } - removeGamesystem(gamesystem : Gamesystem) { + removeGamesystem(gamesystem : Gamesystem) { this._gamesystems = this._gamesystems.filter(g => g !== gamesystem); } diff --git a/src/app/game-model/gamesystems/Gamesystem.ts b/src/app/game-model/gamesystems/Gamesystem.ts index 989e9c0..1af0da7 100644 --- a/src/app/game-model/gamesystems/Gamesystem.ts +++ b/src/app/game-model/gamesystems/Gamesystem.ts @@ -1,7 +1,28 @@ -export class Gamesystem { +export abstract class Gamesystem { gamesystemName: string + gamesystemDescription: string + + states: S[] = []; + transitions: T[] = []; constructor(gamesystemName: string) { this.gamesystemName = gamesystemName; + this.gamesystemDescription = ""; + } + + abstract createState(label: string, description: string): S|undefined; + + abstract createTransition(startingState: S, endingState: S): T|undefined; + + abstract removeState(state: S): boolean; + + removeTransition(transition: T): boolean { + const updatedTransitions = this.transitions.filter(t => t !== transition); + if(updatedTransitions.length == this.transitions.length) { + return false; + } + + this.transitions = updatedTransitions; + return true; } diff --git a/src/app/game-model/gamesystems/ProductGamesystem.ts b/src/app/game-model/gamesystems/ProductGamesystem.ts new file mode 100644 index 0000000..7ae5ff5 --- /dev/null +++ b/src/app/game-model/gamesystems/ProductGamesystem.ts @@ -0,0 +1,7 @@ +import {Gamesystem} from "./Gamesystem"; +import {ProductState} from "./ProductState"; +import {ProductTransition} from "./ProductTransition"; + +export class ProductGamesystem extends Gamesystem { + +} diff --git a/src/app/game-model/gamesystems/ProductState.ts b/src/app/game-model/gamesystems/ProductState.ts new file mode 100644 index 0000000..8a5cbaf --- /dev/null +++ b/src/app/game-model/gamesystems/ProductState.ts @@ -0,0 +1,7 @@ +import {ProductTransition} from "./ProductTransition"; +import {State} from "./State"; +import {SimpleState} from "./SimpleState"; + +export class ProductState extends State { + innerStates: SimpleState[] = []; +} diff --git a/src/app/game-model/gamesystems/ProductTransition.ts b/src/app/game-model/gamesystems/ProductTransition.ts new file mode 100644 index 0000000..3e862ea --- /dev/null +++ b/src/app/game-model/gamesystems/ProductTransition.ts @@ -0,0 +1,6 @@ +import {Transition} from "./Transition"; +import {ProductState} from "./ProductState"; + +export class ProductTransition extends Transition { + +} diff --git a/src/app/game-model/gamesystems/SimpleGamesystem.ts b/src/app/game-model/gamesystems/SimpleGamesystem.ts new file mode 100644 index 0000000..6654332 --- /dev/null +++ b/src/app/game-model/gamesystems/SimpleGamesystem.ts @@ -0,0 +1,45 @@ +import {Gamesystem} from "./Gamesystem"; +import {SimpleState} from "./SimpleState"; +import {SimpleTransition} from "./SimpleTransition"; +export class SimpleGamesystem extends Gamesystem { + createState(label: string, description: string): SimpleState | undefined { + if(label == null) { + return undefined; + } + + if(description == null) { + description = ""; + } + + const state = new SimpleState(label, description); + if(this.states.find(s => s.stateLabel == label) == undefined) { + this.states.push(state); + return state; + } else { + return undefined + } + } + + createTransition(startingState: SimpleState, endingState: SimpleState): SimpleTransition | undefined{ + if((startingState == null || endingState == null) || startingState === endingState) { + return undefined; + } + const transition = new SimpleTransition(startingState, endingState); + if(this.transitions.find(t => t.startingState === startingState && t.endingState === endingState) == undefined) { + this.transitions.push(transition) + return transition; + } else { + startingState.removeOutgoingTransition(transition); + endingState.removeIncomingTransition(transition); + return undefined + } + + } + + + removeState(state: SimpleState): boolean { + return false; + } + + +} diff --git a/src/app/game-model/gamesystems/SimpleState.ts b/src/app/game-model/gamesystems/SimpleState.ts new file mode 100644 index 0000000..d39ffba --- /dev/null +++ b/src/app/game-model/gamesystems/SimpleState.ts @@ -0,0 +1,6 @@ +import {State} from "./State"; +import {SimpleTransition} from "./SimpleTransition"; + +export class SimpleState extends State { + +} diff --git a/src/app/game-model/gamesystems/SimpleTransition.ts b/src/app/game-model/gamesystems/SimpleTransition.ts new file mode 100644 index 0000000..e7356ed --- /dev/null +++ b/src/app/game-model/gamesystems/SimpleTransition.ts @@ -0,0 +1,6 @@ +import {SimpleState} from "./SimpleState"; +import {Transition} from "./Transition"; + +export class SimpleTransition extends Transition { + +} diff --git a/src/app/game-model/gamesystems/State.ts b/src/app/game-model/gamesystems/State.ts new file mode 100644 index 0000000..96fe983 --- /dev/null +++ b/src/app/game-model/gamesystems/State.ts @@ -0,0 +1,30 @@ +import {Transition} from "./Transition"; + +export abstract class State> { + stateLabel: string = ""; + stateDescription: string = ""; + incomingTransitions: T[] =[]; + outgoingTransitions: T[] =[]; + + + constructor(stateLabel: string, stateDescription: string) { + this.stateLabel = stateLabel; + this.stateDescription = stateDescription; + } + + addIncomingTransition(transition: T) { + this.incomingTransitions.push(transition); + } + + addOutgoingTransition(transition: T) { + this.outgoingTransitions.push(transition); + } + + removeIncomingTransition(transition: T) { + + } + + removeOutgoingTransition(transition: T) { + + } +} diff --git a/src/app/game-model/gamesystems/Transition.ts b/src/app/game-model/gamesystems/Transition.ts new file mode 100644 index 0000000..5f75cbd --- /dev/null +++ b/src/app/game-model/gamesystems/Transition.ts @@ -0,0 +1,15 @@ +import {State} from "./State"; + +export abstract class Transition> { + startingState: S + endingState: S + + + constructor(startingState: S, endingState: S) { + this.startingState = startingState; + this.endingState = endingState; + + this.startingState.addOutgoingTransition(this); + this.endingState.addIncomingTransition(this); + } +} From 40fb7c6ab7e0236c1c84370bffbd15c76d5814ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Tue, 6 Feb 2024 19:50:50 +0100 Subject: [PATCH 02/24] Remove SimpleStates from SimpleGamesystems --- .../gamesystems/SimpleGamesystem.spec.ts | 40 +++++++++++++++++++ .../gamesystems/ProductGamesystem.ts | 24 +++++++++++ .../gamesystems/SimpleGamesystem.ts | 17 +++++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts index 504bc30..e916883 100644 --- a/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts +++ b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts @@ -95,7 +95,47 @@ test.describe('Test SimpleGamesystem', () => { }) test("Remove SimpleState", async () => { + const gamesystem = new SimpleGamesystem("Test"); + const state1 = gamesystem.createState("State1", ""); + const state1_delete = gamesystem.removeState(state1); + expect(state1_delete).toBeTruthy(); + expect(gamesystem.states.includes(state1)).toBeFalsy(); + + let startingState = gamesystem.createState("Start", "End"); + let endingState = gamesystem.createState("End", ""); + let transition = gamesystem.createTransition(startingState, endingState); + let result = gamesystem.removeState(startingState); + expect(result).toBeTruthy(); + expect(gamesystem.states.includes(startingState)).toBeFalsy(); + expect(gamesystem.states.includes(endingState)).toBeTruthy(); + expect(gamesystem.transitions.length).toEqual(0); + + startingState = gamesystem.createState("Start"); + transition = gamesystem.createTransition(startingState, endingState); + gamesystem.removeState(endingState); + expect(result).toBeTruthy(); + expect(gamesystem.states.includes(startingState)).toBeTruthy(); + expect(gamesystem.states.includes(endingState)).toBeFalsy(); + expect(gamesystem.transitions.length).toEqual(0); + + endingState = gamesystem.createState("End"); + transition = gamesystem.createTransition(startingState, endingState); + const testingState = gamesystem.createState("TestingState", ""); + result = gamesystem.removeState(testingState); + expect(result).toBeTruthy(); + expect(gamesystem.transitions.includes(transition)).toBeTruthy(); + + const gamesystem2 = new SimpleGamesystem("test2"); + const state2 = gamesystem2.createState("Test", ""); + result = gamesystem.removeState(state2); + expect(result).toBeFalsy(); + + result = gamesystem.removeState(null); + expect(result).toBeFalsy(); + + result = gamesystem.removeState(undefined); + expect(result).toBeFalsy(); }) test("Remove SimpleTransition", async () => { diff --git a/src/app/game-model/gamesystems/ProductGamesystem.ts b/src/app/game-model/gamesystems/ProductGamesystem.ts index 7ae5ff5..10301eb 100644 --- a/src/app/game-model/gamesystems/ProductGamesystem.ts +++ b/src/app/game-model/gamesystems/ProductGamesystem.ts @@ -1,7 +1,31 @@ import {Gamesystem} from "./Gamesystem"; import {ProductState} from "./ProductState"; import {ProductTransition} from "./ProductTransition"; +import {State} from "./State"; +import {Transition} from "./Transition"; +import {SimpleState} from "./SimpleState"; export class ProductGamesystem extends Gamesystem { + innerGamesystems: Gamesystem, Transition>[] = []; + parentGamesystem: ProductGamesystem | undefined + + createState(label: string, description: string): ProductState | undefined { + return undefined; + } + + createTransition(startingState: ProductState, endingState: ProductState): ProductTransition | undefined { + return undefined; + } + + removeState(state: ProductState): boolean { + return false; + } + + removeInnerState(state: SimpleState) { + + } + + + } diff --git a/src/app/game-model/gamesystems/SimpleGamesystem.ts b/src/app/game-model/gamesystems/SimpleGamesystem.ts index 6654332..4021c93 100644 --- a/src/app/game-model/gamesystems/SimpleGamesystem.ts +++ b/src/app/game-model/gamesystems/SimpleGamesystem.ts @@ -1,7 +1,15 @@ import {Gamesystem} from "./Gamesystem"; import {SimpleState} from "./SimpleState"; import {SimpleTransition} from "./SimpleTransition"; +import {State} from "./State"; +import {Transition} from "./Transition"; +import {ProductState} from "./ProductState"; +import {ProductTransition} from "./ProductTransition"; +import {ProductGamesystem} from "./ProductGamesystem"; export class SimpleGamesystem extends Gamesystem { + + parentGamesystem: ProductGamesystem | undefined + createState(label: string, description: string): SimpleState | undefined { if(label == null) { return undefined; @@ -24,6 +32,7 @@ export class SimpleGamesystem extends Gamesystem if((startingState == null || endingState == null) || startingState === endingState) { return undefined; } + const transition = new SimpleTransition(startingState, endingState); if(this.transitions.find(t => t.startingState === startingState && t.endingState === endingState) == undefined) { this.transitions.push(transition) @@ -38,7 +47,13 @@ export class SimpleGamesystem extends Gamesystem removeState(state: SimpleState): boolean { - return false; + const updatedStates = this.states.filter(s => s !== state); + const updated = updatedStates.length != this.states.length; + this.states = updatedStates; + + this.transitions = this.transitions.filter(t => t.startingState !== state && t.endingState !== state); + + return updated; } From dda3aa4bed4283024bd1150cc5f0295e14674338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Tue, 6 Feb 2024 19:58:18 +0100 Subject: [PATCH 03/24] Remove SimpleTransitions --- .../gamesystems/SimpleGamesystem.spec.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts index e916883..4c61efd 100644 --- a/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts +++ b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts @@ -139,6 +139,34 @@ test.describe('Test SimpleGamesystem', () => { }) test("Remove SimpleTransition", async () => { + const gamesystem = new SimpleGamesystem("Gamesystem"); + const A = gamesystem.createState("A"); + const B = gamesystem.createState("B"); + let AB = gamesystem.createTransition(A, B); + + let result = gamesystem.removeTransition(AB); + expect(result).toBeTruthy(); + expect(gamesystem.transitions.includes(AB)).toBeFalsy(); + + AB = gamesystem.createTransition(A, B); + const C = gamesystem.createState("C"); + const D = gamesystem.createState("D"); + let CD = gamesystem.createTransition(C, D); + + result = gamesystem.removeTransition(AB); + expect(result).toBeTruthy(); + expect(gamesystem.transitions.includes(AB)).toBeFalsy(); + expect(gamesystem.transitions.includes(CD)).toBeTruthy(); + + let BA = gamesystem.createTransition(B, A); + AB = gamesystem.createTransition(A, B); + result = gamesystem.removeTransition(AB); + expect(result).toBeTruthy(); + expect(gamesystem.transitions.includes(AB)).toBeFalsy(); + expect(gamesystem.transitions.includes(BA)).toBeTruthy(); + + result = gamesystem.removeTransition(AB); + expect(result).toBeFalsy(); }) }); From 55ccd3faafc51a81f21d34217dbec9e77242e89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Tue, 6 Feb 2024 20:21:52 +0100 Subject: [PATCH 04/24] Display Gamesystemoverview --- src/app/app.component.html | 6 +- src/app/app.component.ts | 7 ++ src/app/app.module.ts | 80 ++++++++++--------- src/app/game-model/ModelComponentType.ts | 4 +- .../ModelComponentTypeUtillities.ts | 3 +- .../gamescript-overview.component.html | 1 + .../gamescript-overview.component.scss | 0 .../gamescript-overview.component.spec.ts | 23 ++++++ .../gamescript-overview.component.ts | 12 +++ 9 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 src/app/side-overviews/gamescript-overview/gamescript-overview.component.html create mode 100644 src/app/side-overviews/gamescript-overview/gamescript-overview.component.scss create mode 100644 src/app/side-overviews/gamescript-overview/gamescript-overview.component.spec.ts create mode 100644 src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts diff --git a/src/app/app.component.html b/src/app/app.component.html index 2beb7f6..b7c855b 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,6 +2,8 @@
+
@@ -17,9 +19,11 @@ + - + +
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 325cbac..5aff408 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -13,6 +13,7 @@ import { import {MatDialog} from "@angular/material/dialog"; import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component"; import {ScriptAccount} from "./game-model/scriptAccounts/ScriptAccount"; +import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component"; @Component({ selector: 'app-root', @@ -25,6 +26,7 @@ export class AppComponent implements OnInit{ @ViewChild('drawer') drawer: MatDrawerContainer|undefined @ViewChild('editor') editor: EditorComponent|undefined @ViewChild('scriptAccountOverview') scriptAccountOverview: ScriptAccountOverviewComponent | undefined + @ViewChild('gamesystemOverview') gamesystemOverview: GamescriptOverviewComponent | undefined gameModel: GameModel | undefined @@ -87,6 +89,11 @@ export class AppComponent implements OnInit{ this.drawer!.open(); } + openGamesystemsOverview() { + this.openContent = ModelComponentType.GAMESYTEM; + this.drawer!.open(); + } + protected readonly ModelComponentType = ModelComponentType; closeContentOverview() { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c3edf21..ad744e9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -28,6 +28,7 @@ import {ScriptAccountEditorComponent} from "./editor/script-account-editor/scrip import {ModelComponentEditorComponent} from "./editor/model-component-editor/model-component-editor.component"; import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component"; import {MatDialogActions, MatDialogContent, MatDialogTitle} from "@angular/material/dialog"; +import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component"; // AoT requires an exported function for factories const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -41,45 +42,46 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl ModelComponentEditorComponent, DeleteConfirmationDialogComponent ], - imports: [ - BrowserModule, - FormsModule, - HttpClientModule, - CoreModule, - SharedModule, - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useFactory: httpLoaderFactory, - deps: [HttpClient] - } - }), - BrowserAnimationsModule, - MatIcon, - MatToolbar, - MatButton, - MatFormField, - MatInput, - MatDrawerContainer, - MatDrawer, - MatIconButton, - MatMenuTrigger, - MatMenu, - MatMenuItem, - MatListItem, - MatActionList, - MatTabGroup, - MatTab, - MatTabLabel, - MatLabel, - MatFormField, - ReactiveFormsModule, - MatError, - MatDialogTitle, - MatDialogContent, - MatDialogActions, - MatMiniFabButton, - ], + imports: [ + BrowserModule, + FormsModule, + HttpClientModule, + CoreModule, + SharedModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: httpLoaderFactory, + deps: [HttpClient] + } + }), + BrowserAnimationsModule, + MatIcon, + MatToolbar, + MatButton, + MatFormField, + MatInput, + MatDrawerContainer, + MatDrawer, + MatIconButton, + MatMenuTrigger, + MatMenu, + MatMenuItem, + MatListItem, + MatActionList, + MatTabGroup, + MatTab, + MatTabLabel, + MatLabel, + MatFormField, + ReactiveFormsModule, + MatError, + MatDialogTitle, + MatDialogContent, + MatDialogActions, + MatMiniFabButton, + GamescriptOverviewComponent, + ], providers: [], bootstrap: [AppComponent] }) diff --git a/src/app/game-model/ModelComponentType.ts b/src/app/game-model/ModelComponentType.ts index 5218558..77a75a7 100644 --- a/src/app/game-model/ModelComponentType.ts +++ b/src/app/game-model/ModelComponentType.ts @@ -1,5 +1,5 @@ export enum ModelComponentType { - SCRIPTACCOUNT - + SCRIPTACCOUNT, + GAMESYTEM } diff --git a/src/app/game-model/ModelComponentTypeUtillities.ts b/src/app/game-model/ModelComponentTypeUtillities.ts index c92fce9..c267736 100644 --- a/src/app/game-model/ModelComponentTypeUtillities.ts +++ b/src/app/game-model/ModelComponentTypeUtillities.ts @@ -1,10 +1,10 @@ import {ModelComponentType} from "./ModelComponentType"; -import {ModelComponent} from "./ModelComponent"; export class ModelComponentTypeUtillities { static toString(modelComponentType: ModelComponentType | undefined): string { switch (modelComponentType) { case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccounts"; + case ModelComponentType.GAMESYTEM: return "Gamesystems"; default: return "Undefined"; } } @@ -12,6 +12,7 @@ export class ModelComponentTypeUtillities { static toSingleString(modelComponentType: ModelComponentType | undefined): string { switch (modelComponentType) { case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccount"; + case ModelComponentType.GAMESYTEM: return "Gamesystem"; default: return "Undefined"; } } diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html new file mode 100644 index 0000000..99e6d6c --- /dev/null +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html @@ -0,0 +1 @@ +

gamescript-overview works!

diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.scss b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.spec.ts b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.spec.ts new file mode 100644 index 0000000..afcbba8 --- /dev/null +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GamescriptOverviewComponent } from './gamescript-overview.component'; + +describe('GamescriptOverviewComponent', () => { + let component: GamescriptOverviewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GamescriptOverviewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GamescriptOverviewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts new file mode 100644 index 0000000..01edda5 --- /dev/null +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-gamescript-overview', + standalone: true, + imports: [], + templateUrl: './gamescript-overview.component.html', + styleUrl: './gamescript-overview.component.scss' +}) +export class GamescriptOverviewComponent { + +} From f55e8dde3d062bfc064a585b7552b11f26d424f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Tue, 6 Feb 2024 20:56:21 +0100 Subject: [PATCH 05/24] Visualize SimpleGamesystems in GamesystemOverview --- src/app/app.component.html | 2 +- src/app/app.component.ts | 7 ++ src/app/app.module.ts | 6 +- src/app/game-model/gamesystems/Gamesystem.ts | 16 +++-- .../gamesystems/ProductGamesystem.ts | 3 +- .../gamescript-overview.component.html | 19 ++++- .../gamescript-overview.component.ts | 69 +++++++++++++++++-- 7 files changed, 108 insertions(+), 14 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index b7c855b..0f43965 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -23,7 +23,7 @@
- +
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 5aff408..7d1f22e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -14,6 +14,7 @@ import {MatDialog} from "@angular/material/dialog"; import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component"; import {ScriptAccount} from "./game-model/scriptAccounts/ScriptAccount"; import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component"; +import {SimpleGamesystem} from "./game-model/gamesystems/SimpleGamesystem"; @Component({ selector: 'app-root', @@ -82,6 +83,12 @@ export class AppComponent implements OnInit{ this.gameModel = new GameModel("No More"); this.gameModel.addScriptAccount("Temperature"); this.gameModel.addScriptAccount("Luftfeuchtigkeit"); + + const weather = new SimpleGamesystem("Weather"); + const season = new SimpleGamesystem("Season"); + + this.gameModel.addGamesystem(weather) + this.gameModel.addGamesystem(season); } openScriptAccountsOverview() { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ad744e9..46973c6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -29,6 +29,7 @@ import {ModelComponentEditorComponent} from "./editor/model-component-editor/mod import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component"; import {MatDialogActions, MatDialogContent, MatDialogTitle} from "@angular/material/dialog"; import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component"; +import {MatTree, MatTreeModule} from "@angular/material/tree"; // AoT requires an exported function for factories const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -40,7 +41,8 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl EditorComponent, ScriptAccountEditorComponent, ModelComponentEditorComponent, - DeleteConfirmationDialogComponent + DeleteConfirmationDialogComponent, + GamescriptOverviewComponent ], imports: [ BrowserModule, @@ -80,7 +82,7 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl MatDialogContent, MatDialogActions, MatMiniFabButton, - GamescriptOverviewComponent, + MatTreeModule, ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/game-model/gamesystems/Gamesystem.ts b/src/app/game-model/gamesystems/Gamesystem.ts index 1af0da7..0dea6ba 100644 --- a/src/app/game-model/gamesystems/Gamesystem.ts +++ b/src/app/game-model/gamesystems/Gamesystem.ts @@ -1,12 +1,14 @@ -export abstract class Gamesystem { - gamesystemName: string - gamesystemDescription: string +import {SimpleGamesystem} from "./SimpleGamesystem"; +import {ProductGamesystem} from "./ProductGamesystem"; +import {ModelComponent} from "../ModelComponent"; +import {ModelComponentType} from "../ModelComponentType"; + +export abstract class Gamesystem extends ModelComponent{ states: S[] = []; transitions: T[] = []; constructor(gamesystemName: string) { - this.gamesystemName = gamesystemName; - this.gamesystemDescription = ""; + super(gamesystemName, "", ModelComponentType.GAMESYTEM); } abstract createState(label: string, description: string): S|undefined; @@ -26,4 +28,8 @@ export abstract class Gamesystem { } + save() { + + } + } diff --git a/src/app/game-model/gamesystems/ProductGamesystem.ts b/src/app/game-model/gamesystems/ProductGamesystem.ts index 10301eb..d97f39e 100644 --- a/src/app/game-model/gamesystems/ProductGamesystem.ts +++ b/src/app/game-model/gamesystems/ProductGamesystem.ts @@ -4,10 +4,11 @@ import {ProductTransition} from "./ProductTransition"; import {State} from "./State"; import {Transition} from "./Transition"; import {SimpleState} from "./SimpleState"; +import {SimpleGamesystem} from "./SimpleGamesystem"; export class ProductGamesystem extends Gamesystem { - innerGamesystems: Gamesystem, Transition>[] = []; + innerGamesystems: SimpleGamesystem[] = []; parentGamesystem: ProductGamesystem | undefined createState(label: string, description: string): ProductState | undefined { diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html index 99e6d6c..e871b87 100644 --- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html @@ -1 +1,18 @@ -

gamescript-overview works!

+ + + + + + {{node.name}} + + + + + {{node.name}} + + diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts index 01edda5..0454cb9 100644 --- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts @@ -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({ selector: 'app-gamescript-overview', - standalone: true, - imports: [], templateUrl: './gamescript-overview.component.html', 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, Transition>, 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( + 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, Transition>) { + return gamesystem instanceof SimpleGamesystem; + } + + isProductGamesystem(gamesystem: Gamesystem, Transition>) { + return gamesystem instanceof ProductGamesystem; + } } From b4cc5304fd8b160371f6e34dce7ae52d8e8d2900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Fri, 9 Feb 2024 20:04:52 +0100 Subject: [PATCH 06/24] Find Gamesystems By Name in GameModel --- .../gamesystems/FindGamesystem.spec.ts | 50 +++++++++++++++++++ .../gamesystems/GamesystemTrainer.ts | 37 ++++++++++++++ src/app/game-model/GameModel.ts | 18 +++++++ .../gamescript-overview.component.html | 13 +++-- .../gamescript-overview.component.scss | 40 +++++++++++++++ .../gamescript-overview.component.ts | 21 +++++++- 6 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 e2e/game-model/gamesystems/FindGamesystem.spec.ts create mode 100644 e2e/game-model/gamesystems/GamesystemTrainer.ts diff --git a/e2e/game-model/gamesystems/FindGamesystem.spec.ts b/e2e/game-model/gamesystems/FindGamesystem.spec.ts new file mode 100644 index 0000000..879717b --- /dev/null +++ b/e2e/game-model/gamesystems/FindGamesystem.spec.ts @@ -0,0 +1,50 @@ +import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright'; +import { test, expect } from '@playwright/test'; +import * as PATH from 'path'; +import {GameModel} from "../../../src/app/game-model/GameModel"; +import {Gamesystem} from "../../src/app/game-model/gamesystems/Gamesystem"; +import {ScriptAccount} from "../../../src/app/game-model/scriptAccounts/ScriptAccount"; +import {ModelComponentType} from "../../../src/app/game-model/ModelComponentType"; +import {SimpleGamesystem} from "../../../src/app/game-model/gamesystems/SimpleGamesystem"; +import exp = require("node:constants"); +import {end} from "electron-debug"; +import {GamesystemTrainer} from "./GamesystemTrainer"; +test.describe('Test Find Gamesystems', () => { + const GAMEMODELNAME: string = "GameModel"; + const SIMPLEGAMESYSTEM_NAME: string = "Simple Gamesystem"; + + + test('Find null or undefined Gamesystem', async () => { + const gameModel = new GameModel(GAMEMODELNAME); + expect(gameModel.findGamesystem(null)).toBeUndefined(); + expect(gameModel.findGamesystem(undefined)).toBeUndefined(); + }) + + test('Find non existend Gamesystem', async () => { + const gameModel = new GameModel(GAMEMODELNAME); + expect(gameModel.findGamesystem("Gamesystem")).toBeUndefined(); + }) + + test("Find existend simple Gamesystem on top layer", async () => { + const gameModel = new GameModel(GAMEMODELNAME); + const gamesystem = new SimpleGamesystem(SIMPLEGAMESYSTEM_NAME); + gameModel.addGamesystem(gamesystem); + + expect(gameModel.findGamesystem(SIMPLEGAMESYSTEM_NAME)).toBeDefined(); + expect(gameModel.findGamesystem(SIMPLEGAMESYSTEM_NAME)).toEqual(gamesystem); + }) + + test('Find existent product gamesystem on top layer', async () => { + const gameModel = GamesystemTrainer.givenGameModelWithProductGamesytemOnTopLayer(); + const result = gameModel.findGamesystem(GamesystemTrainer.TOP_PRODUCT_GAMESYSTEM_NAME); + expect(result).toBeDefined(); + + }) + + test('Find existent simple gamesystem on lower layer', async () => { + const gameModel = GamesystemTrainer.givenGameModelWithProductGamesytemOnTopLayer(); + const result = gameModel.findGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME); + expect(result).toBeDefined(); + + }) +}); diff --git a/e2e/game-model/gamesystems/GamesystemTrainer.ts b/e2e/game-model/gamesystems/GamesystemTrainer.ts new file mode 100644 index 0000000..8b2055f --- /dev/null +++ b/e2e/game-model/gamesystems/GamesystemTrainer.ts @@ -0,0 +1,37 @@ +import {GameModel} from "../../../src/app/game-model/GameModel"; +import {SimpleGamesystem} from "../../../src/app/game-model/gamesystems/SimpleGamesystem"; +import {ProductGamesystem} from "../../../src/app/game-model/gamesystems/ProductGamesystem"; + +export class GamesystemTrainer { + + static GAMEMODELNAME: string = "GAMEMODEL"; + static SIMPLEGAMESYSTEMNAME: string = "SIMPLE GAMESYSTEM"; + static TOP_PRODUCT_GAMESYSTEM_NAME: string = "Top Product Gamesystem" + + static SIMPLEGAMESYSTEM2: string = "Simple Gamesystem Leaf 2"; + static givenEmptyGameModel() { + return new GameModel(GamesystemTrainer.GAMEMODELNAME); + } + + static givenGameModelWithSimpleGamesystemOnTopLayer() { + const gameModel = new GameModel(GamesystemTrainer.GAMEMODELNAME); + const gamesytem = new SimpleGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME); + gameModel.addGamesystem(gamesytem); + + return gameModel; + } + + static givenGameModelWithProductGamesytemOnTopLayer() { + const gameModel = new GameModel(GamesystemTrainer.GAMEMODELNAME); + const productGamesystem = new ProductGamesystem(this.TOP_PRODUCT_GAMESYSTEM_NAME); + const leaf1 = new SimpleGamesystem(this.SIMPLEGAMESYSTEMNAME); + const leaf2 = new SimpleGamesystem(this.SIMPLEGAMESYSTEM2); + productGamesystem.innerGamesystems.push(leaf1); + productGamesystem.innerGamesystems.push(leaf2); + gameModel.addGamesystem(productGamesystem); + + return gameModel; + } + + +} diff --git a/src/app/game-model/GameModel.ts b/src/app/game-model/GameModel.ts index b8cec69..207fd0a 100644 --- a/src/app/game-model/GameModel.ts +++ b/src/app/game-model/GameModel.ts @@ -1,5 +1,8 @@ import {Gamesystem} from "./gamesystems/Gamesystem"; import {ScriptAccount} from "./scriptAccounts/ScriptAccount"; +import {Transition} from "./gamesystems/Transition"; +import {State} from "./gamesystems/State"; +import {ProductGamesystem} from "./gamesystems/ProductGamesystem"; export class GameModel { private readonly _gameModelName: string @@ -48,4 +51,19 @@ export class GameModel { } } + findGamesystem(gamesystemName: string) { + const gamesystemQueue : Gamesystem, Transition>[] = []; + this.gamesystems.forEach(gamesystem => gamesystemQueue.push(gamesystem)); + + while(gamesystemQueue.length > 0) { + const currentGamesystem = gamesystemQueue.shift()!; + if(currentGamesystem.componentName == gamesystemName) { + return currentGamesystem; + } else if(currentGamesystem instanceof ProductGamesystem) { + const currentProductGamesystem = currentGamesystem as ProductGamesystem; + currentProductGamesystem.innerGamesystems.forEach(gamesystem => gamesystemQueue.push(gamesystem)); + } + } + } + } diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html index e871b87..d8a0d79 100644 --- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html @@ -1,14 +1,17 @@ - + - + - + {{node.name}} - +
- +
diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts index c91c383..892bcde 100644 --- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts @@ -86,5 +86,9 @@ export class GamescriptOverviewComponent implements OnInit { openGamesystemEditor(node: FlatNode) { const gamesystem: Gamesystem, Transition>| undefined= this.gameModel!.findGamesystem(node.name); + if(gamesystem != undefined) { + gamesystem.unsaved = false; + this.openGamesystemEmitter.emit(gamesystem); + } } } From b09e9351e0fa75a819903117cb94128618d7aee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Fri, 9 Feb 2024 20:46:00 +0100 Subject: [PATCH 08/24] Edit Name of ModelComponent in Overview (Gamesystems did not apply updated name bcs of Datasource outdated) --- src/app/app.component.html | 2 +- src/app/app.component.ts | 5 +++++ src/app/editor/editor.component.html | 2 +- src/app/editor/editor.component.ts | 7 ++++++- .../model-component-editor.component.ts | 4 +++- .../gamescript-overview/gamescript-overview.component.ts | 4 ++++ 6 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index dee2fce..85d1f15 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -27,7 +27,7 @@
- +
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7d1f22e..3cbfe90 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -116,6 +116,11 @@ export class AppComponent implements OnInit{ } else { console.log("[WARN] [App.Component] Editor is undefined") } + } + onModelNameUpdate() { + if(this.openContent == ModelComponentType.GAMESYTEM) { + this.gamesystemOverview!.onUpdateModelName(); + } } } diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index ef4276b..dc9bd38 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -5,7 +5,7 @@ {{modelComponent.componentName}} - + diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index 6b222fe..36b6726 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -1,4 +1,4 @@ -import {Component, Input} from '@angular/core'; +import {Component, EventEmitter, Input, Output} from '@angular/core'; import {GameModel} from "../game-model/GameModel"; import {ModelComponent} from "../game-model/ModelComponent"; import {ModelComponentType} from "../game-model/ModelComponentType"; @@ -11,6 +11,7 @@ import {ScriptAccount} from "../game-model/scriptAccounts/ScriptAccount"; }) export class EditorComponent { gameModelComponents: ModelComponent[] = []; + @Output("onModelNameUpdate") onModelNameUpdateEmitter = new EventEmitter(); openGameModelComponent(gameModelComponent: ModelComponent) { if(!this.gameModelComponents.includes(gameModelComponent)) { @@ -29,4 +30,8 @@ export class EditorComponent { } protected readonly ModelComponentType = ModelComponentType; + + onModelNameUpdate() { + this.onModelNameUpdateEmitter.emit(true); + } } diff --git a/src/app/editor/model-component-editor/model-component-editor.component.ts b/src/app/editor/model-component-editor/model-component-editor.component.ts index c3a4e67..c527bb5 100644 --- a/src/app/editor/model-component-editor/model-component-editor.component.ts +++ b/src/app/editor/model-component-editor/model-component-editor.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {ModelComponent} from "../../game-model/ModelComponent"; import {FormControl, Validators} from "@angular/forms"; @@ -9,6 +9,7 @@ import {FormControl, Validators} from "@angular/forms"; }) export class ModelComponentEditorComponent implements OnInit{ @Input('modelComponent') modelComponent: ModelComponent | undefined + @Output("onModelNameUpdated") onModelNameUpdateEmitter = new EventEmitter(); nameCtrl: FormControl = new FormControl('', [Validators.required]); descriptionCtrl: FormControl = new FormControl('' ); @@ -21,6 +22,7 @@ export class ModelComponentEditorComponent implements OnInit{ onUpdateName() { this.modelComponent!.componentName = this.nameCtrl.value; this.modelComponent!.onModifyContent(); + this.onModelNameUpdateEmitter.emit(true); } onUpdateDescription() { diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts index 892bcde..87129b9 100644 --- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts @@ -91,4 +91,8 @@ export class GamescriptOverviewComponent implements OnInit { this.openGamesystemEmitter.emit(gamesystem); } } + + onUpdateModelName() { + this.dataSource.data = this.gameModel!.gamesystems; + } } From 8411d69bce924c57a4a5d2ea0516f9fca01cab91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 10:11:07 +0100 Subject: [PATCH 09/24] Create new Gamesystem --- app/main.ts | 2 +- .../gamesystems/CreateGamesystem.spec.ts | 53 +++++++++++ .../gamesystems/GamesystemTrainer.ts | 18 ++++ .../scriptAccounts/ScriptAccountTest.spec.ts | 16 ++-- src/app/app.component.ts | 89 ++++++++++++++----- src/app/game-model/GameModel.ts | 29 +++++- .../ModelComponentTypeUtillities.ts | 8 ++ .../gamesystems/ProductGamesystem.ts | 30 ++++++- .../gamescript-overview.component.ts | 10 ++- .../script-account-overview.component.ts | 18 +--- 10 files changed, 221 insertions(+), 52 deletions(-) create mode 100644 e2e/game-model/gamesystems/CreateGamesystem.spec.ts diff --git a/app/main.ts b/app/main.ts index 7f9f75d..0668026 100644 --- a/app/main.ts +++ b/app/main.ts @@ -57,7 +57,7 @@ function createWindow(): BrowserWindow { { label: "Gamesystem", click: () => { - win!.webContents.send('context-menu', "new-location"); + win!.webContents.send('context-menu', "new-gamesystem"); } }, { diff --git a/e2e/game-model/gamesystems/CreateGamesystem.spec.ts b/e2e/game-model/gamesystems/CreateGamesystem.spec.ts new file mode 100644 index 0000000..84e01c5 --- /dev/null +++ b/e2e/game-model/gamesystems/CreateGamesystem.spec.ts @@ -0,0 +1,53 @@ +import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright'; +import { test, expect } from '@playwright/test'; +import * as PATH from 'path'; +import {GameModel} from "../../../src/app/game-model/GameModel"; +import {Gamesystem} from "../../src/app/game-model/gamesystems/Gamesystem"; +import {ScriptAccount} from "../../../src/app/game-model/scriptAccounts/ScriptAccount"; +import {ModelComponentType} from "../../../src/app/game-model/ModelComponentType"; +import {SimpleGamesystem} from "../../../src/app/game-model/gamesystems/SimpleGamesystem"; +import exp = require("node:constants"); +import {end} from "electron-debug"; +import {GamesystemTrainer} from "./GamesystemTrainer"; +import {ProductGamesystem} from "../../../src/app/game-model/gamesystems/ProductGamesystem"; +test.describe('Test Create Gamesystems', () => { + + test('Test creating gamesystem with invalid name', async => { + const gameModel = GamesystemTrainer.givenEmptyGameModel(); + let result = gameModel.createGamesystem(undefined, undefined); + expect(result).toBeUndefined(); + + result = gameModel.createGamesystem(null, undefined); + expect(result).toBeUndefined(); + }) + + test("Test creating gamesystem with valid name but without parent", async => { + const gameModel = GamesystemTrainer.givenEmptyGameModel(); + let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME, undefined); + expect(result).toBeDefined(); + expect(gameModel.gamesystems.length).toEqual(1); + expect(gameModel.findGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME)).toBeDefined(); + }) + + test("Test creating Gamesystem with valid name but with Product Parent", async => { + const gameModel = GamesystemTrainer.givenGameModelWithProductGamesytemOnTopLayer(); + let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEM_LEAF_LEFT, GamesystemTrainer.TOP_PRODUCT_GAMESYSTEM_NAME); + expect(result).toBeDefined(); + expect(result.parentGamesystem!.componentName).toEqual(GamesystemTrainer.TOP_PRODUCT_GAMESYSTEM_NAME); + expect(result.parentGamesystem!.innerGamesystems.length).toEqual(3); + expect(result.parentGamesystem!.innerGamesystems.includes(result)).toBeTruthy(); + }) + + test("Test creating Gamesystem with valid name but with Simple Parent", async() => { + const gameModel = GamesystemTrainer.givenGameModelWithSimpleGamesystemOnTopLayer(); + let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEM_LEAF_LEFT, GamesystemTrainer.SIMPLEGAMESYSTEMNAME); + expect(result).toBeDefined(); + expect(gameModel.gamesystems.length).toEqual(1); + expect(gameModel.gamesystems[0]).toBeInstanceOf(ProductGamesystem); + expect(gameModel.gamesystems[0]).toEqual(result.parentGamesystem); + expect((gameModel.gamesystems[0] as ProductGamesystem).innerGamesystems.length).toEqual(1); + expect((gameModel.gamesystems[0] as ProductGamesystem).innerGamesystems.includes(result)).toBeTruthy(); + }) + + +}); diff --git a/e2e/game-model/gamesystems/GamesystemTrainer.ts b/e2e/game-model/gamesystems/GamesystemTrainer.ts index 8b2055f..515882e 100644 --- a/e2e/game-model/gamesystems/GamesystemTrainer.ts +++ b/e2e/game-model/gamesystems/GamesystemTrainer.ts @@ -9,6 +9,9 @@ export class GamesystemTrainer { static TOP_PRODUCT_GAMESYSTEM_NAME: string = "Top Product Gamesystem" static SIMPLEGAMESYSTEM2: string = "Simple Gamesystem Leaf 2"; + static SIMPLEGAMESYSTEM_LEAF_LEFT: string = "Leaf Gamesystem Left" + static SIMPLEGAMESYSTEM_LEAF_RIGHT: string = "Leaf Gamesystem Right"; + static givenEmptyGameModel() { return new GameModel(GamesystemTrainer.GAMEMODELNAME); } @@ -33,5 +36,20 @@ export class GamesystemTrainer { return gameModel; } + static givenGameModelWithProductGamesystemOnLowerLayer() { + const gameModel = new GameModel(GamesystemTrainer.GAMEMODELNAME); + const top_productGamesystem = new ProductGamesystem(this.TOP_PRODUCT_GAMESYSTEM_NAME); + const leaf1 = new ProductGamesystem(this.SIMPLEGAMESYSTEMNAME); + const leaf2 = new SimpleGamesystem(this.SIMPLEGAMESYSTEM2); + top_productGamesystem.innerGamesystems.push(leaf1); + top_productGamesystem.innerGamesystems.push(leaf2); + gameModel.addGamesystem(top_productGamesystem); + + const leaf_1_1 = new SimpleGamesystem(this.SIMPLEGAMESYSTEM_LEAF_LEFT); + leaf1.addChildGamesystem(leaf_1_1); + const leaf_1_2 = new SimpleGamesystem(this.SIMPLEGAMESYSTEM_LEAF_RIGHT); + leaf1.addChildGamesystem(leaf_1_2); + } + } diff --git a/e2e/game-model/scriptAccounts/ScriptAccountTest.spec.ts b/e2e/game-model/scriptAccounts/ScriptAccountTest.spec.ts index c7eb65b..00688ac 100644 --- a/e2e/game-model/scriptAccounts/ScriptAccountTest.spec.ts +++ b/e2e/game-model/scriptAccounts/ScriptAccountTest.spec.ts @@ -21,24 +21,24 @@ test.describe('Test ScriptAccounts', () => { test("Test Adding ScriptAccounts", async () => { const gameModel: GameModel = new GameModel("GameModel"); - let scriptAccount =gameModel.addScriptAccount("ScriptAccount"); + let scriptAccount =gameModel.createScriptAccount("ScriptAccount"); expect(scriptAccount).toBeDefined(); expect(gameModel.scriptAccounts.length).toEqual(1); expect(gameModel.scriptAccounts.includes(scriptAccount)).toBeTruthy(); //Test adding scriptAccount with already existing name - const scriptAccount2 = gameModel.addScriptAccount("ScriptAccount") + const scriptAccount2 = gameModel.createScriptAccount("ScriptAccount") expect(scriptAccount2).toBeUndefined(); expect(gameModel.scriptAccounts.length).toEqual(1); //Test for adding invalid names as scriptaccount names (null/undefined/empty) - let result = gameModel.addScriptAccount(null); + let result = gameModel.createScriptAccount(null); expect(result).toBeUndefined(); expect(gameModel.scriptAccounts.length).toEqual(1); - result = gameModel.addScriptAccount(undefined); + result = gameModel.createScriptAccount(undefined); expect(result).toBeUndefined(); expect(gameModel.scriptAccounts.length).toEqual(1); - result = gameModel.addScriptAccount(""); + result = gameModel.createScriptAccount(""); expect(result).toBeUndefined(); expect(gameModel.scriptAccounts.length).toEqual(1); }) @@ -50,7 +50,7 @@ test.describe('Test ScriptAccounts', () => { gameModel.removeScriptAccount(scriptAccount); expect(gameModel.scriptAccounts.length).toEqual(0); - scriptAccount = gameModel.addScriptAccount("ScriptAccount"); + scriptAccount = gameModel.createScriptAccount("ScriptAccount"); gameModel.removeScriptAccount(scriptAccount); expect(gameModel.scriptAccounts.length).toEqual(0); @@ -60,8 +60,8 @@ test.describe('Test ScriptAccounts', () => { gameModel.removeScriptAccount(null); expect(gameModel.scriptAccounts.length).toEqual(0); - scriptAccount = gameModel.addScriptAccount(scriptAccount); - let scriptAccount2 = gameModel.addScriptAccount("ScriptAccount 2"); + scriptAccount = gameModel.createScriptAccount(scriptAccount); + let scriptAccount2 = gameModel.createScriptAccount("ScriptAccount 2"); gameModel.removeScriptAccount(scriptAccount); expect(gameModel.scriptAccounts.length).toEqual(1); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 3cbfe90..fd4ad28 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -45,29 +45,78 @@ export class AppComponent implements OnInit{ electronService.ipcRenderer.on('context-menu', (event: any, message: string) => { this.zone.run(() => { - if(message == "edit") { - if(this.openContent == ModelComponentType.SCRIPTACCOUNT && this.scriptAccountOverview != undefined && this.scriptAccountOverview.selectedScriptAccount != undefined) { - this.editor!.openGameModelComponent(this.scriptAccountOverview.selectedScriptAccount!); - } - } else if(message == "delete") { - const affectedModelComponent = this.getSelectedModelComponent(); - const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, {data: affectedModelComponent, minWidth: "400px"}); - - dialogRef.afterClosed().subscribe(res => { - if(res != undefined && res) { - if(affectedModelComponent instanceof ScriptAccount) { - this.gameModel!.removeScriptAccount(affectedModelComponent); - } - } - }) - } - }) + this.onContextMenuMessageRecieved(message); + }); }) } else { console.log('Run in browser'); } } + onContextMenuMessageRecieved(message: string) { + if(message == "edit") { + this.onEditModelComponent(); + } else if(message == "delete") { + this.onDeleteModelComponent(); + } else if(message.startsWith("new")) { + const splittedMessage = message.split("-"); + const modelComponentType = ModelComponentTypeUtillities.fromString(splittedMessage[1]); + if(modelComponentType != undefined) { + this.onCreateModelComponent(modelComponentType); + } else { + console.log("[ERROR] [App-Component] Unknown Context-Menu Command!") + } + } + } + + private onEditModelComponent() { + if(this.openContent == ModelComponentType.SCRIPTACCOUNT && this.scriptAccountOverview != undefined && this.scriptAccountOverview.selectedScriptAccount != undefined) { + this.editor!.openGameModelComponent(this.scriptAccountOverview.selectedScriptAccount!); + } else { + //Erweitere to Gamesystems + } + } + + private onDeleteModelComponent() { + const affectedModelComponent = this.getSelectedModelComponent(); + const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, {data: affectedModelComponent, minWidth: "400px"}); + + dialogRef.afterClosed().subscribe(res => { + if(res != undefined && res) { + if(affectedModelComponent instanceof ScriptAccount) { + this.gameModel!.removeScriptAccount(affectedModelComponent); + } + } + }) + } + + private onCreateModelComponent(modelComponentType: ModelComponentType) { + switch (modelComponentType) { + case ModelComponentType.SCRIPTACCOUNT: this.onCreateNewScriptAccount(); break + case ModelComponentType.GAMESYTEM: this.onCreateNewGamesystem(); break + } + } + + private onCreateNewScriptAccount() { + const createdScriptAccount = this.gameModel!.createScriptAccount("New ScriptAccount"); + if(createdScriptAccount != undefined) { + this.editor?.openGameModelComponent(createdScriptAccount); + } else { + console.log("[DEBUG] [App-Component] ScriptAccount could not be created (Name not unique)"); + } + } + + private onCreateNewGamesystem() { + let parentGamesystemName = undefined + if(this.openContent != ModelComponentType.GAMESYTEM) { + this.openGamesystemsOverview(); + } else { + parentGamesystemName = this.gamesystemOverview!.selectedGamesystemName; + } + this.gameModel!.createGamesystem("New Gamesystem", parentGamesystemName); + this.gamesystemOverview!.refresh(); + } + private getSelectedModelComponent(): ModelComponent | undefined { if(this.openContent == ModelComponentType.SCRIPTACCOUNT) { if(this.scriptAccountOverview != undefined) { @@ -81,8 +130,8 @@ export class AppComponent implements OnInit{ ngOnInit() { this.gameModel = new GameModel("No More"); - this.gameModel.addScriptAccount("Temperature"); - this.gameModel.addScriptAccount("Luftfeuchtigkeit"); + this.gameModel.createScriptAccount("Temperature"); + this.gameModel.createScriptAccount("Luftfeuchtigkeit"); const weather = new SimpleGamesystem("Weather"); const season = new SimpleGamesystem("Season"); @@ -120,7 +169,7 @@ export class AppComponent implements OnInit{ onModelNameUpdate() { if(this.openContent == ModelComponentType.GAMESYTEM) { - this.gamesystemOverview!.onUpdateModelName(); + this.gamesystemOverview!.refresh(); } } } diff --git a/src/app/game-model/GameModel.ts b/src/app/game-model/GameModel.ts index 207fd0a..9e2a514 100644 --- a/src/app/game-model/GameModel.ts +++ b/src/app/game-model/GameModel.ts @@ -3,6 +3,7 @@ import {ScriptAccount} from "./scriptAccounts/ScriptAccount"; import {Transition} from "./gamesystems/Transition"; import {State} from "./gamesystems/State"; import {ProductGamesystem} from "./gamesystems/ProductGamesystem"; +import {SimpleGamesystem} from "./gamesystems/SimpleGamesystem"; export class GameModel { private readonly _gameModelName: string @@ -24,16 +25,14 @@ export class GameModel { } addGamesystem(gamesystem: Gamesystem) { - if(!this.gamesystems.includes(gamesystem)) { - this._gamesystems.push(gamesystem); - } + this._gamesystems.push(gamesystem); } removeGamesystem(gamesystem : Gamesystem) { this._gamesystems = this._gamesystems.filter(g => g !== gamesystem); } - addScriptAccount(scriptAccountName: string) { + createScriptAccount(scriptAccountName: string) { if(scriptAccountName != undefined && scriptAccountName.length > 0) { const scriptAccount = new ScriptAccount(scriptAccountName, ""); const searchedScriptAccount = this.scriptAccounts.find(s => s.componentName === scriptAccount.componentName); @@ -45,6 +44,28 @@ export class GameModel { return undefined; } + createGamesystem(gamesystemName: string, parentGamesystemName: string | undefined) { + if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) { + const simpleGamesystem = new SimpleGamesystem(gamesystemName); + if(parentGamesystemName != undefined) { + const parentGamesystem = this.findGamesystem(parentGamesystemName); + if(parentGamesystem instanceof SimpleGamesystem) { + const parentProductGamesystem = ProductGamesystem.constructFromSimpleGamesystem(parentGamesystem, this); + parentProductGamesystem.addChildGamesystem(simpleGamesystem); + simpleGamesystem.parentGamesystem = parentProductGamesystem; + } else { + const productParentGamesystem = parentGamesystem as ProductGamesystem; + productParentGamesystem.addChildGamesystem(simpleGamesystem); + simpleGamesystem.parentGamesystem = productParentGamesystem; + } + } else { + this.gamesystems.push(simpleGamesystem); + + } + return simpleGamesystem; + } + } + removeScriptAccount(scriptAccount: ScriptAccount) { if(scriptAccount != undefined) { this._scriptAccounts = this.scriptAccounts.filter(s => s != scriptAccount); diff --git a/src/app/game-model/ModelComponentTypeUtillities.ts b/src/app/game-model/ModelComponentTypeUtillities.ts index c267736..236cc96 100644 --- a/src/app/game-model/ModelComponentTypeUtillities.ts +++ b/src/app/game-model/ModelComponentTypeUtillities.ts @@ -16,4 +16,12 @@ export class ModelComponentTypeUtillities { default: return "Undefined"; } } + + static fromString(string: string) : ModelComponentType | undefined { + console.log(string) + switch (string) { + case "gamesystem": return ModelComponentType.GAMESYTEM; + case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT; + } + } } diff --git a/src/app/game-model/gamesystems/ProductGamesystem.ts b/src/app/game-model/gamesystems/ProductGamesystem.ts index d97f39e..84a135d 100644 --- a/src/app/game-model/gamesystems/ProductGamesystem.ts +++ b/src/app/game-model/gamesystems/ProductGamesystem.ts @@ -5,12 +5,34 @@ import {State} from "./State"; import {Transition} from "./Transition"; import {SimpleState} from "./SimpleState"; import {SimpleGamesystem} from "./SimpleGamesystem"; +import {GameModel} from "../GameModel"; export class ProductGamesystem extends Gamesystem { - innerGamesystems: SimpleGamesystem[] = []; + innerGamesystems: Gamesystem, Transition>[] = []; parentGamesystem: ProductGamesystem | undefined + static constructFromSimpleGamesystem(simpleGamesystem: SimpleGamesystem, gameModel: GameModel) { + const productGamesystem = new ProductGamesystem(simpleGamesystem.componentName); + const parentGamesystem = simpleGamesystem.parentGamesystem; + + if(simpleGamesystem.states.length > 0) { + simpleGamesystem.componentName += "(Child)"; + productGamesystem.addChildGamesystem(simpleGamesystem); + } + + + if(parentGamesystem != undefined) { + parentGamesystem.removeChildGamesystem(simpleGamesystem); + parentGamesystem.addChildGamesystem(productGamesystem); + } else { + gameModel.removeGamesystem(simpleGamesystem); + gameModel.addGamesystem(productGamesystem); + } + + return productGamesystem; + } + createState(label: string, description: string): ProductState | undefined { return undefined; } @@ -28,5 +50,11 @@ export class ProductGamesystem extends Gamesystem, Transition>) { + this.innerGamesystems.push(gamesystem); + } + private removeChildGamesystem(gamesystem: Gamesystem, Transition>) { + this.innerGamesystems = this.innerGamesystems.filter(childSystem => childSystem != gamesystem); + } } diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts index 87129b9..4c07292 100644 --- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts @@ -92,7 +92,15 @@ export class GamescriptOverviewComponent implements OnInit { } } - onUpdateModelName() { + get selectedGamesystemName() { + if(this.selectedGamesystem == undefined) { + return undefined + } else { + return this.selectedGamesystem!.name + } + } + + refresh() { this.dataSource.data = this.gameModel!.gamesystems; } } diff --git a/src/app/side-overviews/script-account-overview/script-account-overview.component.ts b/src/app/side-overviews/script-account-overview/script-account-overview.component.ts index f8621ee..f0d15da 100644 --- a/src/app/side-overviews/script-account-overview/script-account-overview.component.ts +++ b/src/app/side-overviews/script-account-overview/script-account-overview.component.ts @@ -14,17 +14,7 @@ export class ScriptAccountOverviewComponent { selectedScriptAccount: ScriptAccount | undefined - constructor(private electronService: ElectronService, - private zone: NgZone) { - if(electronService.isElectron) { - this.electronService.ipcRenderer.on('context-menu', (event: any, message: string) => { - this.zone.run(() => { - if(message == "new-scriptaccount") { - this.onCreateNewScriptAccount() - } - }) - }) - } + constructor() { } onOpenScriptAccount(scriptAccount: ScriptAccount) { @@ -32,12 +22,6 @@ export class ScriptAccountOverviewComponent { this.openScriptAccountEmitter.emit(scriptAccount); } - onCreateNewScriptAccount() { - const scriptAccount = this.gameModel!.addScriptAccount("New ScriptAccount"); - if(scriptAccount != undefined) { - this.openScriptAccountEmitter.emit(scriptAccount); - } - } selectScriptAccount(scriptAccount: ScriptAccount) { From 635da80bf2e71f9d260814d1864b1bf6fe0855f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 10:12:28 +0100 Subject: [PATCH 10/24] Open Gamesystem Editor after Gamesystem Creation --- src/app/app.component.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index fd4ad28..43021e3 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -113,8 +113,11 @@ export class AppComponent implements OnInit{ } else { parentGamesystemName = this.gamesystemOverview!.selectedGamesystemName; } - this.gameModel!.createGamesystem("New Gamesystem", parentGamesystemName); - this.gamesystemOverview!.refresh(); + const createdGamesystem = this.gameModel!.createGamesystem("New Gamesystem", parentGamesystemName); + if(createdGamesystem != undefined) { + this.gamesystemOverview!.refresh(); + this.editor?.openGameModelComponent(createdGamesystem!); + } } private getSelectedModelComponent(): ModelComponent | undefined { From 64409bf846d0546e16dc0663a834764522d8ad27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 10:13:18 +0100 Subject: [PATCH 11/24] Remove Debug Message --- src/app/game-model/ModelComponentTypeUtillities.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/game-model/ModelComponentTypeUtillities.ts b/src/app/game-model/ModelComponentTypeUtillities.ts index 236cc96..da1f827 100644 --- a/src/app/game-model/ModelComponentTypeUtillities.ts +++ b/src/app/game-model/ModelComponentTypeUtillities.ts @@ -18,7 +18,6 @@ export class ModelComponentTypeUtillities { } static fromString(string: string) : ModelComponentType | undefined { - console.log(string) switch (string) { case "gamesystem": return ModelComponentType.GAMESYTEM; case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT; From 0c328e1fd6b6af4f39ae998638b5f09a5dacc1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 10:17:21 +0100 Subject: [PATCH 12/24] Open Editor to edit Gamesystems --- src/app/app.component.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 43021e3..252e363 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -70,10 +70,18 @@ export class AppComponent implements OnInit{ } private onEditModelComponent() { - if(this.openContent == ModelComponentType.SCRIPTACCOUNT && this.scriptAccountOverview != undefined && this.scriptAccountOverview.selectedScriptAccount != undefined) { - this.editor!.openGameModelComponent(this.scriptAccountOverview.selectedScriptAccount!); - } else { - //Erweitere to Gamesystems + switch (this.openContent!) { + case ModelComponentType.SCRIPTACCOUNT: { + if(this.scriptAccountOverview!.selectedScriptAccount != undefined) { + this.editor!.openGameModelComponent(this.scriptAccountOverview!.selectedScriptAccount); + } + } break; + case ModelComponentType.GAMESYTEM: { + if(this.gamesystemOverview!.selectedGamesystem != undefined) { + const gamesystem = this.gameModel!.findGamesystem(this.gamesystemOverview!.selectedGamesystemName!); + this.editor!.openGameModelComponent(gamesystem!); + } + } break } } From 824ccab48b6837a0199194f28cded9a9b82f3318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 10:23:11 +0100 Subject: [PATCH 13/24] Replace Icon for Gamesystems --- src/app/editor/editor.component.html | 4 +++- .../gamescript-overview.component.html | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index dc9bd38..046bdbf 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -1,7 +1,9 @@ - inventory_2 + inventory_2 + code + {{modelComponent.componentName}} diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html index d8a0d79..d12b880 100644 --- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html @@ -4,7 +4,10 @@ (click)="onSelectGamesystem(node)" (contextmenu)="onSelectGamesystem(node)" (dblclick)="openGamesystemEditor(node)"> - {{node.name}} +
+ + {{node.name}} +
- {{node.name}} +
+ + {{node.name}} +
From 81cda122a496d9687f8ce6f6d389e53cfdc95254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 10:26:56 +0100 Subject: [PATCH 14/24] Fix failing test (include duplicate check) --- src/app/game-model/GameModel.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/game-model/GameModel.ts b/src/app/game-model/GameModel.ts index 9e2a514..ac4d355 100644 --- a/src/app/game-model/GameModel.ts +++ b/src/app/game-model/GameModel.ts @@ -25,7 +25,10 @@ export class GameModel { } addGamesystem(gamesystem: Gamesystem) { - this._gamesystems.push(gamesystem); + if(this.findGamesystem(gamesystem.componentName) == undefined) { + this._gamesystems.push(gamesystem); + } + } removeGamesystem(gamesystem : Gamesystem) { From 9462de256bf6d03be4d543f43206c041b0556ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 11:03:26 +0100 Subject: [PATCH 15/24] Visualize SimpleStates of Simplegamesystems --- src/app/app.component.ts | 3 + src/app/app.module.ts | 111 +++++++++++------- src/app/editor/editor.component.html | 2 + src/app/editor/editor.component.ts | 9 ++ .../gamesystem-editor.component.html | 1 + .../gamesystem-editor.component.scss | 0 .../gamesystem-editor.component.spec.ts | 23 ++++ .../gamesystem-editor.component.ts | 33 ++++++ .../simple-gamesystem-editor.component.html | 1 + .../simple-gamesystem-editor.component.scss | 0 ...simple-gamesystem-editor.component.spec.ts | 23 ++++ .../simple-gamesystem-editor.component.ts | 16 +++ .../simple-state-editor.component.html | 36 ++++++ .../simple-state-editor.component.scss | 51 ++++++++ .../simple-state-editor.component.spec.ts | 23 ++++ .../simple-state-editor.component.ts | 19 +++ src/app/game-model/gamesystems/State.ts | 2 + 17 files changed, 312 insertions(+), 41 deletions(-) create mode 100644 src/app/editor/gamesystem-editor/gamesystem-editor.component.html create mode 100644 src/app/editor/gamesystem-editor/gamesystem-editor.component.scss create mode 100644 src/app/editor/gamesystem-editor/gamesystem-editor.component.spec.ts create mode 100644 src/app/editor/gamesystem-editor/gamesystem-editor.component.ts create mode 100644 src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html create mode 100644 src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.scss create mode 100644 src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.spec.ts create mode 100644 src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.ts create mode 100644 src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html create mode 100644 src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss create mode 100644 src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.spec.ts create mode 100644 src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 252e363..870e90d 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -147,6 +147,9 @@ export class AppComponent implements OnInit{ const weather = new SimpleGamesystem("Weather"); const season = new SimpleGamesystem("Season"); + season.createState("Spring", "Spring, also known as springtime, is one of the four temperate seasons, succeeding winter and preceding summer."); + season.createState("Summer", "Summer is the hottest and brightest of the four temperate seasons, occurring after spring and before autumn. "); + this.gameModel.addGamesystem(weather) this.gameModel.addGamesystem(season); } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 46973c6..12f1b3c 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -30,6 +30,22 @@ import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/de import {MatDialogActions, MatDialogContent, MatDialogTitle} from "@angular/material/dialog"; import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component"; import {MatTree, MatTreeModule} from "@angular/material/tree"; +import {GamesystemEditorComponent} from "./editor/gamesystem-editor/gamesystem-editor.component"; +import { + SimpleGamesystemEditorComponent +} from "./editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component"; +import { + SimpleStateEditorComponent +} from "./editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component"; +import { + MatCell, + MatCellDef, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, + MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef, + MatTable +} from "@angular/material/table"; // AoT requires an exported function for factories const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -42,48 +58,61 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl ScriptAccountEditorComponent, ModelComponentEditorComponent, DeleteConfirmationDialogComponent, - GamescriptOverviewComponent + GamescriptOverviewComponent, + GamesystemEditorComponent, + SimpleGamesystemEditorComponent, + SimpleStateEditorComponent + ], + imports: [ + BrowserModule, + FormsModule, + HttpClientModule, + CoreModule, + SharedModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: httpLoaderFactory, + deps: [HttpClient] + } + }), + BrowserAnimationsModule, + MatIcon, + MatToolbar, + MatButton, + MatFormField, + MatInput, + MatDrawerContainer, + MatDrawer, + MatIconButton, + MatMenuTrigger, + MatMenu, + MatMenuItem, + MatListItem, + MatActionList, + MatTabGroup, + MatTab, + MatTabLabel, + MatLabel, + MatFormField, + ReactiveFormsModule, + MatError, + MatDialogTitle, + MatDialogContent, + MatDialogActions, + MatMiniFabButton, + MatTreeModule, + MatTable, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, + MatCellDef, + MatCell, + MatHeaderRow, + MatRow, + MatHeaderRowDef, + MatRowDef ], - imports: [ - BrowserModule, - FormsModule, - HttpClientModule, - CoreModule, - SharedModule, - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useFactory: httpLoaderFactory, - deps: [HttpClient] - } - }), - BrowserAnimationsModule, - MatIcon, - MatToolbar, - MatButton, - MatFormField, - MatInput, - MatDrawerContainer, - MatDrawer, - MatIconButton, - MatMenuTrigger, - MatMenu, - MatMenuItem, - MatListItem, - MatActionList, - MatTabGroup, - MatTab, - MatTabLabel, - MatLabel, - MatFormField, - ReactiveFormsModule, - MatError, - MatDialogTitle, - MatDialogContent, - MatDialogActions, - MatMiniFabButton, - MatTreeModule, - ], providers: [], bootstrap: [AppComponent] }) diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index 046bdbf..dc13cc1 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -10,6 +10,8 @@ +
diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index 36b6726..c042346 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -3,6 +3,9 @@ import {GameModel} from "../game-model/GameModel"; import {ModelComponent} from "../game-model/ModelComponent"; import {ModelComponentType} from "../game-model/ModelComponentType"; import {ScriptAccount} from "../game-model/scriptAccounts/ScriptAccount"; +import {Gamesystem} from "../game-model/gamesystems/Gamesystem"; +import {State} from "../game-model/gamesystems/State"; +import {Transition} from "../game-model/gamesystems/Transition"; @Component({ selector: 'app-editor', @@ -29,6 +32,12 @@ export class EditorComponent { } } + convertModelComponentToGamesystem(modelComponent: ModelComponent) { + if(modelComponent instanceof Gamesystem) { + return modelComponent as Gamesystem, Transition>; + } + } + protected readonly ModelComponentType = ModelComponentType; onModelNameUpdate() { diff --git a/src/app/editor/gamesystem-editor/gamesystem-editor.component.html b/src/app/editor/gamesystem-editor/gamesystem-editor.component.html new file mode 100644 index 0000000..49bfe84 --- /dev/null +++ b/src/app/editor/gamesystem-editor/gamesystem-editor.component.html @@ -0,0 +1 @@ + diff --git a/src/app/editor/gamesystem-editor/gamesystem-editor.component.scss b/src/app/editor/gamesystem-editor/gamesystem-editor.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/editor/gamesystem-editor/gamesystem-editor.component.spec.ts b/src/app/editor/gamesystem-editor/gamesystem-editor.component.spec.ts new file mode 100644 index 0000000..febd88c --- /dev/null +++ b/src/app/editor/gamesystem-editor/gamesystem-editor.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GamesystemEditorComponent } from './gamesystem-editor.component'; + +describe('GamesystemEditorComponent', () => { + let component: GamesystemEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GamesystemEditorComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GamesystemEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/editor/gamesystem-editor/gamesystem-editor.component.ts b/src/app/editor/gamesystem-editor/gamesystem-editor.component.ts new file mode 100644 index 0000000..666f6a6 --- /dev/null +++ b/src/app/editor/gamesystem-editor/gamesystem-editor.component.ts @@ -0,0 +1,33 @@ +import {Component, Input} from '@angular/core'; +import {GameModel} from "../../game-model/GameModel"; +import {Gamesystem} from "../../game-model/gamesystems/Gamesystem"; +import {State} from "../../game-model/gamesystems/State"; +import {Transition} from "../../game-model/gamesystems/Transition"; +import {SimpleGamesystem} from "../../game-model/gamesystems/SimpleGamesystem"; +import {ProductGamesystem} from "../../game-model/gamesystems/ProductGamesystem"; + +@Component({ + selector: 'app-gamesystem-editor', + templateUrl: './gamesystem-editor.component.html', + styleUrl: './gamesystem-editor.component.scss' +}) +export class GamesystemEditorComponent { + + @Input() gamesystem: Gamesystem, Transition> | undefined + + isSimpleGamesystem() { + return this.gamesystem instanceof SimpleGamesystem; + } + + convertGamesystemToSimpleGamesystem() { + if(this.gamesystem instanceof SimpleGamesystem) { + return this.gamesystem as SimpleGamesystem; + } + } + + convertGamesystemToProductGamesystem() { + if(this.gamesystem instanceof ProductGamesystem) { + return this.gamesystem as ProductGamesystem; + } + } +} diff --git a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html new file mode 100644 index 0000000..e520b73 --- /dev/null +++ b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html @@ -0,0 +1 @@ + diff --git a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.scss b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.spec.ts b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.spec.ts new file mode 100644 index 0000000..b5688c0 --- /dev/null +++ b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SimpleGamesystemEditorComponent } from './simple-gamesystem-editor.component'; + +describe('SimpleGamesystemEditorComponent', () => { + let component: SimpleGamesystemEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SimpleGamesystemEditorComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SimpleGamesystemEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.ts b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.ts new file mode 100644 index 0000000..ab4fcc5 --- /dev/null +++ b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.ts @@ -0,0 +1,16 @@ +import {Component, Input} from '@angular/core'; +import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem"; +import {MatTableDataSource} from "@angular/material/table"; + +@Component({ + selector: 'app-simple-gamesystem-editor', + templateUrl: './simple-gamesystem-editor.component.html', + styleUrl: './simple-gamesystem-editor.component.scss' +}) +export class SimpleGamesystemEditorComponent { + + @Input() simpleGamesystem: SimpleGamesystem | undefined + + + +} diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html new file mode 100644 index 0000000..5b9c36a --- /dev/null +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Label{{state.stateLabel}}Label{{state.stateDescription}}Initial + done + close + + + + +
diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss new file mode 100644 index 0000000..9a0a3e1 --- /dev/null +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss @@ -0,0 +1,51 @@ +table { + width: 100%; +} + +tr.example-detail-row { + height: 0; +} + +tr.example-element-row:not(.example-expanded-row):hover { + background: whitesmoke; +} + +tr.example-element-row:not(.example-expanded-row):active { + background: #efefef; +} + +.example-element-row td { + border-bottom-width: 0; +} + +.example-element-detail { + overflow: hidden; + display: flex; +} + +.example-element-diagram { + min-width: 80px; + border: 2px solid black; + padding: 8px; + font-weight: lighter; + margin: 8px 0; + height: 104px; +} + +.example-element-symbol { + font-weight: bold; + font-size: 40px; + line-height: normal; +} + +.example-element-description { + padding: 16px; +} + +.example-element-description-attribution { + opacity: 0.5; +} + +.mat-column-edit, .mat-column-delete { + width: 32px; +} diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.spec.ts b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.spec.ts new file mode 100644 index 0000000..c667357 --- /dev/null +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SimpleStateEditorComponent } from './simple-state-editor.component'; + +describe('SimpleStateEditorComponent', () => { + let component: SimpleStateEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SimpleStateEditorComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SimpleStateEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts new file mode 100644 index 0000000..39387bc --- /dev/null +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts @@ -0,0 +1,19 @@ +import {Component, Input, OnInit} from '@angular/core'; +import {SimpleState} from "../../../../game-model/gamesystems/SimpleState"; +import {MatTableDataSource} from "@angular/material/table"; + +@Component({ + selector: 'app-simple-state-editor', + templateUrl: './simple-state-editor.component.html', + styleUrl: './simple-state-editor.component.scss' +}) +export class SimpleStateEditorComponent implements OnInit{ + + @Input() states: SimpleState[] = []; + dataSource = new MatTableDataSource(); + displayedColumns = ["name", "initial", "edit", "delete"]; + + ngOnInit() { + this.dataSource.data = this.states; + } +} diff --git a/src/app/game-model/gamesystems/State.ts b/src/app/game-model/gamesystems/State.ts index 96fe983..5184811 100644 --- a/src/app/game-model/gamesystems/State.ts +++ b/src/app/game-model/gamesystems/State.ts @@ -6,6 +6,8 @@ export abstract class State> { incomingTransitions: T[] =[]; outgoingTransitions: T[] =[]; + initial: boolean = false; + constructor(stateLabel: string, stateDescription: string) { this.stateLabel = stateLabel; From 8df38376d04d0bc3d1aa931fb27b4b7d09b6a55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 11:09:53 +0100 Subject: [PATCH 16/24] Include description in simple state visualisation --- .../simple-state-editor.component.html | 36 +++++++++++++++---- .../simple-state-editor.component.scss | 6 ++-- .../simple-state-editor.component.ts | 12 ++++++- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html index 5b9c36a..4c42012 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html @@ -1,14 +1,20 @@ - +
- - - + + + + + - - + + + + + + + + +
Label {{state.stateLabel}} Label{{state.stateDescription}} +
+

{{element.stateDescription}}

+
+
Initial @@ -31,6 +37,24 @@
  + +
diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss index 9a0a3e1..4ae2ebf 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss @@ -7,11 +7,11 @@ tr.example-detail-row { } tr.example-element-row:not(.example-expanded-row):hover { - background: whitesmoke; + background: #545456 } tr.example-element-row:not(.example-expanded-row):active { - background: #efefef; + background: #545456; } .example-element-row td { @@ -46,6 +46,6 @@ tr.example-element-row:not(.example-expanded-row):active { opacity: 0.5; } -.mat-column-edit, .mat-column-delete { +.mat-column-edit, .mat-column-delete, .mat-column-expand { width: 32px; } diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts index 39387bc..1b62bce 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts @@ -1,17 +1,27 @@ import {Component, Input, OnInit} from '@angular/core'; import {SimpleState} from "../../../../game-model/gamesystems/SimpleState"; import {MatTableDataSource} from "@angular/material/table"; +import {animate, state, style, transition, trigger} from "@angular/animations"; @Component({ selector: 'app-simple-state-editor', templateUrl: './simple-state-editor.component.html', - styleUrl: './simple-state-editor.component.scss' + styleUrl: './simple-state-editor.component.scss', + animations: [ + trigger('detailExpand', [ + state('collapsed,void', style({height: '0px', minHeight: '0'})), + state('expanded', style({height: '*'})), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), + ]), + ], }) export class SimpleStateEditorComponent implements OnInit{ @Input() states: SimpleState[] = []; dataSource = new MatTableDataSource(); displayedColumns = ["name", "initial", "edit", "delete"]; + columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; + expandedElement: SimpleState | null = null; ngOnInit() { this.dataSource.data = this.states; From 5d517c3e971c176c0c5c86bee36fe1673b44796c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 11:22:07 +0100 Subject: [PATCH 17/24] Basic SimpleState Editing --- src/app/app.module.ts | 4 ++- .../simple-state-editor.component.html | 30 +++++++++++++++---- .../simple-state-editor.component.scss | 4 +++ .../simple-state-editor.component.ts | 9 ++++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 12f1b3c..8e5ae65 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -46,6 +46,7 @@ import { MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef, MatTable } from "@angular/material/table"; +import {MatCheckbox} from "@angular/material/checkbox"; // AoT requires an exported function for factories const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -111,7 +112,8 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl MatHeaderRow, MatRow, MatHeaderRowDef, - MatRowDef + MatRowDef, + MatCheckbox ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html index 4c42012..dc67e1e 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html @@ -1,14 +1,23 @@ - + @@ -18,15 +27,22 @@ @@ -38,7 +54,9 @@ - + @@ -39,10 +40,8 @@ diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss index 3219c1e..0830e19 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss @@ -53,3 +53,11 @@ tr.example-element-row:not(.example-expanded-row):active { .long-form { width: 100%; } + +.mat-error { + color: red; +} + +.warning-icon { + margin-right: 5px; +} diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts index 3a13320..1172f60 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts @@ -2,6 +2,7 @@ import {Component, Input, OnInit} from '@angular/core'; import {SimpleState} from "../../../../game-model/gamesystems/SimpleState"; import {MatTableDataSource} from "@angular/material/table"; import {animate, state, style, transition, trigger} from "@angular/animations"; +import {MatSnackBar} from "@angular/material/snack-bar"; @Component({ selector: 'app-simple-state-editor', @@ -24,6 +25,11 @@ export class SimpleStateEditorComponent implements OnInit{ expandedElement: SimpleState | null = null; editedElement: SimpleState | null = null; + editedStateLabelError: boolean = false; + + constructor(private snackbar: MatSnackBar) { + } + ngOnInit() { this.dataSource.data = this.states; } @@ -35,4 +41,20 @@ export class SimpleStateEditorComponent implements OnInit{ this.editedElement = state; } } + + finishEditing() { + if(this.isEditedStateValid()) { + this.editedElement = null; + } + } + + isEditedStateValid(): boolean { + if(this.editedElement!.stateLabel.length > 0) { + this.editedStateLabelError = false; + return true; + } else { + this.editedStateLabelError = true; + } + return false; + } } From 19cfe8290542336f8953f0cea49d412e9dbb8094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 11:48:58 +0100 Subject: [PATCH 19/24] Delete States (only top-level simple-gamesystems) --- .../simple-gamesystem-editor.component.html | 2 +- .../simple-state-editor.component.html | 2 +- .../simple-state-editor.component.ts | 11 +++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html index e520b73..78dcc5c 100644 --- a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html +++ b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html @@ -1 +1 @@ - + diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html index f7c6b5f..e38a1d9 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html @@ -48,7 +48,7 @@ diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts index 1172f60..bab330a 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts @@ -3,6 +3,7 @@ import {SimpleState} from "../../../../game-model/gamesystems/SimpleState"; import {MatTableDataSource} from "@angular/material/table"; import {animate, state, style, transition, trigger} from "@angular/animations"; import {MatSnackBar} from "@angular/material/snack-bar"; +import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem"; @Component({ selector: 'app-simple-state-editor', @@ -19,6 +20,7 @@ import {MatSnackBar} from "@angular/material/snack-bar"; export class SimpleStateEditorComponent implements OnInit{ @Input() states: SimpleState[] = []; + @Input() gamesystem: SimpleGamesystem | undefined dataSource = new MatTableDataSource(); displayedColumns = ["name", "initial", "edit", "delete"]; columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; @@ -57,4 +59,13 @@ export class SimpleStateEditorComponent implements OnInit{ } return false; } + + deleteState(state: SimpleState) { + if(this.gamesystem == undefined || this.gamesystem.parentGamesystem == undefined) { + this.gamesystem?.removeState(state); + this.dataSource.data = this.gamesystem!.states + } else { + + } + } } From 4dbed5a855b0f09189a37b15514ca0ea6171b4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 11:51:32 +0100 Subject: [PATCH 20/24] Create new States in Editor --- .../simple-state-editor.component.html | 2 +- .../simple-state-editor.component.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html index e38a1d9..e2e6dc8 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html @@ -54,7 +54,7 @@ @@ -17,7 +17,7 @@

{{element.stateDescription}}

Description - + @@ -32,7 +32,7 @@ doneclose - + diff --git a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts index cbd80ee..76c5bef 100644 --- a/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts @@ -76,7 +76,11 @@ export class SimpleStateEditorComponent implements OnInit{ this.dataSource.data = this.gamesystem.states; this.editedElement = simpleState; this.expandedElement = simpleState; + this.onStateChange(); } } } + onStateChange() { + this.gamesystem!.onModifyContent(); + } } From 7a8c939d6ac6923a4c85cac3272b2ff3b4b471e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 12:21:31 +0100 Subject: [PATCH 22/24] Visualize SimpleTransitions --- src/app/app.component.ts | 6 +- src/app/app.module.ts | 6 +- .../simple-gamesystem-editor.component.html | 1 + .../simple-gamesystem-editor.component.scss | 3 + .../simple-transition-editor.component.html | 56 +++++++++++++++++++ .../simple-transition-editor.component.scss | 51 +++++++++++++++++ ...simple-transition-editor.component.spec.ts | 23 ++++++++ .../simple-transition-editor.component.ts | 38 +++++++++++++ 8 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html create mode 100644 src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.scss create mode 100644 src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.spec.ts create mode 100644 src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 870e90d..c23a46e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -147,8 +147,10 @@ export class AppComponent implements OnInit{ const weather = new SimpleGamesystem("Weather"); const season = new SimpleGamesystem("Season"); - season.createState("Spring", "Spring, also known as springtime, is one of the four temperate seasons, succeeding winter and preceding summer."); - season.createState("Summer", "Summer is the hottest and brightest of the four temperate seasons, occurring after spring and before autumn. "); + const springState = season.createState("Spring", "Spring, also known as springtime, is one of the four temperate seasons, succeeding winter and preceding summer."); + const summerState = season.createState("Summer", "Summer is the hottest and brightest of the four temperate seasons, occurring after spring and before autumn. "); + + season.createTransition(springState!, summerState!); this.gameModel.addGamesystem(weather) this.gameModel.addGamesystem(season); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8e5ae65..31cd04f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -47,6 +47,9 @@ import { MatTable } from "@angular/material/table"; import {MatCheckbox} from "@angular/material/checkbox"; +import { + SimpleTransitionEditorComponent +} from "./editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component"; // AoT requires an exported function for factories const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -62,7 +65,8 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl GamescriptOverviewComponent, GamesystemEditorComponent, SimpleGamesystemEditorComponent, - SimpleStateEditorComponent + SimpleStateEditorComponent, + SimpleTransitionEditorComponent ], imports: [ BrowserModule, diff --git a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html index 78dcc5c..5ad3526 100644 --- a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html +++ b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html @@ -1 +1,2 @@ + diff --git a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.scss b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.scss index e69de29..7112fce 100644 --- a/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.scss +++ b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.scss @@ -0,0 +1,3 @@ +.transition-editor { + margin-top: 15px; +} diff --git a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html new file mode 100644 index 0000000..edd4815 --- /dev/null +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html @@ -0,0 +1,56 @@ +
Label{{state.stateLabel}} + {{state.stateLabel}} + + + +
-

{{element.stateDescription}}

+

{{element.stateDescription}}

+ + Description + +
Initial - done - close +
+ done + close +
+ +
- +   + + {{state.stateLabel}} - + + warningMissing State-Label Information - + + - + - + {{state.stateLabel}} - + warningMissing State-Label Information
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Starting State{{transition.startingState.stateLabel}}Ending State{{transition.endingState.stateLabel}} +
+

Expanded Detail

+
+
+ + + +   + +
diff --git a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.scss b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.scss new file mode 100644 index 0000000..26f0b74 --- /dev/null +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.scss @@ -0,0 +1,51 @@ +table { + width: 100%; + margin-top: 20px; +} +.mat-column-edit, .mat-column-delete, .mat-column-expand { + width: 32px; +} + +tr.example-detail-row { + height: 0; +} + +tr.example-element-row:not(.example-expanded-row):hover { + background: #545456; +} + +tr.example-element-row:not(.example-expanded-row):active { + background: #545456; +} + +.example-element-row td { + border-bottom-width: 0; +} + +.example-element-detail { + overflow: hidden; + display: flex; +} + +.example-element-diagram { + min-width: 80px; + border: 2px solid black; + padding: 8px; + font-weight: lighter; + margin: 8px 0; + height: 104px; +} + +.example-element-symbol { + font-weight: bold; + font-size: 40px; + line-height: normal; +} + +.example-element-description { + padding: 16px; +} + +.example-element-description-attribution { + opacity: 0.5; +} diff --git a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.spec.ts b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.spec.ts new file mode 100644 index 0000000..0edfece --- /dev/null +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SimpleTransitionEditorComponent } from './simple-transition-editor.component'; + +describe('SimpleTransitionEditorComponent', () => { + let component: SimpleTransitionEditorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SimpleTransitionEditorComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SimpleTransitionEditorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts new file mode 100644 index 0000000..146d59f --- /dev/null +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts @@ -0,0 +1,38 @@ +import {Component, Input, OnInit} from '@angular/core'; +import {GameModel} from "../../../../game-model/GameModel"; +import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem"; +import { + MatCell, + MatCellDef, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef, + MatTable, + MatTableDataSource +} from "@angular/material/table"; +import {SimpleTransition} from "../../../../game-model/gamesystems/SimpleTransition"; +import {animate, state, style, transition, trigger} from "@angular/animations"; + +@Component({ + selector: 'app-simple-transition-editor', + templateUrl: './simple-transition-editor.component.html', + styleUrl: './simple-transition-editor.component.scss', + animations: [ + trigger('detailExpand', [ + state('collapsed,void', style({height: '0px', minHeight: '0'})), + state('expanded', style({height: '*'})), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), + ]), + ], +}) +export class SimpleTransitionEditorComponent implements OnInit { + + @Input() gamesystem: SimpleGamesystem | undefined + displayedColumns: string[] = ["starting-state", "ending-state", "edit", "delete"]; + dataSource = new MatTableDataSource(); + columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; + expandedElement: SimpleTransition | null = null; + ngOnInit() { + this.dataSource.data = this.gamesystem!.transitions; + } +} From b730cc1d000fad010fe967077b35ffea9a58cdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 10 Feb 2024 12:51:07 +0100 Subject: [PATCH 23/24] Edit SimpleTransitions --- src/app/app.module.ts | 8 +++- .../simple-transition-editor.component.html | 33 +++++++++++++-- .../simple-transition-editor.component.scss | 12 ++++++ .../simple-transition-editor.component.ts | 41 +++++++++++++++++++ 4 files changed, 88 insertions(+), 6 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 31cd04f..4461bfd 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -14,7 +14,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import {MatIcon} from "@angular/material/icon"; import {MatToolbar} from "@angular/material/toolbar"; import {MatButton, MatIconButton, MatMiniFabButton} from "@angular/material/button"; -import {MatError, MatFormField, MatLabel} from "@angular/material/form-field"; +import {MatError, MatFormField, MatHint, MatLabel} from "@angular/material/form-field"; import {MatInput} from "@angular/material/input"; import {MatDrawer, MatDrawerContainer} from "@angular/material/sidenav"; import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu"; @@ -50,6 +50,7 @@ import {MatCheckbox} from "@angular/material/checkbox"; import { SimpleTransitionEditorComponent } from "./editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component"; +import {MatOption, MatSelect} from "@angular/material/select"; // AoT requires an exported function for factories const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -117,7 +118,10 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl MatRow, MatHeaderRowDef, MatRowDef, - MatCheckbox + MatCheckbox, + MatSelect, + MatOption, + MatHint ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html index edd4815..57eab7d 100644 --- a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html @@ -1,12 +1,32 @@ - + - + @@ -21,7 +41,10 @@ @@ -33,7 +56,9 @@ - + diff --git a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts index fe8f245..c1f64ee 100644 --- a/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts @@ -76,4 +76,11 @@ export class SimpleTransitionEditorComponent implements OnInit { this.dataSource.data = this.gamesystem!.transitions; this.editedTransition = undefined; } + + deleteTransition(transition: SimpleTransition) { + if(this.gamesystem!.parentGamesystem == undefined) { + this.gamesystem!.removeTransition(transition); + this.dataSource.data = this.gamesystem!.transitions; + } + } }
Starting State{{transition.startingState.stateLabel}} + {{transition.startingState.stateLabel}} + + + {{state.stateLabel}} + + warning Starting and Ending State cannot be the same! + warning Select a valid Starting State! + + Ending State{{transition.endingState.stateLabel}} + {{transition.endingState.stateLabel}} + + + {{state.stateLabel}} + + warning Starting and Ending State cannot be the same! + warning Select a valid Ending State! + + - + +   + + - +