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/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..515882e --- /dev/null +++ b/e2e/game-model/gamesystems/GamesystemTrainer.ts @@ -0,0 +1,55 @@ +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 SIMPLEGAMESYSTEM_LEAF_LEFT: string = "Leaf Gamesystem Left" + static SIMPLEGAMESYSTEM_LEAF_RIGHT: string = "Leaf Gamesystem Right"; + + 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; + } + + 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/gamesystems/SimpleGamesystem.spec.ts b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts new file mode 100644 index 0000000..4c61efd --- /dev/null +++ b/e2e/game-model/gamesystems/SimpleGamesystem.spec.ts @@ -0,0 +1,172 @@ +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 () => { + 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 () => { + 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(); + + }) +}); 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.html b/src/app/app.component.html index 2beb7f6..85d1f15 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,6 +2,8 @@
+
@@ -17,13 +19,15 @@ + - + +
- +
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 325cbac..c23a46e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -13,6 +13,8 @@ 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"; +import {SimpleGamesystem} from "./game-model/gamesystems/SimpleGamesystem"; @Component({ selector: 'app-root', @@ -25,6 +27,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 @@ -42,29 +45,89 @@ 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() { + 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 + } + } + + 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; + } + const createdGamesystem = this.gameModel!.createGamesystem("New Gamesystem", parentGamesystemName); + if(createdGamesystem != undefined) { + this.gamesystemOverview!.refresh(); + this.editor?.openGameModelComponent(createdGamesystem!); + } + } + private getSelectedModelComponent(): ModelComponent | undefined { if(this.openContent == ModelComponentType.SCRIPTACCOUNT) { if(this.scriptAccountOverview != undefined) { @@ -78,8 +141,19 @@ 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"); + + 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); } openScriptAccountsOverview() { @@ -87,6 +161,11 @@ export class AppComponent implements OnInit{ this.drawer!.open(); } + openGamesystemsOverview() { + this.openContent = ModelComponentType.GAMESYTEM; + this.drawer!.open(); + } + protected readonly ModelComponentType = ModelComponentType; closeContentOverview() { @@ -102,6 +181,11 @@ export class AppComponent implements OnInit{ } else { console.log("[WARN] [App.Component] Editor is undefined") } + } + onModelNameUpdate() { + if(this.openContent == ModelComponentType.GAMESYTEM) { + this.gamesystemOverview!.refresh(); + } } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c3edf21..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"; @@ -28,6 +28,29 @@ 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"; +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"; +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'); @@ -39,7 +62,12 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl EditorComponent, ScriptAccountEditorComponent, ModelComponentEditorComponent, - DeleteConfirmationDialogComponent + DeleteConfirmationDialogComponent, + GamescriptOverviewComponent, + GamesystemEditorComponent, + SimpleGamesystemEditorComponent, + SimpleStateEditorComponent, + SimpleTransitionEditorComponent ], imports: [ BrowserModule, @@ -79,6 +107,21 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl MatDialogContent, MatDialogActions, MatMiniFabButton, + MatTreeModule, + MatTable, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, + MatCellDef, + MatCell, + MatHeaderRow, + MatRow, + MatHeaderRowDef, + MatRowDef, + MatCheckbox, + MatSelect, + MatOption, + MatHint ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index ef4276b..dc13cc1 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -1,13 +1,17 @@ - inventory_2 + inventory_2 + code + {{modelComponent.componentName}} - + + diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index 6b222fe..c042346 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -1,8 +1,11 @@ -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"; 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', @@ -11,6 +14,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)) { @@ -28,5 +32,15 @@ export class EditorComponent { } } + convertModelComponentToGamesystem(modelComponent: ModelComponent) { + if(modelComponent instanceof Gamesystem) { + return modelComponent as Gamesystem, Transition>; + } + } + protected readonly ModelComponentType = ModelComponentType; + + onModelNameUpdate() { + this.onModelNameUpdateEmitter.emit(true); + } } 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..5ad3526 --- /dev/null +++ b/src/app/editor/gamesystem-editor/simple-gamesystem-editor/simple-gamesystem-editor.component.html @@ -0,0 +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 new file mode 100644 index 0000000..7112fce --- /dev/null +++ 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/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..f723e19 --- /dev/null +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.html @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Label + {{state.stateLabel}} + + + warningMissing State-Label Information + + +
+

{{element.stateDescription}}

+ + Description + + +
+
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..0830e19 --- /dev/null +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.scss @@ -0,0 +1,63 @@ +table { + width: 100%; +} + +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; +} + +.mat-column-edit, .mat-column-delete, .mat-column-expand { + width: 32px; +} + +.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.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..76c5bef --- /dev/null +++ b/src/app/editor/gamesystem-editor/state-editor/simple-state-editor/simple-state-editor.component.ts @@ -0,0 +1,86 @@ +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"; +import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem"; + +@Component({ + selector: 'app-simple-state-editor', + templateUrl: './simple-state-editor.component.html', + 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[] = []; + @Input() gamesystem: SimpleGamesystem | undefined + dataSource = new MatTableDataSource(); + displayedColumns = ["name", "initial", "edit", "delete"]; + columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; + expandedElement: SimpleState | null = null; + editedElement: SimpleState | null = null; + + editedStateLabelError: boolean = false; + + constructor(private snackbar: MatSnackBar) { + } + + ngOnInit() { + this.dataSource.data = this.states; + } + + editState(state: SimpleState) { + if(this.editedElement === state) { + this.editedElement = null; + } else { + 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; + } + + deleteState(state: SimpleState) { + if(this.gamesystem == undefined || this.gamesystem.parentGamesystem == undefined) { + this.gamesystem?.removeState(state); + this.dataSource.data = this.gamesystem!.states + } else { + + } + } + + addState() { + if(this.gamesystem != undefined) { + const simpleState = this.gamesystem.createState("New State", ""); + if(simpleState != undefined) { + this.dataSource.data = this.gamesystem.states; + this.editedElement = simpleState; + this.expandedElement = simpleState; + this.onStateChange(); + } + } + } + onStateChange() { + this.gamesystem!.onModifyContent(); + } +} 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..1ad5505 --- /dev/null +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.html @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Starting State + {{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}} + + + {{state.stateLabel}} + + warning Starting and Ending State cannot be the same! + warning Select a valid Ending State! + + +
+

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..3292508 --- /dev/null +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.scss @@ -0,0 +1,63 @@ +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; +} + +.long-form { + width: 100%; +} + +.warning-icon { + margin-right: 5px; +} + +.mat-error { + color: red; +} 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..c1f64ee --- /dev/null +++ b/src/app/editor/gamesystem-editor/transition-editor/simple-transition-editor/simple-transition-editor.component.ts @@ -0,0 +1,86 @@ +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"; +import {SimpleState} from "../../../../game-model/gamesystems/SimpleState"; + +@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; + editedTransition: SimpleTransition | undefined + editedTransitionIndex = -1; + + defaultStartingState: SimpleState = new SimpleState("None", ""); + defaultEndingState: SimpleState = new SimpleState("None", ""); + + transitionError: boolean = false; + transitionStartingStateError = true; + transitionEndingStateError = true; + ngOnInit() { + this.dataSource.data = this.gamesystem!.transitions; + } + + addTransition() { + this.editedTransition = new SimpleTransition(this.defaultStartingState, this.defaultEndingState); + const updatedData = this.dataSource.data; + updatedData.push(this.editedTransition); + this.dataSource.data = updatedData; + this.editedTransitionIndex = this.dataSource.data.length; + } + + validateEditedTransition() { + this.transitionError = false; + this.transitionStartingStateError = false; + this.transitionEndingStateError = false; + if(this.editedTransition!.startingState === this.editedTransition!.endingState) { + this.transitionError = true; + } else if(this.editedTransition!.startingState == this.defaultStartingState) { + this.transitionStartingStateError = true; + } else if(this.editedTransition!.endingState == this.defaultEndingState) { + this.transitionEndingStateError = true; + } + } + + finishEditing() { + this.validateEditedTransition(); + if(this.transitionError || this.transitionStartingStateError || this.transitionEndingStateError) { + return; + } + this.gamesystem?.createTransition(this.editedTransition!.startingState, this.editedTransition!.endingState); + 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; + } + } +} 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/game-model/GameModel.ts b/src/app/game-model/GameModel.ts index a061db3..ac4d355 100644 --- a/src/app/game-model/GameModel.ts +++ b/src/app/game-model/GameModel.ts @@ -1,10 +1,14 @@ 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"; +import {SimpleGamesystem} from "./gamesystems/SimpleGamesystem"; export class GameModel { private readonly _gameModelName: string - private _gamesystems: Gamesystem[] = []; + private _gamesystems: Gamesystem[] = []; private _scriptAccounts: ScriptAccount[] = []; constructor(gameModelName: string) { @@ -13,26 +17,25 @@ 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) { - if(!this.gamesystems.includes(gamesystem)) { + addGamesystem(gamesystem: Gamesystem) { + if(this.findGamesystem(gamesystem.componentName) == undefined) { this._gamesystems.push(gamesystem); } + } - removeGamesystem(gamesystem : 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); @@ -44,10 +47,47 @@ 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); } } + 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/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..da1f827 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,7 +12,15 @@ export class ModelComponentTypeUtillities { static toSingleString(modelComponentType: ModelComponentType | undefined): string { switch (modelComponentType) { case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccount"; + case ModelComponentType.GAMESYTEM: return "Gamesystem"; default: return "Undefined"; } } + + static fromString(string: string) : ModelComponentType | undefined { + switch (string) { + case "gamesystem": return ModelComponentType.GAMESYTEM; + case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT; + } + } } diff --git a/src/app/game-model/gamesystems/Gamesystem.ts b/src/app/game-model/gamesystems/Gamesystem.ts index 989e9c0..0dea6ba 100644 --- a/src/app/game-model/gamesystems/Gamesystem.ts +++ b/src/app/game-model/gamesystems/Gamesystem.ts @@ -1,8 +1,35 @@ -export class Gamesystem { - gamesystemName: 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; + super(gamesystemName, "", ModelComponentType.GAMESYTEM); + } + + 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; } + save() { + + } + } diff --git a/src/app/game-model/gamesystems/ProductGamesystem.ts b/src/app/game-model/gamesystems/ProductGamesystem.ts new file mode 100644 index 0000000..84a135d --- /dev/null +++ b/src/app/game-model/gamesystems/ProductGamesystem.ts @@ -0,0 +1,60 @@ +import {Gamesystem} from "./Gamesystem"; +import {ProductState} from "./ProductState"; +import {ProductTransition} from "./ProductTransition"; +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: 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; + } + + createTransition(startingState: ProductState, endingState: ProductState): ProductTransition | undefined { + return undefined; + } + + removeState(state: ProductState): boolean { + return false; + } + + removeInnerState(state: SimpleState) { + + } + + + addChildGamesystem(gamesystem: Gamesystem, Transition>) { + this.innerGamesystems.push(gamesystem); + } + + private removeChildGamesystem(gamesystem: Gamesystem, Transition>) { + this.innerGamesystems = this.innerGamesystems.filter(childSystem => childSystem != 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..4021c93 --- /dev/null +++ b/src/app/game-model/gamesystems/SimpleGamesystem.ts @@ -0,0 +1,60 @@ +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; + } + + 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 { + 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; + } + + +} 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..5184811 --- /dev/null +++ b/src/app/game-model/gamesystems/State.ts @@ -0,0 +1,32 @@ +import {Transition} from "./Transition"; + +export abstract class State> { + stateLabel: string = ""; + stateDescription: string = ""; + incomingTransitions: T[] =[]; + outgoingTransitions: T[] =[]; + + initial: boolean = false; + + + 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); + } +} 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..d12b880 --- /dev/null +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.html @@ -0,0 +1,27 @@ + + + + + +
+ + {{node.name}} +
+
+ + + +
+ + {{node.name}} +
+
+
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..6a35f58 --- /dev/null +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.scss @@ -0,0 +1,40 @@ +.mat-tree-node { + min-height: 1.8em !important; + height: 1.8em; +} + + +.small-icon-button { + width: 26px !important; + height: 26px !important; + padding: 0px !important; + display: inline-flex !important; + align-items: center; + justify-content: center; + margin-left: 5px; + margin-bottom: 2px; + + & > *[role=img] { + width: 18px; + height: 18px; + font-size: 18px; + + svg { + width: 18px; + height: 18px; + } + } + + .mat-mdc-button-touch-target { + width: 22px !important; + height: 22px !important; + } +} + +.small-icon-button mat-icon { + color: whitesmoke; +} + +.selected-node { + background-color: #545456 +} 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..4c07292 --- /dev/null +++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts @@ -0,0 +1,106 @@ +import {Component, EventEmitter, Input, OnInit, Output} 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"; +import {ElectronService} from "../../core/services"; + + +interface FlatNode { + expandable: boolean, + name: string, + level: number +} +@Component({ + selector: 'app-gamescript-overview', + templateUrl: './gamescript-overview.component.html', + styleUrl: './gamescript-overview.component.scss' +}) +export class GamescriptOverviewComponent implements OnInit { + + @Input('gameModel') gameModel: GameModel | undefined + @Output('openGamesystemEditor') openGamesystemEmitter : EventEmitter, Transition>> = new EventEmitter, Transition>>(); + + + 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); + selectedGamesystem: FlatNode | undefined; + + constructor(private electronService: ElectronService) { + + } + + hasChild = (_: number, node: FlatNode) => node.expandable; + + + isSimpleGamesystem(gamesystem: Gamesystem, Transition>) { + return gamesystem instanceof SimpleGamesystem; + } + + isProductGamesystem(gamesystem: Gamesystem, Transition>) { + return gamesystem instanceof ProductGamesystem; + } + + onSelectGamesystem(node: FlatNode) { + this.selectedGamesystem = node; + } + + onContextMenu(event: MouseEvent) { + this.electronService.ipcRenderer.send('context-menu', {x: event.x, y: event.y}); + } + + openGamesystemEditor(node: FlatNode) { + const gamesystem: Gamesystem, Transition>| undefined= this.gameModel!.findGamesystem(node.name); + if(gamesystem != undefined) { + gamesystem.unsaved = false; + this.openGamesystemEmitter.emit(gamesystem); + } + } + + 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) {