Merge pull request 'issue-15' (#21) from issue-15 into main
All checks were successful
E2E Testing / test (push) Successful in 7m28s
All checks were successful
E2E Testing / test (push) Successful in 7m28s
Reviewed-on: #21
This commit is contained in:
commit
ef9f24544a
@ -3,7 +3,8 @@
|
|||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
"app/**/*", // ignore nodeJs files
|
"app/**/*", // ignore nodeJs files
|
||||||
"dist/**/*",
|
"dist/**/*",
|
||||||
"release/**/*"
|
"release/**/*",
|
||||||
|
"src/**/*"
|
||||||
],
|
],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.LoadModel = void 0;
|
|
||||||
class LoadModel {
|
|
||||||
constructor(jsonString, modelType) {
|
|
||||||
this.jsonString = jsonString;
|
|
||||||
this.modelType = modelType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.LoadModel = LoadModel;
|
|
||||||
//# sourceMappingURL=LoadModel.js.map
|
|
@ -1,12 +0,0 @@
|
|||||||
import {ModelComponentType} from "../src/app/game-model/ModelComponentType";
|
|
||||||
|
|
||||||
export class LoadModel {
|
|
||||||
jsonString: string
|
|
||||||
modelType: ModelComponentType
|
|
||||||
|
|
||||||
|
|
||||||
constructor(jsonString: string, modelType: ModelComponentType) {
|
|
||||||
this.jsonString = jsonString;
|
|
||||||
this.modelType = modelType;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.LoadedProject = void 0;
|
|
||||||
class LoadedProject {
|
|
||||||
constructor(projectName, loadedModels) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.loadedModels = loadedModels;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.LoadedProject = LoadedProject;
|
|
||||||
//# sourceMappingURL=LoadedProject.js.map
|
|
@ -1,12 +0,0 @@
|
|||||||
import {LoadModel} from "./LoadModel";
|
|
||||||
|
|
||||||
export class LoadedProject {
|
|
||||||
projectName: string
|
|
||||||
loadedModels: LoadModel[]
|
|
||||||
|
|
||||||
|
|
||||||
constructor(projectName: string, loadedModels: LoadModel[]) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.loadedModels = loadedModels;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.RecursiveLoadModel = void 0;
|
|
||||||
const LoadModel_1 = require("./LoadModel");
|
|
||||||
class RecursiveLoadModel extends LoadModel_1.LoadModel {
|
|
||||||
constructor(jsonString, modelType, parentLoadModelname) {
|
|
||||||
super(jsonString, modelType);
|
|
||||||
this.parentLoadModelname = parentLoadModelname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.RecursiveLoadModel = RecursiveLoadModel;
|
|
||||||
//# sourceMappingURL=RecursiveLoadModel.js.map
|
|
@ -1,12 +0,0 @@
|
|||||||
import {LoadModel} from "./LoadModel";
|
|
||||||
import {ModelComponentType} from "../src/app/game-model/ModelComponentType";
|
|
||||||
|
|
||||||
export class RecursiveLoadModel extends LoadModel {
|
|
||||||
parentLoadModelname: string
|
|
||||||
|
|
||||||
|
|
||||||
constructor(jsonString: string, modelType: ModelComponentType, parentLoadModelname: string) {
|
|
||||||
super(jsonString, modelType);
|
|
||||||
this.parentLoadModelname = parentLoadModelname;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.SaveProject = void 0;
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("node:path");
|
|
||||||
const LoadModel_1 = require("./LoadModel");
|
|
||||||
const ModelComponentType_1 = require("../src/app/game-model/ModelComponentType");
|
|
||||||
const LoadedProject_1 = require("./LoadedProject");
|
|
||||||
const RecursiveLoadModel_1 = require("./RecursiveLoadModel");
|
|
||||||
class SaveProject {
|
|
||||||
static saveProject(projectDir, storageModels) {
|
|
||||||
if (!fs.existsSync(projectDir)) {
|
|
||||||
fs.mkdirSync(projectDir, { recursive: true });
|
|
||||||
}
|
|
||||||
console.log(storageModels);
|
|
||||||
storageModels.forEach(storageModel => {
|
|
||||||
let modelDir = path.join(projectDir, storageModel.storageRootDir);
|
|
||||||
storageModel.storagePath.forEach(pathElement => modelDir = path.join(modelDir, pathElement));
|
|
||||||
if (!fs.existsSync(modelDir)) {
|
|
||||||
fs.mkdirSync(modelDir, { recursive: true });
|
|
||||||
}
|
|
||||||
const filePath = path.join(modelDir, storageModel.fileName + ".json");
|
|
||||||
fs.writeFile(filePath, storageModel.jsonString, 'utf-8', (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error writing JSON to file:', err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log('JSON file saved successfully:', filePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
static loadProject(projectDir) {
|
|
||||||
let loadedScriptAccounts = SaveProject.loadScriptAccounts(projectDir);
|
|
||||||
loadedScriptAccounts = loadedScriptAccounts.concat(SaveProject.loadGamesystems(projectDir));
|
|
||||||
return new LoadedProject_1.LoadedProject(path.basename(projectDir), loadedScriptAccounts);
|
|
||||||
}
|
|
||||||
static loadScriptAccounts(projectDir) {
|
|
||||||
const scriptAccountDir = path.join(projectDir, "script-accounts");
|
|
||||||
if (!fs.existsSync(scriptAccountDir)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const loadedScriptAccounts = [];
|
|
||||||
const scriptAccountFileNames = fs.readdirSync(scriptAccountDir);
|
|
||||||
scriptAccountFileNames.forEach(scriptAccountFileName => {
|
|
||||||
const scriptAccountFile = path.join(scriptAccountDir, scriptAccountFileName);
|
|
||||||
const scriptAccountData = fs.readFileSync(scriptAccountFile, 'utf-8');
|
|
||||||
loadedScriptAccounts.push({
|
|
||||||
modelType: ModelComponentType_1.ModelComponentType.SCRIPTACCOUNT,
|
|
||||||
jsonString: scriptAccountData
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return loadedScriptAccounts;
|
|
||||||
}
|
|
||||||
static loadGamesystems(projectDir) {
|
|
||||||
const gamesystemDir = path.join(projectDir, "gamesystems");
|
|
||||||
const loadedGamesystems = this.loadGamesystemsRecursively(gamesystemDir);
|
|
||||||
console.log("LoadedGamesystems: ", loadedGamesystems.length);
|
|
||||||
return loadedGamesystems;
|
|
||||||
}
|
|
||||||
static loadGamesystemsRecursively(gamesystemDir) {
|
|
||||||
let loadedGamesystems = [];
|
|
||||||
const gamesystemFileNames = fs.readdirSync(gamesystemDir);
|
|
||||||
gamesystemFileNames.forEach(fileName => {
|
|
||||||
const gamesystemPath = path.join(gamesystemDir, fileName);
|
|
||||||
if (fs.lstatSync(gamesystemPath).isDirectory()) {
|
|
||||||
const childModels = SaveProject.loadGamesystemsRecursively(gamesystemPath);
|
|
||||||
loadedGamesystems = loadedGamesystems.concat(childModels);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const gamesystemData = fs.readFileSync(path.join(gamesystemDir, fileName), "utf-8");
|
|
||||||
if (path.parse(fileName).name === path.basename(gamesystemDir)) {
|
|
||||||
if ((path.basename(gamesystemDir) === path.parse(fileName).name) && path.basename(path.parse(gamesystemDir).dir) === "gamesystems") {
|
|
||||||
const loadedModel = new LoadModel_1.LoadModel(gamesystemData, ModelComponentType_1.ModelComponentType.GAMESYTEM);
|
|
||||||
loadedGamesystems.unshift(loadedModel);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const loadedModel = new RecursiveLoadModel_1.RecursiveLoadModel(gamesystemData, ModelComponentType_1.ModelComponentType.GAMESYTEM, path.basename(gamesystemDir));
|
|
||||||
loadedGamesystems.unshift(loadedModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const secondCon = path.basename(gamesystemDir) === path.parse(fileName).name;
|
|
||||||
const thirdCon = path.basename(path.parse(gamesystemDir).dir) === "gamesystems";
|
|
||||||
if (path.basename(gamesystemDir) === "gamesystems") {
|
|
||||||
const loadedModel = new LoadModel_1.LoadModel(gamesystemData, ModelComponentType_1.ModelComponentType.GAMESYTEM);
|
|
||||||
loadedGamesystems.push(loadedModel);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const loadedModel = new RecursiveLoadModel_1.RecursiveLoadModel(gamesystemData, ModelComponentType_1.ModelComponentType.GAMESYTEM, path.basename(gamesystemDir));
|
|
||||||
loadedGamesystems.push(loadedModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return loadedGamesystems;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.SaveProject = SaveProject;
|
|
||||||
//# sourceMappingURL=SaveProject.js.map
|
|
@ -1,110 +0,0 @@
|
|||||||
import {StorageModel} from "../src/app/game-model/fs/StorageModel";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import * as path from "node:path";
|
|
||||||
import {LoadModel} from "./LoadModel";
|
|
||||||
import {ModelComponentType} from "../src/app/game-model/ModelComponentType";
|
|
||||||
import {LoadedProject} from "./LoadedProject";
|
|
||||||
import {RecursiveLoadModel} from "./RecursiveLoadModel";
|
|
||||||
|
|
||||||
|
|
||||||
export class SaveProject {
|
|
||||||
static saveProject(projectDir: string, storageModels: StorageModel[]) {
|
|
||||||
if(!fs.existsSync(projectDir)) {
|
|
||||||
fs.mkdirSync(projectDir, {recursive: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(storageModels)
|
|
||||||
storageModels.forEach(storageModel => {
|
|
||||||
let modelDir = path.join(projectDir, storageModel.storageRootDir);
|
|
||||||
storageModel.storagePath.forEach(pathElement => modelDir = path.join(modelDir, pathElement));
|
|
||||||
if(!fs.existsSync(modelDir)) {
|
|
||||||
fs.mkdirSync(modelDir, {recursive: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
const filePath = path.join(modelDir, storageModel.fileName + ".json");
|
|
||||||
fs.writeFile(filePath, storageModel.jsonString ,'utf-8', (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error writing JSON to file:', err);
|
|
||||||
} else {
|
|
||||||
console.log('JSON file saved successfully:', filePath);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadProject(projectDir: string) {
|
|
||||||
let loadedScriptAccounts: LoadModel[] = SaveProject.loadScriptAccounts(projectDir)
|
|
||||||
loadedScriptAccounts = loadedScriptAccounts.concat(SaveProject.loadGamesystems(projectDir))
|
|
||||||
return new LoadedProject(path.basename(projectDir), loadedScriptAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadScriptAccounts(projectDir: string): LoadModel[] {
|
|
||||||
const scriptAccountDir = path.join(projectDir, "script-accounts");
|
|
||||||
if (!fs.existsSync(scriptAccountDir)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadedScriptAccounts: LoadModel[] = [];
|
|
||||||
|
|
||||||
const scriptAccountFileNames = fs.readdirSync(scriptAccountDir);
|
|
||||||
scriptAccountFileNames.forEach(scriptAccountFileName => {
|
|
||||||
const scriptAccountFile = path.join(scriptAccountDir, scriptAccountFileName)
|
|
||||||
const scriptAccountData: string = fs.readFileSync(scriptAccountFile, 'utf-8');
|
|
||||||
|
|
||||||
loadedScriptAccounts.push({
|
|
||||||
modelType: ModelComponentType.SCRIPTACCOUNT,
|
|
||||||
jsonString: scriptAccountData
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
return loadedScriptAccounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadGamesystems(projectDir: string): LoadModel[] {
|
|
||||||
const gamesystemDir = path.join(projectDir, "gamesystems");
|
|
||||||
const loadedGamesystems = this.loadGamesystemsRecursively(gamesystemDir);
|
|
||||||
console.log("LoadedGamesystems: ", loadedGamesystems.length);
|
|
||||||
return loadedGamesystems;
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadGamesystemsRecursively(gamesystemDir: string): LoadModel[] {
|
|
||||||
let loadedGamesystems: LoadModel[] = [];
|
|
||||||
const gamesystemFileNames = fs.readdirSync(gamesystemDir);
|
|
||||||
|
|
||||||
gamesystemFileNames.forEach(fileName => {
|
|
||||||
const gamesystemPath = path.join(gamesystemDir, fileName);
|
|
||||||
|
|
||||||
if(fs.lstatSync(gamesystemPath).isDirectory()) {
|
|
||||||
const childModels: LoadModel[] = SaveProject.loadGamesystemsRecursively(gamesystemPath);
|
|
||||||
loadedGamesystems = loadedGamesystems.concat(childModels);
|
|
||||||
} else {
|
|
||||||
const gamesystemData = fs.readFileSync(path.join(gamesystemDir, fileName), "utf-8");
|
|
||||||
if(path.parse(fileName).name === path.basename(gamesystemDir) ) {
|
|
||||||
if((path.basename(gamesystemDir) === path.parse(fileName).name) && path.basename(path.parse(gamesystemDir).dir) === "gamesystems") {
|
|
||||||
const loadedModel = new LoadModel(gamesystemData, ModelComponentType.GAMESYTEM);
|
|
||||||
loadedGamesystems.unshift(loadedModel)
|
|
||||||
} else {
|
|
||||||
const loadedModel = new RecursiveLoadModel(gamesystemData, ModelComponentType.GAMESYTEM, path.basename(gamesystemDir))
|
|
||||||
loadedGamesystems.unshift(loadedModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const secondCon = path.basename(gamesystemDir) === path.parse(fileName).name
|
|
||||||
const thirdCon = path.basename(path.parse(gamesystemDir).dir) === "gamesystems"
|
|
||||||
|
|
||||||
if(path.basename(gamesystemDir) === "gamesystems"){
|
|
||||||
const loadedModel = new LoadModel(gamesystemData, ModelComponentType.GAMESYTEM)
|
|
||||||
loadedGamesystems.push(loadedModel);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const loadedModel = new RecursiveLoadModel(gamesystemData, ModelComponentType.GAMESYTEM, path.basename(gamesystemDir))
|
|
||||||
loadedGamesystems.push(loadedModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return loadedGamesystems;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
class StorageModel {
|
|
||||||
jsonString: string
|
|
||||||
fileName: string
|
|
||||||
storageDir: string
|
|
||||||
|
|
||||||
|
|
||||||
constructor(jsonString: string, fileName: string, storageDir: string) {
|
|
||||||
this.jsonString = jsonString;
|
|
||||||
this.fileName = fileName;
|
|
||||||
this.storageDir = storageDir;
|
|
||||||
}
|
|
||||||
}
|
|
62
app/main.ts
62
app/main.ts
@ -1,9 +1,11 @@
|
|||||||
import {app, BrowserWindow, screen, Menu, ipcMain, dialog, globalShortcut} from 'electron';
|
import {app, BrowserWindow, dialog, globalShortcut, ipcMain, Menu, screen} from 'electron';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {json} from "node:stream/consumers";
|
import {GameModelLoader} from "./storage/loader/GameModelLoader";
|
||||||
import {StorageModel} from "../src/app/game-model/fs/StorageModel";
|
import {StoredGameModel} from "./storage/StoredGameModel";
|
||||||
import {SaveProject} from "./SaveProject";
|
import {ScriptAccountStorage} from "./storage/storing/ScriptAccountStoring";
|
||||||
|
import {ModelComponentFileDirectory} from "./storage/ModelComponentFileDirectory";
|
||||||
|
import {GamesystemStorage} from "./storage/storing/GamesystemStorage";
|
||||||
|
|
||||||
let win: BrowserWindow | null = null;
|
let win: BrowserWindow | null = null;
|
||||||
const args = process.argv.slice(1),
|
const args = process.argv.slice(1),
|
||||||
@ -94,11 +96,15 @@ function createWindow(): BrowserWindow {
|
|||||||
contextMenu.popup({ window: win!, x: params.x, y: params.y });
|
contextMenu.popup({ window: win!, x: params.x, y: params.y });
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('save-model', (event, storageModels: StorageModel[]) => {
|
ipcMain.on('save-model', (event, storedGameModel: StoredGameModel) => {
|
||||||
console.log("Save Model")
|
recieveGameModelToStore(storedGameModel)
|
||||||
SaveProject.saveProject(projectDirectory, storageModels);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/*ipcMain.on('delete-component', (event, deletedComponent: DeleteModel) => {
|
||||||
|
console.log("Delete Model: ", deletedComponent)
|
||||||
|
deleteComponent(deletedComponent);
|
||||||
|
})*/
|
||||||
|
|
||||||
const menuTemplate = [
|
const menuTemplate = [
|
||||||
{
|
{
|
||||||
label: 'File',
|
label: 'File',
|
||||||
@ -127,6 +133,10 @@ function createWindow(): BrowserWindow {
|
|||||||
const menu = Menu.buildFromTemplate(menuTemplate);
|
const menu = Menu.buildFromTemplate(menuTemplate);
|
||||||
Menu.setApplicationMenu(menu)
|
Menu.setApplicationMenu(menu)
|
||||||
|
|
||||||
|
win.webContents.on('did-finish-load', () => {
|
||||||
|
loadDevProjectAtStart()
|
||||||
|
})
|
||||||
|
|
||||||
return win;
|
return win;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +170,10 @@ try {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Catch Error
|
// Catch Error
|
||||||
// throw e;
|
// throw e;
|
||||||
@ -179,13 +193,39 @@ function openProject() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if(selectedPaths != undefined) {
|
if(selectedPaths != undefined) {
|
||||||
projectDirectory = selectedPaths[0];
|
openProjectFromFile(selectedPaths[0])
|
||||||
console.log("Open Project-Directory: ", projectDirectory)
|
|
||||||
const loadedProject = SaveProject.loadProject(projectDirectory)
|
|
||||||
win!.webContents.send("open-project", loadedProject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadDevProjectAtStart() {
|
||||||
|
const projectDir = path.join(process.cwd(), "testModel/")
|
||||||
|
openProjectFromFile(projectDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
function openProjectFromFile(openProjectDir: string) {
|
||||||
|
projectDirectory = openProjectDir
|
||||||
|
const gameModelLoader = new GameModelLoader(openProjectDir);
|
||||||
|
const loadedProject = gameModelLoader.loadGameModel();
|
||||||
|
win!.webContents.send("open-project", loadedProject)
|
||||||
|
}
|
||||||
|
|
||||||
function saveProject() {
|
function saveProject() {
|
||||||
win!.webContents.send('get-project-data')
|
win!.webContents.send('get-project-data')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recieveGameModelToStore(gameModel: StoredGameModel) {
|
||||||
|
const scriptAccountStorage = new ScriptAccountStorage(path.join(projectDirectory, ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME))
|
||||||
|
scriptAccountStorage.storeScriptAccounts(gameModel.storedScriptAccounts)
|
||||||
|
|
||||||
|
const gamesystemStorage = new GamesystemStorage(path.join(projectDirectory, ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME))
|
||||||
|
gamesystemStorage.storeGamesystems(gameModel.storedGamesystems)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*function deleteComponent(component: DeleteModel) {
|
||||||
|
console.log("Delete Component")
|
||||||
|
if(component.modeltype == ModelComponentType.SCRIPTACCOUNT) {
|
||||||
|
DeleteTransaction.deleteScriptAccount(projectDirectory, component.componentName);
|
||||||
|
} else if(component.modeltype === ModelComponentType.GAMESYTEM) {
|
||||||
|
DeleteTransaction.deleteGamesystem(projectDirectory, component.componentName);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
34
app/storage/FileUtils.js
Normal file
34
app/storage/FileUtils.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.FileUtils = void 0;
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("node:path");
|
||||||
|
const fs_1 = require("fs");
|
||||||
|
class FileUtils {
|
||||||
|
static listFilesInDirectory(directory) {
|
||||||
|
if (fs.lstatSync(directory).isDirectory()) {
|
||||||
|
return fs.readdirSync(directory).map(fileName => path.join(directory, fileName));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static prepareFileForWriting(file) {
|
||||||
|
const parentDirectory = path.dirname(file);
|
||||||
|
if (!fs.existsSync(parentDirectory)) {
|
||||||
|
(0, fs_1.mkdirSync)(parentDirectory, { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static removeFiles(files) {
|
||||||
|
files.forEach(file => {
|
||||||
|
if (fs.lstatSync(file).isDirectory()) {
|
||||||
|
fs.rmdirSync(file);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fs.unlinkSync(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FileUtils = FileUtils;
|
||||||
|
//# sourceMappingURL=FileUtils.js.map
|
33
app/storage/FileUtils.ts
Normal file
33
app/storage/FileUtils.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import * as path from "node:path";
|
||||||
|
import {mkdirSync} from "fs";
|
||||||
|
import {lstatSync} from "node:fs";
|
||||||
|
|
||||||
|
|
||||||
|
export class FileUtils {
|
||||||
|
public static listFilesInDirectory(directory: string) {
|
||||||
|
if(fs.lstatSync(directory).isDirectory()) {
|
||||||
|
return fs.readdirSync(directory).map(fileName => path.join(directory, fileName))
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static prepareFileForWriting(file: string) {
|
||||||
|
const parentDirectory = path.dirname(file)
|
||||||
|
|
||||||
|
if(!fs.existsSync(parentDirectory)) {
|
||||||
|
mkdirSync(parentDirectory, {recursive: true})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static removeFiles(files: string[]) {
|
||||||
|
files.forEach(file => {
|
||||||
|
if(fs.lstatSync(file).isDirectory()) {
|
||||||
|
fs.rmdirSync(file)
|
||||||
|
} else {
|
||||||
|
fs.unlinkSync(file);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
11
app/storage/ModelComponentFileDirectory.js
Normal file
11
app/storage/ModelComponentFileDirectory.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ModelComponentFileDirectory = void 0;
|
||||||
|
class ModelComponentFileDirectory {
|
||||||
|
}
|
||||||
|
exports.ModelComponentFileDirectory = ModelComponentFileDirectory;
|
||||||
|
ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME = "script-accounts";
|
||||||
|
ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME = "gamesystems";
|
||||||
|
ModelComponentFileDirectory.GAMESYSTEM_SIMPLE_DIR_NAME = "simple";
|
||||||
|
ModelComponentFileDirectory.GAMESYSTEM_PRODUCT_DIR_NAME = "product";
|
||||||
|
//# sourceMappingURL=ModelComponentFileDirectory.js.map
|
6
app/storage/ModelComponentFileDirectory.ts
Normal file
6
app/storage/ModelComponentFileDirectory.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export class ModelComponentFileDirectory {
|
||||||
|
public static SCRIPTACCOUNT_DIR_NAME = "script-accounts"
|
||||||
|
public static GAMESYSTEM_DIR_NAME = "gamesystems";
|
||||||
|
public static GAMESYSTEM_SIMPLE_DIR_NAME = "simple";
|
||||||
|
public static GAMESYSTEM_PRODUCT_DIR_NAME = "product";
|
||||||
|
}
|
12
app/storage/StoreComponent.js
Normal file
12
app/storage/StoreComponent.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.StoreComponent = void 0;
|
||||||
|
class StoreComponent {
|
||||||
|
constructor(jsonString, fileName, componentType) {
|
||||||
|
this.jsonString = jsonString;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.componentType = componentType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.StoreComponent = StoreComponent;
|
||||||
|
//# sourceMappingURL=StoreComponent.js.map
|
13
app/storage/StoreComponent.ts
Normal file
13
app/storage/StoreComponent.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import {ModelComponentType} from "../../src/app/project/game-model/ModelComponentType";
|
||||||
|
|
||||||
|
|
||||||
|
export class StoreComponent {
|
||||||
|
jsonString: string
|
||||||
|
fileName: string
|
||||||
|
componentType: ModelComponentType
|
||||||
|
constructor(jsonString: string, fileName: string, componentType: ModelComponentType) {
|
||||||
|
this.jsonString = jsonString;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.componentType = componentType
|
||||||
|
}
|
||||||
|
}
|
12
app/storage/StoredGameModel.js
Normal file
12
app/storage/StoredGameModel.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.StoredGameModel = void 0;
|
||||||
|
class StoredGameModel {
|
||||||
|
constructor(gameModelName, storedScriptAccounts, storedGamesystems) {
|
||||||
|
this.gameModelName = gameModelName;
|
||||||
|
this.storedGamesystems = storedGamesystems;
|
||||||
|
this.storedScriptAccounts = storedScriptAccounts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.StoredGameModel = StoredGameModel;
|
||||||
|
//# sourceMappingURL=StoredGameModel.js.map
|
15
app/storage/StoredGameModel.ts
Normal file
15
app/storage/StoredGameModel.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import {StoreComponent} from "./StoreComponent";
|
||||||
|
|
||||||
|
export class StoredGameModel {
|
||||||
|
gameModelName: string
|
||||||
|
|
||||||
|
storedGamesystems: StoreComponent[]
|
||||||
|
storedScriptAccounts: StoreComponent[]
|
||||||
|
|
||||||
|
|
||||||
|
constructor(gameModelName: string, storedScriptAccounts: StoreComponent[], storedGamesystems: StoreComponent[]) {
|
||||||
|
this.gameModelName = gameModelName;
|
||||||
|
this.storedGamesystems = storedGamesystems;
|
||||||
|
this.storedScriptAccounts = storedScriptAccounts;
|
||||||
|
}
|
||||||
|
}
|
31
app/storage/loader/GameModelLoader.js
Normal file
31
app/storage/loader/GameModelLoader.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.GameModelLoader = void 0;
|
||||||
|
const StoredGameModel_1 = require("../StoredGameModel");
|
||||||
|
const path = require("node:path");
|
||||||
|
const ModelComponentFileDirectory_1 = require("../ModelComponentFileDirectory");
|
||||||
|
const ScriptAccountLoader_1 = require("./ScriptAccountLoader");
|
||||||
|
const GamesystemLoader_1 = require("./GamesystemLoader");
|
||||||
|
class GameModelLoader {
|
||||||
|
constructor(gameModelDir) {
|
||||||
|
this.gameModelDir = gameModelDir;
|
||||||
|
}
|
||||||
|
loadGameModel() {
|
||||||
|
const gameModelName = path.basename(this.gameModelDir);
|
||||||
|
const storedScriptAccounts = this.loadScriptAccountComponents();
|
||||||
|
const storedGamesystems = this.loadGamesystems();
|
||||||
|
return new StoredGameModel_1.StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems);
|
||||||
|
}
|
||||||
|
loadScriptAccountComponents() {
|
||||||
|
const scriptAccountDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME);
|
||||||
|
const scriptAccountLoader = new ScriptAccountLoader_1.ScriptAccountLoader(scriptAccountDir);
|
||||||
|
return scriptAccountLoader.loadScriptAccounts();
|
||||||
|
}
|
||||||
|
loadGamesystems() {
|
||||||
|
const gamesystemDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME);
|
||||||
|
const gamesystemLoader = new GamesystemLoader_1.GamesystemLoader(gamesystemDir);
|
||||||
|
return gamesystemLoader.loadGamesystems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.GameModelLoader = GameModelLoader;
|
||||||
|
//# sourceMappingURL=GameModelLoader.js.map
|
42
app/storage/loader/GameModelLoader.ts
Normal file
42
app/storage/loader/GameModelLoader.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import {StoredGameModel} from "../StoredGameModel";
|
||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
import * as path from "node:path";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {ModelComponentFileDirectory} from "../ModelComponentFileDirectory";
|
||||||
|
import {ScriptAccountLoader} from "./ScriptAccountLoader";
|
||||||
|
import {GamesystemLoader} from "./GamesystemLoader";
|
||||||
|
|
||||||
|
export class GameModelLoader {
|
||||||
|
gameModelDir: string
|
||||||
|
|
||||||
|
|
||||||
|
constructor(gameModelDir: string) {
|
||||||
|
this.gameModelDir = gameModelDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadGameModel(): StoredGameModel {
|
||||||
|
const gameModelName = path.basename(this.gameModelDir)
|
||||||
|
|
||||||
|
const storedScriptAccounts = this.loadScriptAccountComponents();
|
||||||
|
const storedGamesystems = this.loadGamesystems();
|
||||||
|
|
||||||
|
return new StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems);
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadScriptAccountComponents() {
|
||||||
|
const scriptAccountDir = path.join(this.gameModelDir, ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME);
|
||||||
|
const scriptAccountLoader = new ScriptAccountLoader(scriptAccountDir);
|
||||||
|
return scriptAccountLoader.loadScriptAccounts()
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadGamesystems(): StoreComponent[] {
|
||||||
|
const gamesystemDir = path.join(this.gameModelDir, ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME);
|
||||||
|
const gamesystemLoader = new GamesystemLoader(gamesystemDir);
|
||||||
|
return gamesystemLoader.loadGamesystems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
41
app/storage/loader/GamesystemLoader.js
Normal file
41
app/storage/loader/GamesystemLoader.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.GamesystemLoader = void 0;
|
||||||
|
const StoreComponent_1 = require("../StoreComponent");
|
||||||
|
const FileUtils_1 = require("../FileUtils");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("node:path");
|
||||||
|
const ModelComponentType_1 = require("../../../src/app/project/game-model/ModelComponentType");
|
||||||
|
class GamesystemLoader {
|
||||||
|
constructor(gamesystemDir) {
|
||||||
|
this.gamesystemDir = gamesystemDir;
|
||||||
|
}
|
||||||
|
loadGamesystems() {
|
||||||
|
return this.loadGamesystemsRecursivly(this.gamesystemDir);
|
||||||
|
}
|
||||||
|
loadGamesystemsRecursivly(currentGamesystemDir) {
|
||||||
|
let loadedGamesystems = [];
|
||||||
|
const gamesystemFiles = FileUtils_1.FileUtils.listFilesInDirectory(currentGamesystemDir);
|
||||||
|
gamesystemFiles.forEach(gamesystemFile => {
|
||||||
|
if (fs.lstatSync(gamesystemFile).isDirectory()) {
|
||||||
|
const childGamesystems = this.loadGamesystemsRecursivly(gamesystemFile);
|
||||||
|
loadedGamesystems = loadedGamesystems.concat(childGamesystems);
|
||||||
|
}
|
||||||
|
else if (path.basename(gamesystemFile).endsWith(".json")) {
|
||||||
|
const loadedGamesystem = this.loadGamesystem(gamesystemFile);
|
||||||
|
if (loadedGamesystem != undefined) {
|
||||||
|
loadedGamesystems.push(loadedGamesystem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return loadedGamesystems;
|
||||||
|
}
|
||||||
|
loadGamesystem(gamesystemFile) {
|
||||||
|
if (gamesystemFile.endsWith(".json")) {
|
||||||
|
const gamesystemData = fs.readFileSync(gamesystemFile, 'utf-8');
|
||||||
|
return new StoreComponent_1.StoreComponent(gamesystemData, gamesystemFile, ModelComponentType_1.ModelComponentType.GAMESYTEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.GamesystemLoader = GamesystemLoader;
|
||||||
|
//# sourceMappingURL=GamesystemLoader.js.map
|
44
app/storage/loader/GamesystemLoader.ts
Normal file
44
app/storage/loader/GamesystemLoader.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
import {FileUtils} from "../FileUtils";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import * as path from "node:path";
|
||||||
|
import {ModelComponentType} from "../../../src/app/project/game-model/ModelComponentType";
|
||||||
|
|
||||||
|
export class GamesystemLoader {
|
||||||
|
|
||||||
|
gamesystemDir: string
|
||||||
|
|
||||||
|
|
||||||
|
constructor(gamesystemDir: string) {
|
||||||
|
this.gamesystemDir = gamesystemDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadGamesystems() {
|
||||||
|
return this.loadGamesystemsRecursivly(this.gamesystemDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadGamesystemsRecursivly(currentGamesystemDir: string) {
|
||||||
|
let loadedGamesystems: StoreComponent[] = []
|
||||||
|
const gamesystemFiles = FileUtils.listFilesInDirectory(currentGamesystemDir);
|
||||||
|
gamesystemFiles.forEach(gamesystemFile => {
|
||||||
|
if(fs.lstatSync(gamesystemFile).isDirectory()) {
|
||||||
|
const childGamesystems = this.loadGamesystemsRecursivly(gamesystemFile);
|
||||||
|
loadedGamesystems = loadedGamesystems.concat(childGamesystems);
|
||||||
|
} else if(path.basename(gamesystemFile).endsWith(".json")) {
|
||||||
|
const loadedGamesystem = this.loadGamesystem(gamesystemFile);
|
||||||
|
if(loadedGamesystem != undefined) {
|
||||||
|
loadedGamesystems.push(loadedGamesystem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return loadedGamesystems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadGamesystem(gamesystemFile: string) {
|
||||||
|
if(gamesystemFile.endsWith(".json")) {
|
||||||
|
const gamesystemData = fs.readFileSync(gamesystemFile, 'utf-8');
|
||||||
|
return new StoreComponent(gamesystemData, gamesystemFile, ModelComponentType.GAMESYTEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
app/storage/loader/ScriptAccountLoader.js
Normal file
31
app/storage/loader/ScriptAccountLoader.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ScriptAccountLoader = void 0;
|
||||||
|
const StoreComponent_1 = require("../StoreComponent");
|
||||||
|
const FileUtils_1 = require("../FileUtils");
|
||||||
|
const ModelComponentType_1 = require("../../../src/app/project/game-model/ModelComponentType");
|
||||||
|
const fs = require("fs");
|
||||||
|
class ScriptAccountLoader {
|
||||||
|
constructor(scriptAccountDir) {
|
||||||
|
this.scriptAccountDir = scriptAccountDir;
|
||||||
|
}
|
||||||
|
loadScriptAccounts() {
|
||||||
|
const scriptAccountFiles = FileUtils_1.FileUtils.listFilesInDirectory(this.scriptAccountDir);
|
||||||
|
const loadedScriptAccounts = [];
|
||||||
|
scriptAccountFiles.forEach(scriptAccountFile => {
|
||||||
|
const loadedScriptAccount = this.loadScriptAccount(scriptAccountFile);
|
||||||
|
if (loadedScriptAccount != undefined) {
|
||||||
|
loadedScriptAccounts.push(loadedScriptAccount);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return loadedScriptAccounts;
|
||||||
|
}
|
||||||
|
loadScriptAccount(scriptAccountFile) {
|
||||||
|
if (scriptAccountFile.endsWith(".json")) {
|
||||||
|
const scriptAccountData = fs.readFileSync(scriptAccountFile, 'utf-8');
|
||||||
|
return new StoreComponent_1.StoreComponent(scriptAccountData, scriptAccountFile, ModelComponentType_1.ModelComponentType.SCRIPTACCOUNT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ScriptAccountLoader = ScriptAccountLoader;
|
||||||
|
//# sourceMappingURL=ScriptAccountLoader.js.map
|
34
app/storage/loader/ScriptAccountLoader.ts
Normal file
34
app/storage/loader/ScriptAccountLoader.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
import {FileUtils} from "../FileUtils";
|
||||||
|
import {ModelComponentType} from "../../../src/app/project/game-model/ModelComponentType";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {ModelComponentFileDirectory} from "../ModelComponentFileDirectory";
|
||||||
|
import {load} from "@angular-devkit/build-angular/src/utils/server-rendering/esm-in-memory-loader/loader-hooks";
|
||||||
|
|
||||||
|
export class ScriptAccountLoader {
|
||||||
|
scriptAccountDir: string
|
||||||
|
|
||||||
|
|
||||||
|
constructor(scriptAccountDir: string) {
|
||||||
|
this.scriptAccountDir = scriptAccountDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadScriptAccounts(): StoreComponent[] {
|
||||||
|
const scriptAccountFiles = FileUtils.listFilesInDirectory(this.scriptAccountDir);
|
||||||
|
const loadedScriptAccounts: StoreComponent[] = []
|
||||||
|
scriptAccountFiles.forEach(scriptAccountFile => {
|
||||||
|
const loadedScriptAccount = this.loadScriptAccount(scriptAccountFile);
|
||||||
|
if(loadedScriptAccount != undefined) {
|
||||||
|
loadedScriptAccounts.push(loadedScriptAccount)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return loadedScriptAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadScriptAccount(scriptAccountFile: string) {
|
||||||
|
if(scriptAccountFile.endsWith(".json")) {
|
||||||
|
const scriptAccountData = fs.readFileSync(scriptAccountFile, 'utf-8');
|
||||||
|
return new StoreComponent(scriptAccountData, scriptAccountFile, ModelComponentType.SCRIPTACCOUNT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
app/storage/storing/GamesystemStorage.js
Normal file
57
app/storage/storing/GamesystemStorage.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.GamesystemStorage = void 0;
|
||||||
|
const FileUtils_1 = require("../FileUtils");
|
||||||
|
const path = require("node:path");
|
||||||
|
const fs = require("fs");
|
||||||
|
class GamesystemStorage {
|
||||||
|
constructor(gamesystemRootDir) {
|
||||||
|
this.gamesystemRootDir = gamesystemRootDir;
|
||||||
|
}
|
||||||
|
storeGamesystems(gamesystems) {
|
||||||
|
const unreferencedFiles = this.detectUnusedGamesystemFiles(gamesystems);
|
||||||
|
FileUtils_1.FileUtils.removeFiles(unreferencedFiles);
|
||||||
|
gamesystems.forEach(gamesystem => this.storeGamesystem(gamesystem));
|
||||||
|
}
|
||||||
|
detectUnusedGamesystemFiles(gamesystems) {
|
||||||
|
const unreferencedFiles = [];
|
||||||
|
const gamesystemFiles = FileUtils_1.FileUtils.listFilesInDirectory(this.gamesystemRootDir);
|
||||||
|
while (gamesystemFiles.length > 0) {
|
||||||
|
const currentGamesystemFile = gamesystemFiles.shift();
|
||||||
|
const referencedGamesystemName = path.parse(path.basename(currentGamesystemFile)).name;
|
||||||
|
const referencedGamesystem = this.findReferencedGamesystem(referencedGamesystemName, gamesystems);
|
||||||
|
if (referencedGamesystem == undefined) {
|
||||||
|
unreferencedFiles.push(currentGamesystemFile);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const decodedJSONData = JSON.parse(referencedGamesystem.jsonString);
|
||||||
|
if (decodedJSONData.childsystems != undefined) {
|
||||||
|
//Check if current file is a directory. When it is a directory, everything is fine
|
||||||
|
if (fs.lstatSync(currentGamesystemFile).isDirectory()) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const parentDirName = path.basename(path.dirname(currentGamesystemFile));
|
||||||
|
if (parentDirName !== referencedGamesystemName) {
|
||||||
|
unreferencedFiles.push(currentGamesystemFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fs.lstatSync(currentGamesystemFile).isDirectory()) {
|
||||||
|
gamesystemFiles.push(...FileUtils_1.FileUtils.listFilesInDirectory(currentGamesystemFile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unreferencedFiles;
|
||||||
|
}
|
||||||
|
findReferencedGamesystem(referencedName, gamesystems) {
|
||||||
|
return gamesystems.find(gamesystem => path.basename(gamesystem.fileName) === referencedName);
|
||||||
|
}
|
||||||
|
storeGamesystem(gamesystem) {
|
||||||
|
const gamesystemFile = path.join(...gamesystem.fileName.split("/"));
|
||||||
|
const completeGamesystemFile = path.join(this.gamesystemRootDir, gamesystemFile);
|
||||||
|
FileUtils_1.FileUtils.prepareFileForWriting(completeGamesystemFile);
|
||||||
|
fs.writeFileSync(completeGamesystemFile + ".json", gamesystem.jsonString, 'utf-8');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.GamesystemStorage = GamesystemStorage;
|
||||||
|
//# sourceMappingURL=GamesystemStorage.js.map
|
64
app/storage/storing/GamesystemStorage.ts
Normal file
64
app/storage/storing/GamesystemStorage.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
import {FileUtils} from "../FileUtils";
|
||||||
|
import * as path from "node:path";
|
||||||
|
import * as fs from "fs";
|
||||||
|
|
||||||
|
export class GamesystemStorage {
|
||||||
|
|
||||||
|
private gamesystemRootDir: string
|
||||||
|
|
||||||
|
|
||||||
|
constructor(gamesystemRootDir: string) {
|
||||||
|
this.gamesystemRootDir = gamesystemRootDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public storeGamesystems(gamesystems: StoreComponent[]) {
|
||||||
|
const unreferencedFiles = this.detectUnusedGamesystemFiles(gamesystems)
|
||||||
|
FileUtils.removeFiles(unreferencedFiles)
|
||||||
|
gamesystems.forEach(gamesystem => this.storeGamesystem(gamesystem))
|
||||||
|
}
|
||||||
|
|
||||||
|
private detectUnusedGamesystemFiles(gamesystems: StoreComponent[]) {
|
||||||
|
const unreferencedFiles: string[] = []
|
||||||
|
const gamesystemFiles = FileUtils.listFilesInDirectory(this.gamesystemRootDir);
|
||||||
|
while(gamesystemFiles.length > 0) {
|
||||||
|
const currentGamesystemFile = gamesystemFiles.shift()
|
||||||
|
const referencedGamesystemName = path.parse(path.basename(currentGamesystemFile!)).name
|
||||||
|
const referencedGamesystem = this.findReferencedGamesystem(referencedGamesystemName, gamesystems)
|
||||||
|
if(referencedGamesystem == undefined) {
|
||||||
|
unreferencedFiles.push(currentGamesystemFile!)
|
||||||
|
} else {
|
||||||
|
const decodedJSONData = JSON.parse(referencedGamesystem!.jsonString)
|
||||||
|
if(decodedJSONData.childsystems != undefined) {
|
||||||
|
//Check if current file is a directory. When it is a directory, everything is fine
|
||||||
|
if(fs.lstatSync(currentGamesystemFile!).isDirectory()) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const parentDirName = path.basename(path.dirname(currentGamesystemFile!))
|
||||||
|
if(parentDirName !== referencedGamesystemName) {
|
||||||
|
unreferencedFiles.push(currentGamesystemFile!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fs.lstatSync(currentGamesystemFile!).isDirectory()) {
|
||||||
|
gamesystemFiles.push(... FileUtils.listFilesInDirectory(currentGamesystemFile!))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unreferencedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
private findReferencedGamesystem(referencedName: string, gamesystems: StoreComponent[]): StoreComponent | undefined {
|
||||||
|
return gamesystems.find(gamesystem =>
|
||||||
|
path.basename(gamesystem.fileName) === referencedName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private storeGamesystem(gamesystem: StoreComponent) {
|
||||||
|
const gamesystemFile = path.join(... gamesystem.fileName.split("/"))
|
||||||
|
const completeGamesystemFile = path.join(this.gamesystemRootDir, gamesystemFile)
|
||||||
|
FileUtils.prepareFileForWriting(completeGamesystemFile)
|
||||||
|
fs.writeFileSync(completeGamesystemFile + ".json", gamesystem.jsonString, 'utf-8')
|
||||||
|
}
|
||||||
|
}
|
33
app/storage/storing/ScriptAccountStoring.js
Normal file
33
app/storage/storing/ScriptAccountStoring.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ScriptAccountStorage = void 0;
|
||||||
|
const FileUtils_1 = require("../FileUtils");
|
||||||
|
const path = require("node:path");
|
||||||
|
const fs = require("fs");
|
||||||
|
class ScriptAccountStorage {
|
||||||
|
constructor(scriptAccountDir) {
|
||||||
|
this.scriptAccountDir = scriptAccountDir;
|
||||||
|
}
|
||||||
|
storeScriptAccounts(scriptAccounts) {
|
||||||
|
this.persistDeletedScriptAccounts(scriptAccounts);
|
||||||
|
scriptAccounts.forEach(scriptAccount => {
|
||||||
|
this.storeScriptAccount(scriptAccount);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
persistDeletedScriptAccounts(existingScriptAccount) {
|
||||||
|
const scriptAccountFiles = FileUtils_1.FileUtils.listFilesInDirectory(this.scriptAccountDir);
|
||||||
|
scriptAccountFiles.forEach(scriptAccountFile => {
|
||||||
|
const scriptAccountFileName = path.parse(path.basename(scriptAccountFile)).name;
|
||||||
|
if (existingScriptAccount.find(scriptAccount => scriptAccount.fileName === scriptAccountFileName) == undefined) {
|
||||||
|
//No scriptAccountFile was found with that nae of the file. So the scriptAccount was deleted. Remove file
|
||||||
|
fs.unlinkSync(scriptAccountFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
storeScriptAccount(scriptAccount) {
|
||||||
|
const completeScriptAccountFile = path.join(this.scriptAccountDir, scriptAccount.fileName + ".json");
|
||||||
|
fs.writeFileSync(completeScriptAccountFile, scriptAccount.jsonString, 'utf-8');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ScriptAccountStorage = ScriptAccountStorage;
|
||||||
|
//# sourceMappingURL=ScriptAccountStoring.js.map
|
36
app/storage/storing/ScriptAccountStoring.ts
Normal file
36
app/storage/storing/ScriptAccountStoring.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
import {FileUtils} from "../FileUtils";
|
||||||
|
import * as path from "node:path";
|
||||||
|
import * as fs from "fs";
|
||||||
|
|
||||||
|
export class ScriptAccountStorage {
|
||||||
|
|
||||||
|
private scriptAccountDir: string
|
||||||
|
|
||||||
|
constructor(scriptAccountDir: string) {
|
||||||
|
this.scriptAccountDir = scriptAccountDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
storeScriptAccounts(scriptAccounts: StoreComponent[]) {
|
||||||
|
this.persistDeletedScriptAccounts(scriptAccounts)
|
||||||
|
scriptAccounts.forEach(scriptAccount => {
|
||||||
|
this.storeScriptAccount(scriptAccount)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private persistDeletedScriptAccounts(existingScriptAccount: StoreComponent[]) {
|
||||||
|
const scriptAccountFiles = FileUtils.listFilesInDirectory(this.scriptAccountDir);
|
||||||
|
scriptAccountFiles.forEach(scriptAccountFile => {
|
||||||
|
const scriptAccountFileName = path.parse(path.basename(scriptAccountFile)).name
|
||||||
|
if(existingScriptAccount.find(scriptAccount => scriptAccount.fileName === scriptAccountFileName) == undefined) {
|
||||||
|
//No scriptAccountFile was found with that nae of the file. So the scriptAccount was deleted. Remove file
|
||||||
|
fs.unlinkSync(scriptAccountFile)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private storeScriptAccount(scriptAccount: StoreComponent) {
|
||||||
|
const completeScriptAccountFile = path.join(this.scriptAccountDir, scriptAccount.fileName + ".json")
|
||||||
|
fs.writeFileSync(completeScriptAccountFile, scriptAccount.jsonString, 'utf-8')
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import * as PATH from 'path';
|
import * as PATH from 'path';
|
||||||
import {GameModel} from "../../src/app/game-model/GameModel";
|
import {GameModel} from "../../src/app/project/game-model/GameModel";
|
||||||
import {Gamesystem} from "../../src/app/game-model/gamesystems/Gamesystem";
|
import {Gamesystem} from "../../src/app/project/game-model/gamesystems/Gamesystem";
|
||||||
|
|
||||||
test.describe('Adding Gamesystems', () => {
|
test.describe('Adding Gamesystems', () => {
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import * as PATH from 'path';
|
import * as PATH from 'path';
|
||||||
import {GameModel} from "../../src/app/game-model/GameModel";
|
|
||||||
import {Gamesystem} from "../../src/app/game-model/gamesystems/Gamesystem";
|
import {Gamesystem} from "../../src/app/project/game-model/gamesystems/Gamesystem";
|
||||||
|
import {GameModel} from "../../src/app/project/game-model/GameModel";
|
||||||
|
|
||||||
test.describe('Removing Gamesystems', () => {
|
test.describe('Removing Gamesystems', () => {
|
||||||
|
|
||||||
|
@ -1,15 +1,6 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
|
||||||
import { test, expect } from '@playwright/test';
|
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 {GamesystemTrainer} from "./GamesystemTrainer";
|
||||||
import {ProductGamesystem} from "../../../src/app/game-model/gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "../../../src/app/project/game-model/gamesystems/ProductGamesystem";
|
||||||
test.describe('Test Create Gamesystems', () => {
|
test.describe('Test Create Gamesystems', () => {
|
||||||
|
|
||||||
test('Test creating gamesystem with invalid name', async => {
|
test('Test creating gamesystem with invalid name', async => {
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import * as PATH from 'path';
|
import {GameModel} from "../../../src/app/project/game-model/GameModel";
|
||||||
import {GameModel} from "../../../src/app/game-model/GameModel";
|
import {SimpleGamesystem} from "../../../src/app/project/game-model/gamesystems/SimpleGamesystem";
|
||||||
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 {GamesystemTrainer} from "./GamesystemTrainer";
|
||||||
test.describe('Test Find Gamesystems', () => {
|
test.describe('Test Find Gamesystems', () => {
|
||||||
const GAMEMODELNAME: string = "GameModel";
|
const GAMEMODELNAME: string = "GameModel";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {GameModel} from "../../../src/app/game-model/GameModel";
|
import {GameModel} from "../../../src/app/project/game-model/GameModel";
|
||||||
import {SimpleGamesystem} from "../../../src/app/game-model/gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "../../../src/app/project/game-model/gamesystems/SimpleGamesystem";
|
||||||
import {ProductGamesystem} from "../../../src/app/game-model/gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "../../../src/app/project/game-model/gamesystems/ProductGamesystem";
|
||||||
|
|
||||||
export class GamesystemTrainer {
|
export class GamesystemTrainer {
|
||||||
|
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import * as PATH from 'path';
|
import {SimpleGamesystem} from "../../../src/app/project/game-model/gamesystems/SimpleGamesystem";
|
||||||
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.describe('Test SimpleGamesystem', () => {
|
||||||
|
|
||||||
|
59
e2e/game-model/gamesystems/actions/AddActions.spec.ts
Normal file
59
e2e/game-model/gamesystems/actions/AddActions.spec.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import {GamesystemTrainer} from "../GamesystemTrainer";
|
||||||
|
import {SimpleActionTrainer} from "./SimpleActionTrainer";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import {ScriptAccountAction} from "../../../../src/app/project/game-model/gamesystems/actions/ScriptAccountAction";
|
||||||
|
test.describe('Test Create SimpleActions', () => {
|
||||||
|
|
||||||
|
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("Adding invalid actions", async () => {
|
||||||
|
const transition = SimpleActionTrainer.withEmptyActions();
|
||||||
|
|
||||||
|
transition.addScriptAccountAction(null);
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(0);
|
||||||
|
|
||||||
|
transition.addScriptAccountAction(undefined);
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(0);
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Adding not existing action", async () => {
|
||||||
|
const transition = SimpleActionTrainer.withEmptyActions();
|
||||||
|
const scriptAccount = new ScriptAccount("test", "");
|
||||||
|
|
||||||
|
const action = new ScriptAccountAction(scriptAccount, 10);
|
||||||
|
transition.addScriptAccountAction(action);
|
||||||
|
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(1);
|
||||||
|
expect(transition.scriptAccountActions[0].scriptAccount).toEqual(action.scriptAccount);
|
||||||
|
expect(transition.scriptAccountActions[0].changingValue).toEqual(10);
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Adding existing action", async () => {
|
||||||
|
const transition = SimpleActionTrainer.withSingleAction();
|
||||||
|
const action = transition.scriptAccountActions[0];
|
||||||
|
|
||||||
|
transition.addScriptAccountAction(action);
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(1);
|
||||||
|
expect(transition.scriptAccountActions[0].changingValue).toEqual(20);
|
||||||
|
expect(transition.scriptAccountActions[0].scriptAccount).toEqual(action.scriptAccount);
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Adding not existing action into non empty actions", async () => {
|
||||||
|
const transition = SimpleActionTrainer.withSingleAction();
|
||||||
|
|
||||||
|
const scriptAccount = new ScriptAccount("Tes", "");
|
||||||
|
|
||||||
|
transition.addScriptAccountAction(new ScriptAccountAction(scriptAccount, 10));
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(2);
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
33
e2e/game-model/gamesystems/actions/RemoveActions.spec.ts
Normal file
33
e2e/game-model/gamesystems/actions/RemoveActions.spec.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import {GamesystemTrainer} from "../GamesystemTrainer";
|
||||||
|
import {SimpleActionTrainer} from "./SimpleActionTrainer";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import {ScriptAccountAction} from "../../../../src/app/project/game-model/gamesystems/actions/ScriptAccountAction";
|
||||||
|
import {SimpleTransition} from "../../../../src/app/project/game-model/gamesystems/transitions/SimpleTransition";
|
||||||
|
test.describe('Test Remove SimpleActions', () => {
|
||||||
|
|
||||||
|
test("Test Removing invalid Actions", async () => {
|
||||||
|
const transition = SimpleActionTrainer.withSingleAction();
|
||||||
|
|
||||||
|
transition.removeScriptAccountAction(null);
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(1)
|
||||||
|
|
||||||
|
transition.removeScriptAccountAction(undefined);
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(1);
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test removing unknown scriptAccount Action", async () => {
|
||||||
|
const transition = SimpleActionTrainer.withSingleAction();
|
||||||
|
const scriptAccount = new ScriptAccount("Test");
|
||||||
|
|
||||||
|
transition.removeScriptAccountAction(scriptAccount);
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(1);
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test removing known ScriptAccount", async () => {
|
||||||
|
const transition = SimpleActionTrainer.withSingleAction();
|
||||||
|
transition.removeScriptAccountAction(transition.scriptAccountActions[0].scriptAccount)
|
||||||
|
expect(transition.scriptAccountActions.length).toEqual(0);
|
||||||
|
})
|
||||||
|
});
|
25
e2e/game-model/gamesystems/actions/SimpleActionTrainer.ts
Normal file
25
e2e/game-model/gamesystems/actions/SimpleActionTrainer.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import {SimpleState} from "../../../../src/app/project/game-model/gamesystems/states/SimpleState";
|
||||||
|
import {SimpleTransition} from "../../../../src/app/project/game-model/gamesystems/transitions/SimpleTransition";
|
||||||
|
import {Script} from "node:vm";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import {ScriptAccountAction} from "../../../../src/app/project/game-model/gamesystems/actions/ScriptAccountAction";
|
||||||
|
|
||||||
|
export class SimpleActionTrainer {
|
||||||
|
static withEmptyActions() {
|
||||||
|
const startingState = new SimpleState("Wolkig", "");
|
||||||
|
const endingState = new SimpleState("Schnee", "");
|
||||||
|
|
||||||
|
return new SimpleTransition(startingState, endingState);
|
||||||
|
}
|
||||||
|
|
||||||
|
static withSingleAction() {
|
||||||
|
const startingState = new SimpleState("Wolkig", "");
|
||||||
|
const endingState = new SimpleState("Schnee", "");
|
||||||
|
|
||||||
|
const scriptAccount = new ScriptAccount("Temperature", "");
|
||||||
|
const transition = new SimpleTransition(startingState, endingState);
|
||||||
|
transition.scriptAccountActions.push(new ScriptAccountAction(scriptAccount, 10));
|
||||||
|
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import {ScriptAccountCondition} from "../../../../src/app/project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import exp = require("node:constants");
|
||||||
|
import {ConditionTrainer} from "./ConditionTrainer";
|
||||||
|
import {Conditional} from "@angular/compiler";
|
||||||
|
import {TransitionConditionTrainer} from "./TransitionConditionTrainer";
|
||||||
|
import {transition} from "@angular/animations";
|
||||||
|
test.describe('Test Adding Conditions To Transitions', () => {
|
||||||
|
|
||||||
|
test("Test adding not contradicting Conditions", async () => {
|
||||||
|
const transition = TransitionConditionTrainer.withTransitionWithCondition();
|
||||||
|
const condition = ScriptAccountCondition.constructScriptAccountCondition(new ScriptAccount("Test", ""), -200, -100);
|
||||||
|
|
||||||
|
transition.addScriptAccountCondition(condition);
|
||||||
|
expect(transition.scriptAccountConditions.length).toEqual(2);
|
||||||
|
expect(transition.scriptAccountConditions.includes(condition)).toBeTruthy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test adding contradicting Conditions", async () => {
|
||||||
|
const transition = TransitionConditionTrainer.withTransitionWithCondition();
|
||||||
|
const condition = ConditionTrainer.withContradictingCondition(transition.scriptAccountConditions[0]);
|
||||||
|
|
||||||
|
transition.addScriptAccountCondition(condition)
|
||||||
|
expect(transition.scriptAccountConditions.length).toEqual(1);
|
||||||
|
expect(transition.scriptAccountConditions.includes(condition)).toBeFalsy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test expanding Conditions", async () => {
|
||||||
|
const transition = TransitionConditionTrainer.withTransitionWithCondition();
|
||||||
|
const condition = ConditionTrainer.withExpendingCondition(transition.scriptAccountConditions[0]);
|
||||||
|
|
||||||
|
transition.addScriptAccountCondition(condition);
|
||||||
|
expect(transition.scriptAccountConditions.length).toEqual(1);
|
||||||
|
expect(transition.scriptAccountConditions.includes(condition)).toBeFalsy();
|
||||||
|
expect(transition.scriptAccountConditions[0].minValue).toEqual(-10)
|
||||||
|
expect(transition.scriptAccountConditions[0].maxValue).toEqual(20)
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import {ScriptAccountCondition} from "../../../../src/app/project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import exp = require("node:constants");
|
||||||
|
import {ConditionTrainer} from "./ConditionTrainer";
|
||||||
|
import {Conditional} from "@angular/compiler";
|
||||||
|
test.describe('Test Contradicting Conditions', () => {
|
||||||
|
|
||||||
|
test("Test contradicting conditions", async () => {
|
||||||
|
const condition = ConditionTrainer.withSimpleCondition();
|
||||||
|
|
||||||
|
let contradictingCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.maxValue + 10, condition.maxValue+200);
|
||||||
|
expect(condition.isContradicting(contradictingCondition)).toBeTruthy();
|
||||||
|
|
||||||
|
contradictingCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue-100, condition.minValue-50);
|
||||||
|
expect(condition.isContradicting(contradictingCondition)).toBeTruthy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test intersecting conditions", async () => {
|
||||||
|
const condition = ConditionTrainer.withSimpleCondition();
|
||||||
|
let otherCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue-1, condition.minValue+1);
|
||||||
|
expect(condition.isContradicting(otherCondition)).toBeFalsy();
|
||||||
|
|
||||||
|
otherCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.maxValue-1, condition.maxValue+1);
|
||||||
|
expect(condition.isContradicting(otherCondition)).toBeFalsy();
|
||||||
|
|
||||||
|
otherCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue-1, condition.maxValue+1);
|
||||||
|
expect(condition.isContradicting(otherCondition)).toBeFalsy();
|
||||||
|
|
||||||
|
expect(condition.isContradicting(condition)).toBeFalsy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test contradicting conditions with different ScriptAccount", async () => {
|
||||||
|
const condition = ConditionTrainer.withSimpleCondition();
|
||||||
|
const otherCondition = ScriptAccountCondition.constructScriptAccountCondition(
|
||||||
|
new ScriptAccount("Another test", ""), condition.minValue-20, condition.minValue-10);
|
||||||
|
|
||||||
|
expect(condition.isContradicting(otherCondition)).toBeFalsy();
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import {ScriptAccountCondition} from "../../../../src/app/project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import exp = require("node:constants");
|
||||||
|
test.describe('Test Create Gamesystems', () => {
|
||||||
|
|
||||||
|
test("Test creation with null/undefined parameters", async () => {
|
||||||
|
let result = ScriptAccountCondition.constructScriptAccountCondition(null, 1, 2);
|
||||||
|
expect(result).toBeUndefined()
|
||||||
|
|
||||||
|
result = ScriptAccountCondition.constructScriptAccountCondition(undefined, 1, 2);
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
|
||||||
|
result = ScriptAccountCondition.constructScriptAccountCondition(new ScriptAccount("Test", ""), null, 2);
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
|
||||||
|
result = ScriptAccountCondition.constructScriptAccountCondition(new ScriptAccount("Test", ""), undefined, 2);
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
|
||||||
|
result = ScriptAccountCondition.constructScriptAccountCondition(new ScriptAccount("Test", ""), 1, undefined);
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
|
||||||
|
result = ScriptAccountCondition.constructScriptAccountCondition(new ScriptAccount("Test", ""),1, null);
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test Creation with swapped Min Max Parameter", async () => {
|
||||||
|
let result = ScriptAccountCondition.constructScriptAccountCondition(new ScriptAccount("Test", ""), 2, 1);
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test Correct Condition Creation", async () => {
|
||||||
|
const scriptAccount = new ScriptAccount("Test", "");
|
||||||
|
|
||||||
|
let result = ScriptAccountCondition.constructScriptAccountCondition(scriptAccount, 1, 2);
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result!.scriptAccount).toEqual(scriptAccount)
|
||||||
|
expect(result!.minValue).toEqual(1);
|
||||||
|
expect(result!.maxValue).toEqual(2)
|
||||||
|
|
||||||
|
result = ScriptAccountCondition.constructScriptAccountCondition(scriptAccount, -10, 2);
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result!.scriptAccount).toEqual(scriptAccount)
|
||||||
|
expect(result!.minValue).toEqual(-10);
|
||||||
|
expect(result!.maxValue).toEqual(2)
|
||||||
|
|
||||||
|
result = ScriptAccountCondition.constructScriptAccountCondition(scriptAccount, -20, -10);
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result!.scriptAccount).toEqual(scriptAccount)
|
||||||
|
expect(result!.minValue).toEqual(-20);
|
||||||
|
expect(result!.maxValue).toEqual(-10)
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import {ScriptAccountCondition} from "../../../../src/app/project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import exp = require("node:constants");
|
||||||
|
import {ConditionTrainer} from "./ConditionTrainer";
|
||||||
|
test.describe('Test Expand Conditions', () => {
|
||||||
|
|
||||||
|
test("Test expansion with contradiccting Conditions", async () => {
|
||||||
|
const condition = ConditionTrainer.withSimpleCondition();
|
||||||
|
const otherCondition = ConditionTrainer.withContradictingCondition(condition);
|
||||||
|
|
||||||
|
condition.extendCondition(otherCondition)
|
||||||
|
expect(condition.minValue).toEqual(ConditionTrainer.withSimpleCondition().minValue);
|
||||||
|
expect(condition.maxValue).toEqual(ConditionTrainer.withSimpleCondition().maxValue);
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test lower expansion of Conditions", async () => {
|
||||||
|
const condition = ConditionTrainer.withSimpleCondition();
|
||||||
|
const otherCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue-10, condition.minValue+10)
|
||||||
|
|
||||||
|
condition.extendCondition(otherCondition);
|
||||||
|
expect(condition.minValue).toEqual(ConditionTrainer.withSimpleCondition().minValue-10)
|
||||||
|
expect(condition.maxValue).toEqual(ConditionTrainer.withSimpleCondition().maxValue);
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test higher expansion of conditions", async () => {
|
||||||
|
const condition = ConditionTrainer.withSimpleCondition();
|
||||||
|
const otherCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.maxValue-10, condition.maxValue+10)
|
||||||
|
|
||||||
|
condition.extendCondition(otherCondition)
|
||||||
|
expect(condition.minValue).toEqual(ConditionTrainer.withSimpleCondition().minValue)
|
||||||
|
expect(condition.maxValue).toEqual(ConditionTrainer.withSimpleCondition().maxValue+10)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test higher and lower Expansion of Conditions", async () => {
|
||||||
|
const condition = ConditionTrainer.withSimpleCondition();
|
||||||
|
const otherCondition = ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue-10, condition.maxValue+10);
|
||||||
|
|
||||||
|
condition.extendCondition(otherCondition);
|
||||||
|
expect(condition.minValue).toEqual(ConditionTrainer.withSimpleCondition().minValue-10)
|
||||||
|
expect(condition.maxValue).toEqual(ConditionTrainer.withSimpleCondition().maxValue+10)
|
||||||
|
})
|
||||||
|
});
|
17
e2e/game-model/gamesystems/conditions/ConditionTrainer.ts
Normal file
17
e2e/game-model/gamesystems/conditions/ConditionTrainer.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import {ScriptAccountCondition} from "../../../../src/app/project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
|
||||||
|
export class ConditionTrainer {
|
||||||
|
static withSimpleCondition(): ScriptAccountCondition {
|
||||||
|
const scriptAccount = new ScriptAccount("Test", "");
|
||||||
|
return ScriptAccountCondition.constructScriptAccountCondition(scriptAccount, 0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static withContradictingCondition(condition: ScriptAccountCondition): ScriptAccountCondition {
|
||||||
|
return ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue-20, condition.minValue-10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static withExpendingCondition(condition: ScriptAccountCondition): ScriptAccount {
|
||||||
|
return ScriptAccountCondition.constructScriptAccountCondition(condition.scriptAccount, condition.minValue-10, condition.maxValue+10);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import {SimpleState} from "../../../../src/app/project/game-model/gamesystems/states/SimpleState";
|
||||||
|
import {SimpleTransition} from "../../../../src/app/project/game-model/gamesystems/transitions/SimpleTransition";
|
||||||
|
import {ScriptAccount} from "../../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import {ScriptAccountCondition} from "../../../../src/app/project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
export class TransitionConditionTrainer {
|
||||||
|
static withTransitionWithoutConditions() {
|
||||||
|
const startingState = new SimpleState("StartingState", "");
|
||||||
|
const endingState = new SimpleState("EndingState", "");
|
||||||
|
|
||||||
|
return new SimpleTransition(startingState, endingState);
|
||||||
|
}
|
||||||
|
|
||||||
|
static withTransitionWithCondition() {
|
||||||
|
const startingState = new SimpleState("StartingState", "");
|
||||||
|
const endingState = new SimpleState("EndingState", "");
|
||||||
|
|
||||||
|
const transition = new SimpleTransition(startingState, endingState);
|
||||||
|
|
||||||
|
const scriptAccount = new ScriptAccount("ScriptAccount", "");
|
||||||
|
transition.scriptAccountConditions.push(ScriptAccountCondition.constructScriptAccountCondition(scriptAccount, 0, 10)!)
|
||||||
|
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,6 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
|
||||||
import { test, expect } from '@playwright/test';
|
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";
|
|
||||||
import {ProductStateTrainer} from "./ProductStateTrainer";
|
import {ProductStateTrainer} from "./ProductStateTrainer";
|
||||||
import {SimpleState} from "../../../../src/app/game-model/gamesystems/SimpleState";
|
import {SimpleState} from "../../../../src/app/project/game-model/gamesystems/states/SimpleState";
|
||||||
test.describe('Test Create ProductStates', () => {
|
test.describe('Test Create ProductStates', () => {
|
||||||
|
|
||||||
test("Adding already existent ProductState", async () => {
|
test("Adding already existent ProductState", async () => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import {ProductStateTrainer} from "./ProductStateTrainer";
|
import {ProductStateTrainer} from "./ProductStateTrainer";
|
||||||
import {ProductState} from "../../../../src/app/game-model/gamesystems/ProductState";
|
import {ProductState} from "../../../../src/app/project/game-model/gamesystems/states/ProductState";
|
||||||
import {SimpleGamesystem} from "../../../../src/app/game-model/gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "../../../../src/app/project/game-model/gamesystems/SimpleGamesystem";
|
||||||
test.describe('Test Create ProductTransitions', () => {
|
test.describe('Test Create ProductTransitions', () => {
|
||||||
test("Test ProductTransition Creation with invalid inputs", async ()=> {
|
test("Test ProductTransition Creation with invalid inputs", async ()=> {
|
||||||
const gamesystem = ProductStateTrainer.givenFullProductGamesystemWithTwoStates();
|
const gamesystem = ProductStateTrainer.givenFullProductGamesystemWithTwoStates();
|
||||||
|
@ -1,17 +1,5 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
|
||||||
import { test, expect } from '@playwright/test';
|
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";
|
|
||||||
import {ProductStateTrainer} from "./ProductStateTrainer";
|
import {ProductStateTrainer} from "./ProductStateTrainer";
|
||||||
import {SimpleState} from "../../../../src/app/game-model/gamesystems/SimpleState";
|
|
||||||
test.describe('Test Check Equal of Innerstates', () => {
|
test.describe('Test Check Equal of Innerstates', () => {
|
||||||
|
|
||||||
test("Test invalid input for equal checking", async()=> {
|
test("Test invalid input for equal checking", async()=> {
|
||||||
|
@ -1,17 +1,4 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
|
||||||
import { test, expect } from '@playwright/test';
|
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";
|
|
||||||
import {ProductStateTrainer} from "./ProductStateTrainer";
|
|
||||||
import {SimpleState} from "../../../../src/app/game-model/gamesystems/SimpleState";
|
|
||||||
import {ProductSystemGenerationTrainer} from "./ProductSystemGenerationTrainer";
|
import {ProductSystemGenerationTrainer} from "./ProductSystemGenerationTrainer";
|
||||||
test.describe('Test Create ProductStates', () => {
|
test.describe('Test Create ProductStates', () => {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {ProductGamesystem} from "../../../../src/app/game-model/gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "../../../../src/app/project/game-model/gamesystems/ProductGamesystem";
|
||||||
import {SimpleGamesystem} from "../../../../src/app/game-model/gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "../../../../src/app/project/game-model/gamesystems/SimpleGamesystem";
|
||||||
import {ProductState} from "../../../../src/app/game-model/gamesystems/ProductState";
|
import {ProductState} from "../../../../src/app/project/game-model/gamesystems/states/ProductState";
|
||||||
import {ProductTransition} from "../../../../src/app/game-model/gamesystems/ProductTransition";
|
import {ProductTransition} from "../../../../src/app/project/game-model/gamesystems/transitions/ProductTransition";
|
||||||
|
|
||||||
export class ProductStateTrainer {
|
export class ProductStateTrainer {
|
||||||
static INNERSTATE_LETTER_1 = "A";
|
static INNERSTATE_LETTER_1 = "A";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {ProductGamesystem} from "../../../../src/app/game-model/gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "../../../../src/app/project/game-model/gamesystems/ProductGamesystem";
|
||||||
import {SimpleGamesystem} from "../../../../src/app/game-model/gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "../../../../src/app/project/game-model/gamesystems/SimpleGamesystem";
|
||||||
|
|
||||||
export class ProductSystemGenerationTrainer {
|
export class ProductSystemGenerationTrainer {
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import * as PATH from 'path';
|
import * as PATH from 'path';
|
||||||
import {GameModel} from "../../../src/app/game-model/GameModel";
|
import {GameModel} from "../../../src/app/project/game-model/GameModel";
|
||||||
import {Gamesystem} from "../../src/app/game-model/gamesystems/Gamesystem";
|
import {Gamesystem} from "../../src/app/project/game-model/gamesystems/Gamesystem";
|
||||||
import {ScriptAccount} from "../../../src/app/game-model/scriptAccounts/ScriptAccount";
|
import {ScriptAccount} from "../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
|
||||||
import {ModelComponentType} from "../../../src/app/game-model/ModelComponentType";
|
import {ModelComponentType} from "../../../src/app/project/game-model/ModelComponentType";
|
||||||
|
|
||||||
test.describe('Test ScriptAccounts', () => {
|
test.describe('Test ScriptAccounts', () => {
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="full-height-container">
|
<div class="full-height-container" >
|
||||||
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.SCRIPTACCOUNT ? 'selected':''"
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.SCRIPTACCOUNT ? 'selected':''"
|
||||||
(click)="openScriptAccountsOverview()"><mat-icon>inventory_2</mat-icon></button>
|
(click)="openScriptAccountsOverview()"><mat-icon>inventory_2</mat-icon></button>
|
||||||
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.GAMESYTEM ? 'selected':''"
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.GAMESYTEM ? 'selected':''"
|
||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<mat-drawer-container class="example-container" autosize>
|
<mat-drawer-container class="example-container" autosize>
|
||||||
<mat-drawer #drawer class="example-sidenav" mode="side">
|
<mat-drawer #drawer class="example-sidenav" mode="side">
|
||||||
<div class="sidenav-header">
|
<div class="sidenav-header" (click)="resetSelection()">
|
||||||
<button mat-button [matMenuTriggerFor]="contentMenu">
|
<button mat-button [matMenuTriggerFor]="contentMenu">
|
||||||
<span class="mat-button-wrapper">{{ModelComponentTypeUtillities.toString(openContent)}}
|
<span class="mat-button-wrapper">{{ModelComponentTypeUtillities.toString(openContent)}}
|
||||||
<mat-icon class="mat-icon">expand_more</mat-icon>
|
<mat-icon class="mat-icon">expand_more</mat-icon>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
</mat-drawer>
|
</mat-drawer>
|
||||||
|
|
||||||
<div class="example-sidenav-content">
|
<div class="example-sidenav-content">
|
||||||
<app-editor #editor (onModelNameUpdate)="onModelNameUpdate()"></app-editor>
|
<app-editor #editor (onModelNameUpdate)="onModelNameUpdate()" [gameModel]="gameModel"></app-editor>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</mat-drawer-container>
|
</mat-drawer-container>
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
import {Component, NgZone, OnInit, ViewChild} from '@angular/core';
|
import {Component, NgZone, OnInit, ViewChild} from '@angular/core';
|
||||||
import {ElectronService} from './core/services';
|
|
||||||
import {APP_CONFIG} from '../environments/environment';
|
|
||||||
import {ModelComponentType} from "./game-model/ModelComponentType";
|
|
||||||
import {MatDrawerContainer} from "@angular/material/sidenav";
|
import {MatDrawerContainer} from "@angular/material/sidenav";
|
||||||
import {ModelComponentTypeUtillities} from "./game-model/ModelComponentTypeUtillities";
|
|
||||||
import {GameModel} from "./game-model/GameModel";
|
|
||||||
import {EditorComponent} from "./editor/editor.component";
|
import {EditorComponent} from "./editor/editor.component";
|
||||||
import {ModelComponent} from "./game-model/ModelComponent";
|
|
||||||
import {
|
import {
|
||||||
ScriptAccountOverviewComponent
|
ScriptAccountOverviewComponent
|
||||||
} from "./side-overviews/script-account-overview/script-account-overview.component";
|
} from "./side-overviews/script-account-overview/script-account-overview.component";
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component";
|
import {DeleteConfirmationDialogComponent} from "./delete-confirmation-dialog/delete-confirmation-dialog.component";
|
||||||
import {ScriptAccount} from "./game-model/scriptAccounts/ScriptAccount";
|
|
||||||
import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component";
|
import {GamescriptOverviewComponent} from "./side-overviews/gamescript-overview/gamescript-overview.component";
|
||||||
import {SimpleGamesystem} from "./game-model/gamesystems/SimpleGamesystem";
|
import {ModelComponentType} from "./project/game-model/ModelComponentType";
|
||||||
import {ProductGamesystem} from "./game-model/gamesystems/ProductGamesystem";
|
import {ModelComponentTypeUtillities} from "./project/game-model/ModelComponentTypeUtillities";
|
||||||
import {ProductState} from "./game-model/gamesystems/ProductState";
|
import {ScriptAccount} from "./project/game-model/scriptAccounts/ScriptAccount";
|
||||||
import {LoadModel} from "../../app/LoadModel";
|
import {Gamesystem} from "./project/game-model/gamesystems/Gamesystem";
|
||||||
import {LoadedProject} from "../../app/LoadedProject";
|
import {ModelComponent} from "./project/game-model/ModelComponent";
|
||||||
import {ProcessLoadedProject} from "./game-model/fs/ProcessLoadedProject";
|
import {GameModel} from "./project/game-model/GameModel";
|
||||||
import {StoreProject} from "./game-model/fs/store/StoreProject";
|
import {StoredGameModel} from "../../app/storage/StoredGameModel";
|
||||||
|
import {GamesystemParser} from "./project/parser/gamesystemParser/GamesystemParser";
|
||||||
|
import {ScriptAccountParser} from "./project/parser/ScriptAccountParser";
|
||||||
|
import {ElectronService} from "./core/services";
|
||||||
|
import {ScriptAccountSerializer} from "./project/serializer/ScriptAccountSerializer";
|
||||||
|
import {StoreComponent} from "../../app/storage/StoreComponent";
|
||||||
|
import {GamesystemSerializer} from "./project/serializer/GamesystemSerializer";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -38,17 +37,10 @@ export class AppComponent implements OnInit{
|
|||||||
gameModel: GameModel | undefined
|
gameModel: GameModel | undefined
|
||||||
|
|
||||||
constructor(private electronService: ElectronService,
|
constructor(private electronService: ElectronService,
|
||||||
private zone: NgZone,
|
private dialog: MatDialog,
|
||||||
private dialog: MatDialog
|
private zone: NgZone
|
||||||
) {
|
) {
|
||||||
console.log('APP_CONFIG', APP_CONFIG);
|
if(electronService.isElectron) {
|
||||||
|
|
||||||
if (electronService.isElectron) {
|
|
||||||
console.log(process.env);
|
|
||||||
console.log('Run in electron');
|
|
||||||
console.log('Electron ipcRenderer', this.electronService.ipcRenderer);
|
|
||||||
console.log('NodeJS childProcess', this.electronService.childProcess);
|
|
||||||
|
|
||||||
electronService.ipcRenderer.on('context-menu', (event: any, message: string) => {
|
electronService.ipcRenderer.on('context-menu', (event: any, message: string) => {
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
this.onContextMenuMessageRecieved(message);
|
this.onContextMenuMessageRecieved(message);
|
||||||
@ -57,21 +49,18 @@ export class AppComponent implements OnInit{
|
|||||||
|
|
||||||
electronService.ipcRenderer.on('get-project-data', (event: any, message: string) => {
|
electronService.ipcRenderer.on('get-project-data', (event: any, message: string) => {
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
this.saveGameModel();
|
this.onSaveProject();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
electronService.ipcRenderer.on('open-project', (event: any, loadedProject: LoadedProject) => {
|
electronService.ipcRenderer.on('open-project', (event: any, loadedProject: StoredGameModel) => {
|
||||||
this.gameModel = ProcessLoadedProject.processLoadedProject(loadedProject)
|
this.zone.run(() => {
|
||||||
|
this.onLoadProject(loadedProject)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
console.log('Run in browser');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
saveGameModel() {
|
|
||||||
const storageModels = StoreProject.storeProject(this.gameModel!);
|
}
|
||||||
this.electronService.ipcRenderer.send('save-model', storageModels)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onContextMenuMessageRecieved(message: string) {
|
onContextMenuMessageRecieved(message: string) {
|
||||||
@ -108,12 +97,18 @@ export class AppComponent implements OnInit{
|
|||||||
|
|
||||||
private onDeleteModelComponent() {
|
private onDeleteModelComponent() {
|
||||||
const affectedModelComponent = this.getSelectedModelComponent();
|
const affectedModelComponent = this.getSelectedModelComponent();
|
||||||
|
console.log("Affected ModelComponent: ", affectedModelComponent)
|
||||||
const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, {data: affectedModelComponent, minWidth: "400px"});
|
const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, {data: affectedModelComponent, minWidth: "400px"});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(res => {
|
dialogRef.afterClosed().subscribe(res => {
|
||||||
if(res != undefined && res) {
|
if(res != undefined && res) {
|
||||||
if(affectedModelComponent instanceof ScriptAccount) {
|
if(affectedModelComponent instanceof ScriptAccount) {
|
||||||
this.gameModel!.removeScriptAccount(affectedModelComponent);
|
this.gameModel!.removeScriptAccount(affectedModelComponent);
|
||||||
|
//this.electronService.ipcRenderer.send('delete-component', new DeleteModel(affectedModelComponent.componentName, ModelComponentType.SCRIPTACCOUNT))
|
||||||
|
} else if(affectedModelComponent instanceof Gamesystem) {
|
||||||
|
this.gameModel!.removeGamesystem(affectedModelComponent);
|
||||||
|
//this.electronService.ipcRenderer.send('delete-component', new DeleteModel(affectedModelComponent.componentName, ModelComponentType.GAMESYTEM))
|
||||||
|
this.gamesystemOverview!.refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -142,48 +137,63 @@ export class AppComponent implements OnInit{
|
|||||||
} else {
|
} else {
|
||||||
parentGamesystemName = this.gamesystemOverview!.selectedGamesystemName;
|
parentGamesystemName = this.gamesystemOverview!.selectedGamesystemName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const createdGamesystem = this.gameModel!.createGamesystem("New Gamesystem", parentGamesystemName);
|
const createdGamesystem = this.gameModel!.createGamesystem("New Gamesystem", parentGamesystemName);
|
||||||
if(createdGamesystem != undefined) {
|
if(createdGamesystem != undefined) {
|
||||||
this.gamesystemOverview!.refresh();
|
this.gamesystemOverview!.refresh();
|
||||||
this.editor?.openGameModelComponent(createdGamesystem!);
|
this.editor?.openGameModelComponent(createdGamesystem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSelectedModelComponent(): ModelComponent | undefined {
|
private getSelectedModelComponent(): ModelComponent | undefined {
|
||||||
if(this.openContent == ModelComponentType.SCRIPTACCOUNT) {
|
if(this.openContent == ModelComponentType.SCRIPTACCOUNT) {
|
||||||
if(this.scriptAccountOverview != undefined) {
|
if(this.scriptAccountOverview != undefined) {
|
||||||
return this.scriptAccountOverview!.selectedScriptAccount;
|
return this.scriptAccountOverview.selectedScriptAccount;
|
||||||
} else {
|
} else {
|
||||||
console.log("[WARN] [App.component] ScriptAccountOverview is undefined")
|
console.log("[WARN] [App.component] ScriptAccountOverview is undefined")
|
||||||
}
|
}
|
||||||
|
} else if(this.openContent == ModelComponentType.GAMESYTEM){
|
||||||
|
if(this.gamesystemOverview != undefined) {
|
||||||
|
return this.gamesystemOverview.getSelectedGamesystem()
|
||||||
|
} else {
|
||||||
|
console.log("[WARN] [App.component] GamesystemOverview is undefined")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
/*this.gameModel = new GameModel("No More");
|
|
||||||
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.");
|
onLoadProject(storedGameModel: StoredGameModel) {
|
||||||
const summerState = season.createState("Summer", "Summer is the hottest and brightest of the four temperate seasons, occurring after spring and before autumn. ");
|
const gameModel = new GameModel(storedGameModel.gameModelName)
|
||||||
|
|
||||||
const sunnyState = weather.createState("Sunny", "The sun is shining. No clouds, no rain, no storm.");
|
const scriptAccounts = ScriptAccountParser.parseScriptAccounts(storedGameModel.storedScriptAccounts);
|
||||||
const rainingState = weather.createState("Raining", "It rains")
|
|
||||||
|
|
||||||
season.createTransition(springState!, summerState!);
|
const gamesystemParser = new GamesystemParser(scriptAccounts);
|
||||||
weather.createTransition(sunnyState!, rainingState!);
|
const gamesystems = gamesystemParser.parseStoredGamesystems(storedGameModel.storedGamesystems);
|
||||||
|
|
||||||
const weather_season = new ProductGamesystem("Weather-Season");
|
gameModel.scriptAccounts = scriptAccounts
|
||||||
weather_season.addChildGamesystem(weather);
|
gameModel.gamesystems = gamesystems
|
||||||
weather_season.addChildGamesystem(season);
|
gameModel.generateProductSystemContents()
|
||||||
|
|
||||||
weather_season.createState([springState!, sunnyState!]);
|
console.log(gameModel.scriptAccounts)
|
||||||
|
|
||||||
this.gameModel.addGamesystem(weather_season);*/
|
this.gameModel = gameModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSaveProject() {
|
||||||
|
if(this.gameModel != undefined) {
|
||||||
|
const storedScriptAccounts = ScriptAccountSerializer.serializeScriptAccounts(this.gameModel.scriptAccounts)
|
||||||
|
const storedGamesystems: StoreComponent[] = GamesystemSerializer.serializeGamesystems(this.gameModel.gamesystems)
|
||||||
|
const storeModel = new StoredGameModel(this.gameModel.gameModelName, storedScriptAccounts, storedGamesystems)
|
||||||
|
|
||||||
|
if(this.electronService.isElectron) {
|
||||||
|
this.electronService.ipcRenderer.send('save-model', storeModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openScriptAccountsOverview() {
|
openScriptAccountsOverview() {
|
||||||
@ -218,4 +228,10 @@ export class AppComponent implements OnInit{
|
|||||||
this.gamesystemOverview!.refresh();
|
this.gamesystemOverview!.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetSelection() {
|
||||||
|
if(this.gamesystemOverview != undefined) {
|
||||||
|
this.gamesystemOverview.resetSelectedGamesystem()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,12 @@ import {
|
|||||||
} from "./editor/gamesystem-editor/state-editor/product-state-editor/product-state-editor.component";
|
} from "./editor/gamesystem-editor/state-editor/product-state-editor/product-state-editor.component";
|
||||||
import {MatTooltip} from "@angular/material/tooltip";
|
import {MatTooltip} from "@angular/material/tooltip";
|
||||||
import {MatCard, MatCardContent} from "@angular/material/card";
|
import {MatCard, MatCardContent} from "@angular/material/card";
|
||||||
|
import {
|
||||||
|
ScriptaccountActionEditorComponent
|
||||||
|
} from "./editor/gamesystem-editor/transition-editor/scriptaccount-action-editor/scriptaccount-action-editor.component";
|
||||||
|
import {
|
||||||
|
ScriptaccountConditionEditorComponent
|
||||||
|
} from "./editor/gamesystem-editor/scriptaccount-condition-editor/scriptaccount-condition-editor.component";
|
||||||
|
|
||||||
// AoT requires an exported function for factories
|
// AoT requires an exported function for factories
|
||||||
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
|
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
|
||||||
@ -81,7 +87,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
|
|||||||
SimpleTransitionEditorComponent,
|
SimpleTransitionEditorComponent,
|
||||||
ProductTransitionEditorComponent,
|
ProductTransitionEditorComponent,
|
||||||
ProductStateEditorComponent,
|
ProductStateEditorComponent,
|
||||||
ProductGamesystemEditorComponent
|
ProductGamesystemEditorComponent,
|
||||||
|
ScriptaccountActionEditorComponent,
|
||||||
|
ScriptaccountConditionEditorComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
import {Component, Inject} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
import {ModelComponentTypeUtillities} from "../game-model/ModelComponentTypeUtillities";
|
import {ModelComponent} from "../project/game-model/ModelComponent";
|
||||||
import {ModelComponent} from "../game-model/ModelComponent";
|
import {ModelComponentTypeUtillities} from "../project/game-model/ModelComponentTypeUtillities";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-delete-confirmation-dialog',
|
selector: 'app-delete-confirmation-dialog',
|
||||||
templateUrl: './delete-confirmation-dialog.component.html',
|
templateUrl: './delete-confirmation-dialog.component.html',
|
||||||
styleUrl: './delete-confirmation-dialog.component.scss'
|
styleUrl: './delete-confirmation-dialog.component.scss'
|
||||||
})
|
})
|
||||||
export class DeleteConfirmationDialogComponent {
|
export class DeleteConfirmationDialogComponent implements OnInit{
|
||||||
|
|
||||||
constructor(private dialogRef: MatDialogRef<DeleteConfirmationDialogComponent>,
|
constructor(private dialogRef: MatDialogRef<DeleteConfirmationDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public deleteModelComponent: ModelComponent) {
|
@Inject(MAT_DIALOG_DATA) public deleteModelComponent: ModelComponent) {
|
||||||
}
|
}
|
||||||
protected readonly ModelComponentTypeUtillities = ModelComponentTypeUtillities;
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
console.log("delete Confirmation dialog here")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
||||||
@ -22,4 +27,6 @@ export class DeleteConfirmationDialogComponent {
|
|||||||
confirmDelete() {
|
confirmDelete() {
|
||||||
this.dialogRef.close(true);
|
this.dialogRef.close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected readonly ModelComponentTypeUtillities = ModelComponentTypeUtillities;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
[scriptAccount]="convertModelComponentToScriptAccount(modelComponent)"></app-script-account-editor>
|
[scriptAccount]="convertModelComponentToScriptAccount(modelComponent)"></app-script-account-editor>
|
||||||
<app-gamesystem-editor *ngIf="modelComponent.type === ModelComponentType.GAMESYTEM"
|
<app-gamesystem-editor *ngIf="modelComponent.type === ModelComponentType.GAMESYTEM"
|
||||||
[gamesystem]="convertModelComponentToGamesystem(modelComponent)"
|
[gamesystem]="convertModelComponentToGamesystem(modelComponent)"
|
||||||
(onOpenGamesystemEditor)="openGameModelComponent($event)"></app-gamesystem-editor>
|
(onOpenGamesystemEditor)="openGameModelComponent($event)"
|
||||||
|
[scriptAccounts]="gameModel!.scriptAccounts"></app-gamesystem-editor>
|
||||||
|
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {GameModel} from "../game-model/GameModel";
|
import {ModelComponent} from "../project/game-model/ModelComponent";
|
||||||
import {ModelComponent} from "../game-model/ModelComponent";
|
import {GameModel} from "../project/game-model/GameModel";
|
||||||
import {ModelComponentType} from "../game-model/ModelComponentType";
|
import {ScriptAccount} from "../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
import {ScriptAccount} from "../game-model/scriptAccounts/ScriptAccount";
|
import {Gamesystem} from "../project/game-model/gamesystems/Gamesystem";
|
||||||
import {Gamesystem} from "../game-model/gamesystems/Gamesystem";
|
import {State} from "../project/game-model/gamesystems/states/State";
|
||||||
import {State} from "../game-model/gamesystems/State";
|
import {Transition} from "../project/game-model/gamesystems/transitions/Transition";
|
||||||
import {Transition} from "../game-model/gamesystems/Transition";
|
import {ModelComponentType} from "../project/game-model/ModelComponentType";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-editor',
|
selector: 'app-editor',
|
||||||
@ -16,6 +17,7 @@ export class EditorComponent {
|
|||||||
gameModelComponents: ModelComponent[] = [];
|
gameModelComponents: ModelComponent[] = [];
|
||||||
@Output("onModelNameUpdate") onModelNameUpdateEmitter = new EventEmitter<boolean>();
|
@Output("onModelNameUpdate") onModelNameUpdateEmitter = new EventEmitter<boolean>();
|
||||||
activeTab: number = this.gameModelComponents.length;
|
activeTab: number = this.gameModelComponents.length;
|
||||||
|
@Input() gameModel: GameModel | undefined
|
||||||
|
|
||||||
openGameModelComponent(gameModelComponent: ModelComponent) {
|
openGameModelComponent(gameModelComponent: ModelComponent) {
|
||||||
if(!this.gameModelComponents.includes(gameModelComponent)) {
|
if(!this.gameModelComponents.includes(gameModelComponent)) {
|
||||||
@ -42,9 +44,10 @@ export class EditorComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly ModelComponentType = ModelComponentType;
|
|
||||||
|
|
||||||
onModelNameUpdate() {
|
onModelNameUpdate() {
|
||||||
this.onModelNameUpdateEmitter.emit(true);
|
this.onModelNameUpdateEmitter.emit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected readonly ModelComponentType = ModelComponentType;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<app-simple-gamesystem-editor *ngIf="isSimpleGamesystem()" [simpleGamesystem]="convertGamesystemToSimpleGamesystem()"></app-simple-gamesystem-editor>
|
<app-simple-gamesystem-editor *ngIf="isSimpleGamesystem()" [simpleGamesystem]="convertGamesystemToSimpleGamesystem()" [scriptAccunts]="scriptAccounts"></app-simple-gamesystem-editor>
|
||||||
<app-product-gamesystem-editor *ngIf="!isSimpleGamesystem()" [gamesystem]="convertGamesystemToProductGamesystem()"
|
<app-product-gamesystem-editor *ngIf="!isSimpleGamesystem()" [gamesystem]="convertGamesystemToProductGamesystem()"
|
||||||
(onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-gamesystem-editor>
|
(onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-gamesystem-editor>
|
||||||
|
@ -1,21 +1,26 @@
|
|||||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||||
import {GameModel} from "../../game-model/GameModel";
|
import {State} from "../../project/game-model/gamesystems/states/State";
|
||||||
import {Gamesystem} from "../../game-model/gamesystems/Gamesystem";
|
import {Gamesystem} from "../../project/game-model/gamesystems/Gamesystem";
|
||||||
import {State} from "../../game-model/gamesystems/State";
|
import { Transition } from '../../project/game-model/gamesystems/transitions/Transition';
|
||||||
import {Transition} from "../../game-model/gamesystems/Transition";
|
import {ScriptAccount} from "../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
import {SimpleGamesystem} from "../../game-model/gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
import {ProductGamesystem} from "../../game-model/gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "../../project/game-model/gamesystems/ProductGamesystem";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-gamesystem-editor',
|
selector: 'app-gamesystem-editor',
|
||||||
templateUrl: './gamesystem-editor.component.html',
|
templateUrl: './gamesystem-editor.component.html',
|
||||||
styleUrl: './gamesystem-editor.component.scss'
|
styleUrl: './gamesystem-editor.component.scss'
|
||||||
})
|
})
|
||||||
export class GamesystemEditorComponent {
|
export class GamesystemEditorComponent implements OnInit{
|
||||||
|
|
||||||
@Input() gamesystem: Gamesystem<State<any>, Transition<any>> | undefined
|
@Input() gamesystem: Gamesystem<State<any>, Transition<any>> | undefined
|
||||||
|
@Input() scriptAccounts: ScriptAccount[] = [];
|
||||||
@Output('onOpenGamesystemEditor') openGamesystemEmitter = new EventEmitter<SimpleGamesystem>();
|
@Output('onOpenGamesystemEditor') openGamesystemEmitter = new EventEmitter<SimpleGamesystem>();
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
console.log("GamesystemEditor: ", this.scriptAccounts.length)
|
||||||
|
}
|
||||||
|
|
||||||
isSimpleGamesystem() {
|
isSimpleGamesystem() {
|
||||||
return this.gamesystem instanceof SimpleGamesystem;
|
return this.gamesystem instanceof SimpleGamesystem;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import {Gamesystem} from "../../../game-model/gamesystems/Gamesystem";
|
import {Gamesystem} from "../../../project/game-model/gamesystems/Gamesystem";
|
||||||
import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "../../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
import {ProductGamesystem} from "../../../game-model/gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "../../../project/game-model/gamesystems/ProductGamesystem";
|
||||||
import {State} from "../../../game-model/gamesystems/State";
|
import {State} from "../../../project/game-model/gamesystems/states/State";
|
||||||
import {ProductState} from "../../../game-model/gamesystems/ProductState";
|
import {SimpleState} from "../../../project/game-model/gamesystems/states/SimpleState";
|
||||||
import {SimpleState} from "../../../game-model/gamesystems/SimpleState";
|
import {ProductState} from "../../../project/game-model/gamesystems/states/ProductState";
|
||||||
|
|
||||||
export class LeafGamesystemCalculator {
|
export class LeafGamesystemCalculator {
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {ProductGamesystem} from "../../../game-model/gamesystems/ProductGamesystem";
|
|
||||||
import {ProductStateEditorComponent} from "../state-editor/product-state-editor/product-state-editor.component";
|
|
||||||
import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem";
|
|
||||||
import {
|
import {
|
||||||
ProductTransitionEditorComponent
|
ProductTransitionEditorComponent
|
||||||
} from "../transition-editor/product-transition-editor/product-transition-editor.component";
|
} from "../transition-editor/product-transition-editor/product-transition-editor.component";
|
||||||
|
import {ProductGamesystem} from "../../../project/game-model/gamesystems/ProductGamesystem";
|
||||||
|
import {SimpleGamesystem} from "../../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||||
|
<ng-container matColumnDef="scriptAccount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>ScriptAccount</th>
|
||||||
|
<td mat-cell *matCellDef="let condition; let i = index">
|
||||||
|
<span *ngIf="condition !== addedCondition">{{condition.scriptAccount.componentName}}</span>
|
||||||
|
<mat-form-field appearance="fill" class="long-form" *ngIf="condition === addedCondition">
|
||||||
|
<mat-label>ScriptAccount</mat-label>
|
||||||
|
<mat-select [(ngModel)]="addedCondition!.scriptAccount">
|
||||||
|
<mat-option *ngFor="let scriptAccount of scriptAccounts" [value]="scriptAccount">{{scriptAccount.componentName}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="minValue">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Minimal Value</th>
|
||||||
|
<td mat-cell *matCellDef="let condition">
|
||||||
|
<span *ngIf="condition !== editedCondition && condition !== addedCondition">{{condition.minValue}}</span>
|
||||||
|
<mat-form-field appearance="fill" class="long-form" *ngIf=" condition === editedCondition">
|
||||||
|
<mat-label>Minimal Value</mat-label>
|
||||||
|
<input matInput [(ngModel)]="editedCondition!.minValue">
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="maxValue">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Maximal Value</th>
|
||||||
|
<td mat-cell *matCellDef="let condition">
|
||||||
|
<span *ngIf="condition !== editedCondition && condition !== addedCondition">{{condition.maxValue}}</span>
|
||||||
|
<mat-form-field appearance="fill" class="long-form" *ngIf=" condition === editedCondition">
|
||||||
|
<mat-label>Maximal Value</mat-label>
|
||||||
|
<input matInput [(ngModel)]="editedCondition!.maxValue">
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="edit">
|
||||||
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
|
<td mat-cell *matCellDef="let condition;">
|
||||||
|
<button mat-icon-button class="icon-btn-primary" *ngIf="editedCondition === undefined" (click)="edit(condition)"><mat-icon>edit</mat-icon></button>
|
||||||
|
<button mat-icon-button class="icon-btn-primary" *ngIf="editedCondition === condition" (click)="finishEditing()"><mat-icon>done</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="delete">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
|
<button mat-icon-button (click)="createCondition()"><mat-icon>add</mat-icon></button>
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let condition">
|
||||||
|
<button mat-icon-button color="warn" (click)="deleteCondition(condition)"><mat-icon>delete</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
</table>
|
@ -0,0 +1,7 @@
|
|||||||
|
.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ScriptaccountConditionEditorComponent } from './scriptaccount-condition-editor.component';
|
||||||
|
|
||||||
|
describe('ScriptaccountConditionEditorComponent', () => {
|
||||||
|
let component: ScriptaccountConditionEditorComponent;
|
||||||
|
let fixture: ComponentFixture<ScriptaccountConditionEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ScriptaccountConditionEditorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ScriptaccountConditionEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,67 @@
|
|||||||
|
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||||
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
|
import {ScriptAccountCondition} from "../../../project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
import {ScriptAccount} from "../../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-scriptaccount-condition-editor',
|
||||||
|
templateUrl: './scriptaccount-condition-editor.component.html',
|
||||||
|
styleUrl: './scriptaccount-condition-editor.component.scss'
|
||||||
|
})
|
||||||
|
export class ScriptaccountConditionEditorComponent implements OnInit{
|
||||||
|
|
||||||
|
@Input() conditions: ScriptAccountCondition[] = []
|
||||||
|
@Input() scriptAccounts: ScriptAccount[] = []
|
||||||
|
@Input() enableEditiong: boolean = false
|
||||||
|
@Output() onCreateCondition: EventEmitter<ScriptAccountCondition> = new EventEmitter<ScriptAccountCondition>();
|
||||||
|
@Output() onDeleteCondition: EventEmitter<ScriptAccountCondition> = new EventEmitter<ScriptAccountCondition>();
|
||||||
|
|
||||||
|
dataSource: MatTableDataSource<ScriptAccountCondition> = new MatTableDataSource();
|
||||||
|
displayedColumns = ['scriptAccount', 'minValue', 'maxValue']
|
||||||
|
|
||||||
|
editedCondition: ScriptAccountCondition | undefined
|
||||||
|
addedCondition: ScriptAccountCondition | undefined
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.dataSource.data = this.conditions.concat();
|
||||||
|
|
||||||
|
if(this.enableEditiong) {
|
||||||
|
this.displayedColumns.push( 'edit', 'delete')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
createCondition() {
|
||||||
|
this.addedCondition = ScriptAccountCondition.constructScriptAccountCondition(new ScriptAccount("", ""), 0,0);
|
||||||
|
this.editedCondition = this.addedCondition;
|
||||||
|
this.dataSource.data = this.dataSource.data.concat(this.addedCondition!);
|
||||||
|
}
|
||||||
|
|
||||||
|
finishEditing() {
|
||||||
|
if(this.addedCondition != undefined) {
|
||||||
|
const createdCondition = ScriptAccountCondition.constructScriptAccountCondition(this.addedCondition.scriptAccount, this.addedCondition.minValue, this.addedCondition.maxValue);
|
||||||
|
if(createdCondition != undefined) {
|
||||||
|
console.log(createdCondition)
|
||||||
|
this.onCreateCondition.emit(createdCondition);
|
||||||
|
console.log(this.conditions)
|
||||||
|
this.dataSource.data = this.conditions;
|
||||||
|
}
|
||||||
|
this.addedCondition = undefined;
|
||||||
|
}
|
||||||
|
this.editedCondition = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit(condition: ScriptAccountCondition) {
|
||||||
|
this.editedCondition = condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteCondition(condition: ScriptAccountCondition) {
|
||||||
|
if(this.addedCondition === condition) {
|
||||||
|
this.addedCondition = undefined;
|
||||||
|
this.dataSource.data = this.conditions.concat();
|
||||||
|
} else {
|
||||||
|
this.onDeleteCondition.emit(condition);
|
||||||
|
this.dataSource.data = this.conditions.concat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
<app-simple-state-editor [states]="simpleGamesystem!.states" [gamesystem]="simpleGamesystem"></app-simple-state-editor>
|
<app-simple-state-editor [states]="simpleGamesystem!.states" [gamesystem]="simpleGamesystem" [scriptAccounts]="scriptAccunts"></app-simple-state-editor>
|
||||||
<div id="transition-editor">
|
<div id="transition-editor">
|
||||||
<app-simple-transition-editor [gamesystem]="simpleGamesystem"></app-simple-transition-editor>
|
<app-simple-transition-editor [gamesystem]="simpleGamesystem" [scriptAccounts]="scriptAccunts"></app-simple-transition-editor>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {SimpleGamesystem} from "../../../game-model/gamesystems/SimpleGamesystem";
|
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
|
import {SimpleGamesystem} from "../../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
|
import {ScriptAccount} from "../../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-simple-gamesystem-editor',
|
selector: 'app-simple-gamesystem-editor',
|
||||||
@ -10,7 +11,7 @@ import {MatTableDataSource} from "@angular/material/table";
|
|||||||
export class SimpleGamesystemEditorComponent {
|
export class SimpleGamesystemEditorComponent {
|
||||||
|
|
||||||
@Input() simpleGamesystem: SimpleGamesystem | undefined
|
@Input() simpleGamesystem: SimpleGamesystem | undefined
|
||||||
|
@Input() scriptAccunts: ScriptAccount[] = []
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter" #input>
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter" #input>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<table mat-table [dataSource]="datasource" class="mat-elevation-z8">
|
<table mat-table [dataSource]="datasource" class="mat-elevation-z8" multiTemplateDataRows>
|
||||||
<ng-container *ngFor="let col of displayedColumns; let i = index" [matColumnDef]="col">
|
<ng-container *ngFor="let col of displayedColumns; let i = index" [matColumnDef]="col">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{col}}</th>
|
<th mat-header-cell *matHeaderCellDef>{{col}}</th>
|
||||||
<td mat-cell *matCellDef="let state">
|
<td mat-cell *matCellDef="let state">
|
||||||
@ -15,8 +15,36 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<ng-container matColumnDef="expand">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
<th mat-header-cell *matHeaderCellDef aria-label="row actions"> </th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
<button mat-icon-button aria-label="expand row" (click)="(expandedElement = expandedElement === element ? null : element); $event.stopPropagation()">
|
||||||
|
@if (expandedElement === element) {
|
||||||
|
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||||
|
} @else {
|
||||||
|
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="expandedDetail">
|
||||||
|
<td mat-cell *matCellDef="let element" [attr.colspan]="expandedColumns.length">
|
||||||
|
<div class="example-element-detail"
|
||||||
|
[@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||||
|
<app-scriptaccount-condition-editor [conditions]="element.conditions" [enableEditiong]="false"></app-scriptaccount-condition-editor>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="expandedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let element; columns: expandedColumns;"
|
||||||
|
class="example-element-row"
|
||||||
|
[class.example-expanded-row]="expandedElement === element"
|
||||||
|
(click)="expandedElement = expandedElement === element ? null : element">
|
||||||
|
</tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||||
</table>
|
</table>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
@ -2,10 +2,59 @@ table {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-column-Initial {
|
.mat-column-Initial, .mat-column-expand {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.long-form {
|
.long-form {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
@ -1,18 +1,24 @@
|
|||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||||
import {ProductGamesystem} from "../../../../game-model/gamesystems/ProductGamesystem";
|
|
||||||
import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem";
|
|
||||||
import {
|
import {
|
||||||
MatTableDataSource
|
MatTableDataSource
|
||||||
} from "@angular/material/table";
|
} from "@angular/material/table";
|
||||||
import {SimpleState} from "../../../../game-model/gamesystems/SimpleState";
|
|
||||||
import {State} from "../../../../game-model/gamesystems/State";
|
|
||||||
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
|
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
|
||||||
import {ProductTransition} from "../../../../game-model/gamesystems/ProductTransition";
|
import {animate, state, style, transition, trigger} from "@angular/animations";
|
||||||
import {ProductState} from "../../../../game-model/gamesystems/ProductState";
|
import {ProductGamesystem} from "../../../../project/game-model/gamesystems/ProductGamesystem";
|
||||||
|
import {SimpleGamesystem} from "../../../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
|
import {ProductState} from "../../../../project/game-model/gamesystems/states/ProductState";
|
||||||
|
import {State} from "../../../../project/game-model/gamesystems/states/State";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-product-state-editor',
|
selector: 'app-product-state-editor',
|
||||||
templateUrl: './product-state-editor.component.html',
|
templateUrl: './product-state-editor.component.html',
|
||||||
|
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)')),
|
||||||
|
]),
|
||||||
|
],
|
||||||
styleUrl: './product-state-editor.component.scss'
|
styleUrl: './product-state-editor.component.scss'
|
||||||
})
|
})
|
||||||
export class ProductStateEditorComponent implements OnInit{
|
export class ProductStateEditorComponent implements OnInit{
|
||||||
@ -20,13 +26,16 @@ export class ProductStateEditorComponent implements OnInit{
|
|||||||
@Input() gamesystem: ProductGamesystem | undefined
|
@Input() gamesystem: ProductGamesystem | undefined
|
||||||
@Output('onOpenGamesystemEditor') openGamesystemEditorEmitter = new EventEmitter<SimpleGamesystem>();
|
@Output('onOpenGamesystemEditor') openGamesystemEditorEmitter = new EventEmitter<SimpleGamesystem>();
|
||||||
displayedColumns: string[] = [];
|
displayedColumns: string[] = [];
|
||||||
|
expandedColumns: string[] = []
|
||||||
datasource = new MatTableDataSource<ProductState>();
|
datasource = new MatTableDataSource<ProductState>();
|
||||||
|
|
||||||
|
expandedElement: ProductState | null = null;
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.gamesystem!.generateFromChildsystems();
|
this.gamesystem!.generateFromChildsystems();
|
||||||
this.generateColumnNamesRecursively(this.gamesystem!, "");
|
this.generateColumnNamesRecursively(this.gamesystem!, "");
|
||||||
this.displayedColumns.push('Initial');
|
this.displayedColumns.push('Initial');
|
||||||
|
this.expandedColumns = [...this.displayedColumns, 'expand'];
|
||||||
this.datasource.data = this.gamesystem!.states;
|
this.datasource.data = this.gamesystem!.states;
|
||||||
this.datasource.filterPredicate = (data: ProductState, filter: string) => {
|
this.datasource.filterPredicate = (data: ProductState, filter: string) => {
|
||||||
const leaf_states = LeafGamesystemCalculator.calcLeafStates(data);
|
const leaf_states = LeafGamesystemCalculator.calcLeafStates(data);
|
||||||
@ -44,7 +53,6 @@ export class ProductStateEditorComponent implements OnInit{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly SimpleState = SimpleState;
|
|
||||||
|
|
||||||
getLeafState(state: State<any>, i: number) {
|
getLeafState(state: State<any>, i: number) {
|
||||||
return LeafGamesystemCalculator.calcLeafStates(state)[i];
|
return LeafGamesystemCalculator.calcLeafStates(state)[i];
|
||||||
|
@ -25,6 +25,11 @@
|
|||||||
<mat-label>Description</mat-label>
|
<mat-label>Description</mat-label>
|
||||||
<textarea matInput [(ngModel)]="element.stateDescription" rows="3" (ngModelChange)="onStateChange()"></textarea>
|
<textarea matInput [(ngModel)]="element.stateDescription" rows="3" (ngModelChange)="onStateChange()"></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div class="long-form">
|
||||||
|
<app-scriptaccount-condition-editor [conditions]="element.conditions" [scriptAccounts]="scriptAccounts" [enableEditiong]="true"
|
||||||
|
(onCreateCondition)="onCreateCondition(element, $event)" (onDeleteCondition)="deleteCondition(element, $event)"></app-scriptaccount-condition-editor>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@ -46,8 +51,8 @@
|
|||||||
<ng-container matColumnDef="edit">
|
<ng-container matColumnDef="edit">
|
||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let state">
|
<td mat-cell *matCellDef="let state">
|
||||||
<button mat-icon-button color="primary" *ngIf="editedElement !== state" (click)="editState(state)" [disabled]="editedElement !== null"><mat-icon>edit</mat-icon></button>
|
<button mat-icon-button class="icon-btn-primary" *ngIf="editedElement !== state" (click)="editState(state)" [disabled]="editedElement !== null"><mat-icon>edit</mat-icon></button>
|
||||||
<button mat-icon-button color="primary" (click)="finishEditing()" *ngIf="editedElement === state"><mat-icon>done</mat-icon></button>
|
<button mat-icon-button class="icon-btn-primary" (click)="finishEditing()" *ngIf="editedElement === state"><mat-icon>done</mat-icon></button>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@ -17,12 +17,6 @@ tr.example-element-row:not(.example-expanded-row):active {
|
|||||||
.example-element-row td {
|
.example-element-row td {
|
||||||
border-bottom-width: 0;
|
border-bottom-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.example-element-detail {
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example-element-diagram {
|
.example-element-diagram {
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
border: 2px solid black;
|
border: 2px solid black;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import {Component, Input, OnInit} from '@angular/core';
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
import {SimpleState} from "../../../../game-model/gamesystems/SimpleState";
|
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
import {animate, state, style, transition, trigger} from "@angular/animations";
|
import {animate, state, style, transition, trigger} from "@angular/animations";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem";
|
import {SimpleState} from "../../../../project/game-model/gamesystems/states/SimpleState";
|
||||||
import {ProductState} from "../../../../game-model/gamesystems/ProductState";
|
import {SimpleGamesystem} from "../../../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
|
import {ScriptAccount} from "../../../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import {ScriptAccountCondition} from "../../../../project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-simple-state-editor',
|
selector: 'app-simple-state-editor',
|
||||||
@ -23,6 +23,7 @@ export class SimpleStateEditorComponent implements OnInit{
|
|||||||
|
|
||||||
@Input() states: SimpleState[] = [];
|
@Input() states: SimpleState[] = [];
|
||||||
@Input() gamesystem: SimpleGamesystem | undefined
|
@Input() gamesystem: SimpleGamesystem | undefined
|
||||||
|
@Input() scriptAccounts: ScriptAccount[] = []
|
||||||
dataSource = new MatTableDataSource<SimpleState>();
|
dataSource = new MatTableDataSource<SimpleState>();
|
||||||
displayedColumns = ["name", "initial", "edit", "delete"];
|
displayedColumns = ["name", "initial", "edit", "delete"];
|
||||||
columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
|
columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
|
||||||
@ -93,4 +94,13 @@ export class SimpleStateEditorComponent implements OnInit{
|
|||||||
const filterValue = (event.target as HTMLInputElement).value;
|
const filterValue = (event.target as HTMLInputElement).value;
|
||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCreateCondition(state: SimpleState, condition: ScriptAccountCondition) {
|
||||||
|
state.addScriptAccountCondition(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
deleteCondition(state: SimpleState, condition: ScriptAccountCondition) {
|
||||||
|
state.removeScriptAccountCondition(condition.scriptAccount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,31 @@
|
|||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter" #input>
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter" #input>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<table mat-table [dataSource]="dataSource">
|
<table mat-table [dataSource]="dataSource" multiTemplateDataRows>
|
||||||
<ng-container *ngFor="let col of displayedColumns; let i = index" [matColumnDef]="col.internalName">
|
<ng-container *ngFor="let col of displayedColumns; let i = index" [matColumnDef]="col.internalName">
|
||||||
<th mat-header-cell *matHeaderCellDef (dblclick)="openGamesystemEditor(i)">{{col.displayedName}}</th>
|
<th mat-header-cell *matHeaderCellDef (dblclick)="openGamesystemEditor(i)">{{col.displayedName}}</th>
|
||||||
<td mat-cell *matCellDef="let transition" [matTooltip]="getLeafStateByIndex(transition, i).stateDescription" (dblclick)="openGamesystemEditor(i)">
|
<td mat-cell *matCellDef="let transition" [matTooltip]="getLeafStateByIndex(transition, i).stateDescription" (dblclick)="openGamesystemEditor(i)">
|
||||||
{{getLeafStateByIndex(transition, i).stateLabel}}
|
{{getLeafStateByIndex(transition, i).stateLabel}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container [matColumnDef]="'expand'">
|
||||||
|
<th mat-header-cell *matHeaderCellDef ></th>
|
||||||
|
<td mat-cell *matCellDef="let transition">
|
||||||
|
<button mat-icon-button aria-label="expand row" (click)="(expandedElement = expandedElement === transition ? null : transition); $event.stopPropagation()">
|
||||||
|
@if (expandedElement === transition) {
|
||||||
|
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||||
|
} @else {
|
||||||
|
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ng-container matColumnDef="header-row-sec-group">
|
<ng-container matColumnDef="header-row-sec-group">
|
||||||
<th
|
<th
|
||||||
mat-header-cell
|
mat-header-cell
|
||||||
@ -28,7 +45,7 @@
|
|||||||
mat-header-cell
|
mat-header-cell
|
||||||
*matHeaderCellDef
|
*matHeaderCellDef
|
||||||
[style.text-align]="'center'"
|
[style.text-align]="'center'"
|
||||||
[attr.colspan]="numberLeafSystems"
|
[attr.colspan]="numberLeafSystems+1"
|
||||||
>
|
>
|
||||||
Ending State
|
Ending State
|
||||||
</th>
|
</th>
|
||||||
@ -41,9 +58,22 @@
|
|||||||
></tr>
|
></tr>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="expandedDetail">
|
||||||
|
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
|
||||||
|
<div class="example-element-detail"
|
||||||
|
[@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||||
|
<app-scriptaccount-condition-editor [enableEditiong]="false" [conditions]="element.scriptAccountConditions" ></app-scriptaccount-condition-editor>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="columns;sticky:true"></tr>
|
|
||||||
<tr mat-row *matRowDef="let row; columns: columns;"></tr>
|
<tr mat-header-row *matHeaderRowDef="columnsToDisplayWithExpand"></tr>
|
||||||
|
<tr mat-row *matRowDef="let element; columns: columnsToDisplayWithExpand;"
|
||||||
|
class="example-element-row"
|
||||||
|
[class.example-expanded-row]="expandedElement === element"
|
||||||
|
(click)="expandedElement = expandedElement === element ? null : element">
|
||||||
|
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||||
|
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
|
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
|
||||||
|
@ -2,3 +2,56 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.mat-column-expand {
|
||||||
|
width: 32px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||||
import {ProductGamesystem} from "../../../../game-model/gamesystems/ProductGamesystem";
|
|
||||||
import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem";
|
|
||||||
import {
|
import {
|
||||||
MatTableDataSource
|
MatTableDataSource
|
||||||
} from "@angular/material/table";
|
} from "@angular/material/table";
|
||||||
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
|
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
|
||||||
import {ProductTransition} from "../../../../game-model/gamesystems/ProductTransition";
|
import {animate, state, style, transition, trigger} from "@angular/animations";
|
||||||
import {ProductState} from "../../../../game-model/gamesystems/ProductState";
|
import {ProductGamesystem} from "../../../../project/game-model/gamesystems/ProductGamesystem";
|
||||||
|
import {SimpleGamesystem} from "../../../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
|
import {ProductTransition} from "../../../../project/game-model/gamesystems/transitions/ProductTransition";
|
||||||
|
import {ProductState} from "../../../../project/game-model/gamesystems/states/ProductState";
|
||||||
class DisplayedColumnName {
|
class DisplayedColumnName {
|
||||||
displayedName: string
|
displayedName: string
|
||||||
internalName: string
|
internalName: string
|
||||||
@ -20,7 +21,14 @@ class DisplayedColumnName {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-product-transition-editor',
|
selector: 'app-product-transition-editor',
|
||||||
templateUrl: './product-transition-editor.component.html',
|
templateUrl: './product-transition-editor.component.html',
|
||||||
styleUrl: './product-transition-editor.component.scss'
|
styleUrl: './product-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 ProductTransitionEditorComponent implements OnInit{
|
export class ProductTransitionEditorComponent implements OnInit{
|
||||||
|
|
||||||
@ -30,6 +38,8 @@ export class ProductTransitionEditorComponent implements OnInit{
|
|||||||
dataSource = new MatTableDataSource<ProductTransition>();
|
dataSource = new MatTableDataSource<ProductTransition>();
|
||||||
displayedColumns: DisplayedColumnName[] = [];
|
displayedColumns: DisplayedColumnName[] = [];
|
||||||
columns: string[] = [];
|
columns: string[] = [];
|
||||||
|
columnsToDisplayWithExpand = [...this.columns, 'expand'];
|
||||||
|
expandedElement: ProductTransition | null = null
|
||||||
numberLeafSystems: number = -1;
|
numberLeafSystems: number = -1;
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -40,6 +50,7 @@ export class ProductTransitionEditorComponent implements OnInit{
|
|||||||
|
|
||||||
this.numberLeafSystems = leafGamesystems.length;
|
this.numberLeafSystems = leafGamesystems.length;
|
||||||
this.columns = this.displayedColumns.map(column => column.internalName)
|
this.columns = this.displayedColumns.map(column => column.internalName)
|
||||||
|
this.columnsToDisplayWithExpand = [...this.columns, 'expand']
|
||||||
|
|
||||||
this.dataSource.data = this.gamesystem.transitions;
|
this.dataSource.data = this.gamesystem.transitions;
|
||||||
this.dataSource.filterPredicate = (data: ProductTransition, filter: string) => {
|
this.dataSource.filterPredicate = (data: ProductTransition, filter: string) => {
|
||||||
@ -64,7 +75,6 @@ export class ProductTransitionEditorComponent implements OnInit{
|
|||||||
}
|
}
|
||||||
|
|
||||||
const leafStates = LeafGamesystemCalculator.calcLeafStates(state);
|
const leafStates = LeafGamesystemCalculator.calcLeafStates(state);
|
||||||
console.log(leafStates)
|
|
||||||
return leafStates[index];
|
return leafStates[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||||
|
<ng-container matColumnDef="scriptAccount">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>ScriptAccount</th>
|
||||||
|
<td mat-cell *matCellDef="let action">
|
||||||
|
<span *ngIf="action !== addedAction">{{action.scriptAccount.componentName}}</span>
|
||||||
|
<mat-form-field appearance="fill" class="long-form" *ngIf="action === addedAction">
|
||||||
|
<mat-label>ScriptAccount</mat-label>
|
||||||
|
<mat-select [(ngModel)]="addedAction!.scriptAccount">
|
||||||
|
<mat-option *ngFor="let scriptAccount of scriptAccounts" [value]="scriptAccount">{{scriptAccount.componentName}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="valueChange">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Value</th>
|
||||||
|
<td mat-cell *matCellDef="let action">
|
||||||
|
<span *ngIf="addedAction !== action && editedAction != action">{{action.changingValue}}</span>
|
||||||
|
<mat-form-field appearance="fill" class="long-form" *ngIf="addedAction === action || editedAction === action">
|
||||||
|
<mat-label>Value</mat-label>
|
||||||
|
<input matInput [(ngModel)]="editedAction!.changingValue" type="number">
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="edit">
|
||||||
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
|
<td mat-cell *matCellDef="let action">
|
||||||
|
<button mat-icon-button class="icon-btn-primary" (click)="editAction(action)" [disabled]="addedAction != undefined || editedAction != undefined" *ngIf="action !== editedAction && action !== addedAction"><mat-icon>edit</mat-icon></button>
|
||||||
|
<button mat-icon-button class="icon-btn-primary" *ngIf="action === editedAction || action === addedAction" (click)="finishEditing()"><mat-icon>done</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="delete">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
|
<button mat-icon-button (click)="createNewAction()"><mat-icon>add</mat-icon></button>
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let action">
|
||||||
|
<button mat-icon-button color="warn" (click)="deleteAction(action)"><mat-icon>delete</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
</table>
|
@ -0,0 +1,11 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.long-form {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-edit, .mat-column-delete, .mat-column-expand {
|
||||||
|
width: 32px;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ScriptaccountActionEditorComponent } from './scriptaccount-action-editor.component';
|
||||||
|
|
||||||
|
describe('ScriptaccountActionEditorComponent', () => {
|
||||||
|
let component: ScriptaccountActionEditorComponent;
|
||||||
|
let fixture: ComponentFixture<ScriptaccountActionEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ScriptaccountActionEditorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ScriptaccountActionEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,57 @@
|
|||||||
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
|
import {ScriptAccount} from "../../../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
import {Transition} from "../../../../project/game-model/gamesystems/transitions/Transition";
|
||||||
|
import {ScriptAccountAction} from "../../../../project/game-model/gamesystems/actions/ScriptAccountAction";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-scriptaccount-action-editor',
|
||||||
|
templateUrl: './scriptaccount-action-editor.component.html',
|
||||||
|
styleUrl: './scriptaccount-action-editor.component.scss'
|
||||||
|
})
|
||||||
|
export class ScriptaccountActionEditorComponent implements OnInit{
|
||||||
|
@Input() transition: Transition<any> | undefined
|
||||||
|
@Input() scriptAccounts: ScriptAccount[] = []
|
||||||
|
@Input() enableEditing: boolean = false;
|
||||||
|
|
||||||
|
dataSource: MatTableDataSource<ScriptAccountAction> = new MatTableDataSource();
|
||||||
|
displayedColumns: string[] = ['scriptAccount', "valueChange", 'edit', 'delete'];
|
||||||
|
|
||||||
|
editedAction: ScriptAccountAction | undefined
|
||||||
|
addedAction: ScriptAccountAction | undefined
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.dataSource.data = this.transition!.scriptAccountActions.map(action => action);
|
||||||
|
|
||||||
|
if(!this.enableEditing) {
|
||||||
|
this.displayedColumns = this.displayedColumns.slice(0, -2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editAction(scriptAccountAction: ScriptAccountAction) {
|
||||||
|
this.editedAction = scriptAccountAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
createNewAction() {
|
||||||
|
this.addedAction = new ScriptAccountAction(new ScriptAccount("", ""), 0);
|
||||||
|
this.editedAction = this.addedAction;
|
||||||
|
|
||||||
|
this.dataSource.data = this.dataSource.data.concat(this.addedAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
finishEditing() {
|
||||||
|
if(this.addedAction != undefined && this.addedAction.scriptAccount.componentName !== '') {
|
||||||
|
this.transition?.addScriptAccountAction(this.addedAction)
|
||||||
|
console.log(this.addedAction.scriptAccount)
|
||||||
|
this.dataSource.data = this.transition!.scriptAccountActions;
|
||||||
|
console.log(this.dataSource.data.length, this.transition!.scriptAccountActions.length)
|
||||||
|
this.addedAction = undefined;
|
||||||
|
}
|
||||||
|
this.editedAction = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteAction(action: ScriptAccountAction) {
|
||||||
|
this.transition!.removeScriptAccountAction(action.scriptAccount)
|
||||||
|
this.dataSource.data = this.transition!.scriptAccountActions
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,17 @@
|
|||||||
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
|
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
|
||||||
<div class="example-element-detail"
|
<div class="example-element-detail"
|
||||||
[@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
[@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||||
<p>Expanded Detail</p>
|
<div class="condition-action-container">
|
||||||
|
<div class="action-container">
|
||||||
|
<app-scriptaccount-action-editor [transition]="element" [scriptAccounts]="scriptAccounts" [enableEditing]="true"></app-scriptaccount-action-editor>
|
||||||
|
</div>
|
||||||
|
<div class="condition-container">
|
||||||
|
<app-scriptaccount-condition-editor [conditions]="element.scriptAccountConditions" [scriptAccounts]="scriptAccounts" [enableEditiong]="true"
|
||||||
|
(onCreateCondition)="onCreateCondition(element, $event)" (onDeleteCondition)="deleteCondition(element, $event)"></app-scriptaccount-condition-editor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@ -48,8 +58,8 @@
|
|||||||
<ng-container matColumnDef="edit">
|
<ng-container matColumnDef="edit">
|
||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let transition">
|
<td mat-cell *matCellDef="let transition">
|
||||||
<button mat-icon-button color="primary" *ngIf="editedTransition !== transition" [disabled]="editedTransition != undefined"><mat-icon>edit</mat-icon></button>
|
<button mat-icon-button class="icon-btn-primary" *ngIf="editedTransition !== transition" [disabled]="editedTransition != undefined"><mat-icon>edit</mat-icon></button>
|
||||||
<button mat-icon-button color="primary" *ngIf="editedTransition === transition"
|
<button mat-icon-button class="icon-btn-primary" *ngIf="editedTransition === transition"
|
||||||
[disabled]="transitionError || transitionStartingStateError || transitionEndingStateError" (click)="finishEditing()"
|
[disabled]="transitionError || transitionStartingStateError || transitionEndingStateError" (click)="finishEditing()"
|
||||||
><mat-icon>done</mat-icon></button>
|
><mat-icon>done</mat-icon></button>
|
||||||
</td>
|
</td>
|
||||||
|
@ -61,3 +61,16 @@ tr.example-element-row:not(.example-expanded-row):active {
|
|||||||
.mat-error {
|
.mat-error {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.condition-action-container {
|
||||||
|
display: flex;
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.condition-container {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-container {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
import {Component, Input, OnInit} from '@angular/core';
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
import {GameModel} from "../../../../game-model/GameModel";
|
|
||||||
import {SimpleGamesystem} from "../../../../game-model/gamesystems/SimpleGamesystem";
|
|
||||||
import {
|
import {
|
||||||
MatCell,
|
|
||||||
MatCellDef,
|
|
||||||
MatColumnDef,
|
|
||||||
MatHeaderCell,
|
|
||||||
MatHeaderCellDef, MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef,
|
|
||||||
MatTable,
|
|
||||||
MatTableDataSource
|
MatTableDataSource
|
||||||
} from "@angular/material/table";
|
} from "@angular/material/table";
|
||||||
import {SimpleTransition} from "../../../../game-model/gamesystems/SimpleTransition";
|
|
||||||
import {animate, state, style, transition, trigger} from "@angular/animations";
|
import {animate, state, style, transition, trigger} from "@angular/animations";
|
||||||
import {SimpleState} from "../../../../game-model/gamesystems/SimpleState";
|
import {SimpleGamesystem} from "../../../../project/game-model/gamesystems/SimpleGamesystem";
|
||||||
import {ProductTransition} from "../../../../game-model/gamesystems/ProductTransition";
|
import {ScriptAccount} from "../../../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGamesystemCalculator";
|
import {SimpleTransition} from "../../../../project/game-model/gamesystems/transitions/SimpleTransition";
|
||||||
|
import {SimpleState} from "../../../../project/game-model/gamesystems/states/SimpleState";
|
||||||
|
import {ScriptAccountCondition} from "../../../../project/game-model/gamesystems/conditions/ScriptAccountCondition";
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-simple-transition-editor',
|
selector: 'app-simple-transition-editor',
|
||||||
templateUrl: './simple-transition-editor.component.html',
|
templateUrl: './simple-transition-editor.component.html',
|
||||||
@ -31,6 +23,7 @@ import {LeafGamesystemCalculator} from "../../product-gamesystem-editor/LeafGame
|
|||||||
export class SimpleTransitionEditorComponent implements OnInit {
|
export class SimpleTransitionEditorComponent implements OnInit {
|
||||||
|
|
||||||
@Input() gamesystem: SimpleGamesystem | undefined
|
@Input() gamesystem: SimpleGamesystem | undefined
|
||||||
|
@Input() scriptAccounts: ScriptAccount[] = []
|
||||||
displayedColumns: string[] = ["starting-state", "ending-state", "edit", "delete"];
|
displayedColumns: string[] = ["starting-state", "ending-state", "edit", "delete"];
|
||||||
dataSource = new MatTableDataSource<SimpleTransition>();
|
dataSource = new MatTableDataSource<SimpleTransition>();
|
||||||
columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
|
columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
|
||||||
@ -49,6 +42,7 @@ export class SimpleTransitionEditorComponent implements OnInit {
|
|||||||
this.dataSource.filterPredicate = (data: SimpleTransition, filter: string) => {
|
this.dataSource.filterPredicate = (data: SimpleTransition, filter: string) => {
|
||||||
return [data.startingState, data.endingState].some((state) => state.stateLabel.toLowerCase().includes(filter))
|
return [data.startingState, data.endingState].some((state) => state.stateLabel.toLowerCase().includes(filter))
|
||||||
}
|
}
|
||||||
|
console.log("TransitionEditor: ", this.scriptAccounts.length)
|
||||||
}
|
}
|
||||||
|
|
||||||
addTransition() {
|
addTransition() {
|
||||||
@ -93,4 +87,14 @@ export class SimpleTransitionEditorComponent implements OnInit {
|
|||||||
const filterValue = (event.target as HTMLInputElement).value;
|
const filterValue = (event.target as HTMLInputElement).value;
|
||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected readonly transition = transition;
|
||||||
|
|
||||||
|
onCreateCondition(transition: SimpleTransition, condition: ScriptAccountCondition) {
|
||||||
|
transition.addScriptAccountCondition(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteCondition(trasition: SimpleTransition, condition: ScriptAccountCondition) {
|
||||||
|
trasition.removeScriptAccountCondition(condition.scriptAccount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||||
import {ModelComponent} from "../../game-model/ModelComponent";
|
|
||||||
import {FormControl, Validators} from "@angular/forms";
|
import {FormControl, Validators} from "@angular/forms";
|
||||||
|
import {ModelComponent} from "../../project/game-model/ModelComponent";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-model-component-editor',
|
selector: 'app-model-component-editor',
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<div *ngIf="scriptAccount != undefined">
|
<div *ngIf="scriptAccount != undefined">
|
||||||
<mat-form-field class="example-full-width">
|
<mat-form-field class="example-full-width">
|
||||||
<mat-label>MinValue</mat-label>
|
<mat-label>MinValue</mat-label>
|
||||||
<input matInput [formControl]="minCtrl" type="number" (keypress)="onKeyPress($event)" (change)="onUpdateMinValue()">
|
<input matInput [formControl]="minCtrl" type="number" (change)="onUpdateMinValue($event)">
|
||||||
<mat-error *ngIf="minCtrl.hasError('required')">Please enter a valid number!</mat-error>
|
<mat-error *ngIf="minCtrl.hasError('required')">Please enter a valid number!</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field class="example-full-width">
|
<mat-form-field class="example-full-width">
|
||||||
<mat-label>MaxValue</mat-label>
|
<mat-label>MaxValue</mat-label>
|
||||||
<input matInput type="number" [formControl]="maxCtrl" (keypress)="onKeyPress($event)" (change)="onUpdateMaxValue()">
|
<input matInput type="number" [formControl]="maxCtrl" (change)="onUpdateMaxValue()">
|
||||||
<mat-error *ngIf="maxCtrl.hasError('required')">Please enter a valid number!</mat-error>
|
<mat-error *ngIf="maxCtrl.hasError('required')">Please enter a valid number!</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import {Component, Input, OnInit} from '@angular/core';
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
import {ScriptAccount} from "../../game-model/scriptAccounts/ScriptAccount";
|
|
||||||
import {ModelComponent} from "../../game-model/ModelComponent";
|
|
||||||
import {MatFormField} from "@angular/material/form-field";
|
import {MatFormField} from "@angular/material/form-field";
|
||||||
import {MatInput} from "@angular/material/input";
|
import {MatInput} from "@angular/material/input";
|
||||||
import {FormControl, FormGroupDirective, FormsModule, NgForm, Validators} from "@angular/forms";
|
import {FormControl, FormGroupDirective, FormsModule, NgForm, Validators} from "@angular/forms";
|
||||||
import {NgIf} from "@angular/common";
|
import {NgIf} from "@angular/common";
|
||||||
import {ErrorStateMatcher} from "@angular/material/core";
|
import {ErrorStateMatcher} from "@angular/material/core";
|
||||||
import {ElectronService} from "../../core/services";
|
import {ElectronService} from "../../core/services";
|
||||||
|
import {ScriptAccount} from "../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
|
||||||
export class MyErrorStateMatcher implements ErrorStateMatcher {
|
export class MyErrorStateMatcher implements ErrorStateMatcher {
|
||||||
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
||||||
@ -22,8 +22,8 @@ export class MyErrorStateMatcher implements ErrorStateMatcher {
|
|||||||
export class ScriptAccountEditorComponent implements OnInit{
|
export class ScriptAccountEditorComponent implements OnInit{
|
||||||
@Input("scriptAccount") scriptAccount : ScriptAccount | undefined
|
@Input("scriptAccount") scriptAccount : ScriptAccount | undefined
|
||||||
|
|
||||||
minCtrl: FormControl = new FormControl(0, [Validators.required, Validators.pattern('^[0-9]*$')]);
|
minCtrl: FormControl = new FormControl(0, [Validators.required, Validators.pattern('^[-]?[0-9]*$')]);
|
||||||
maxCtrl: FormControl = new FormControl(100, [Validators.required, Validators.pattern('^[0-9]*$')]);
|
maxCtrl: FormControl = new FormControl(100, [Validators.required, Validators.pattern('^[-]?[0-9]*$')]);
|
||||||
matcher = new MyErrorStateMatcher();
|
matcher = new MyErrorStateMatcher();
|
||||||
|
|
||||||
constructor(private electronService: ElectronService) {
|
constructor(private electronService: ElectronService) {
|
||||||
@ -33,15 +33,8 @@ export class ScriptAccountEditorComponent implements OnInit{
|
|||||||
this.maxCtrl.setValue(this.scriptAccount!.maxValue);
|
this.maxCtrl.setValue(this.scriptAccount!.maxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeyPress(event: KeyboardEvent) {
|
|
||||||
const input = event.key;
|
|
||||||
const isDigit = /^\d+$/.test(input);
|
|
||||||
if (!isDigit) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onUpdateMinValue() {
|
onUpdateMinValue(event: Event) {
|
||||||
this.scriptAccount!.minValue = Number(this.minCtrl.value);
|
this.scriptAccount!.minValue = Number(this.minCtrl.value);
|
||||||
this.scriptAccount!.onModifyContent();
|
this.scriptAccount!.onModifyContent();
|
||||||
}
|
}
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import {SimpleGamesystem} from "../../gamesystems/SimpleGamesystem";
|
|
||||||
import {SimpleState} from "../../gamesystems/SimpleState";
|
|
||||||
import {SimpleTransition} from "../../gamesystems/SimpleTransition";
|
|
||||||
|
|
||||||
export class SimpleGamesystemParser {
|
|
||||||
|
|
||||||
static parseSimpleGamesystem(jsonObject: any) : SimpleGamesystem {
|
|
||||||
const gamesystemName = jsonObject.componentName;
|
|
||||||
const gamesystemDescription = jsonObject.componentDescription;
|
|
||||||
const simpleStates = SimpleGamesystemParser.parseSimpleStates(jsonObject)
|
|
||||||
const simpleTransitions = SimpleGamesystemParser.parseSimpleTransitions(jsonObject, simpleStates);
|
|
||||||
|
|
||||||
const gamesystem = new SimpleGamesystem(gamesystemName, gamesystemDescription);
|
|
||||||
gamesystem.states = simpleStates;
|
|
||||||
gamesystem.transitions = simpleTransitions;
|
|
||||||
|
|
||||||
return gamesystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
static parseSimpleStates(jsonObject: any): SimpleState[] {
|
|
||||||
const states: SimpleState[] = [];
|
|
||||||
for(let i=0; i<jsonObject.states.length; i++) {
|
|
||||||
const state = new SimpleState("", "");
|
|
||||||
Object.assign(state, jsonObject.states[i]);
|
|
||||||
states.push(state);
|
|
||||||
}
|
|
||||||
return states;
|
|
||||||
}
|
|
||||||
|
|
||||||
static parseSimpleTransitions(jsonObject: any, states: SimpleState[]): SimpleTransition[] {
|
|
||||||
const transitions: SimpleTransition[] = [];
|
|
||||||
for(let i=0; i<jsonObject.transitions.length; i++) {
|
|
||||||
const startingStateLabel = jsonObject.transitions[i].startingState;
|
|
||||||
const endingStateLabel = jsonObject.transitions[i].endingState;
|
|
||||||
|
|
||||||
const startingState = states.find(state => state.stateLabel === startingStateLabel);
|
|
||||||
const endingState = states.find(state => state.stateLabel === endingStateLabel);
|
|
||||||
|
|
||||||
if(startingState != undefined && endingState != undefined) {
|
|
||||||
transitions.push(new SimpleTransition(startingState, endingState));
|
|
||||||
} else {
|
|
||||||
console.error("Starting or Ending State are not defined!", startingState, endingState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transitions;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
import {Transition} from "./Transition";
|
|
||||||
|
|
||||||
export abstract class State<T extends Transition<any>> {
|
|
||||||
|
|
||||||
incomingTransitions: T[] =[];
|
|
||||||
outgoingTransitions: T[] =[];
|
|
||||||
|
|
||||||
initial: boolean = false;
|
|
||||||
|
|
||||||
addIncomingTransition(transition: T) {
|
|
||||||
this.incomingTransitions.push(transition);
|
|
||||||
}
|
|
||||||
|
|
||||||
addOutgoingTransition(transition: T) {
|
|
||||||
this.outgoingTransitions.push(transition);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeIncomingTransition(transition: T) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
removeOutgoingTransition(transition: T) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract equals(state: State<Transition<any>>): boolean;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
import {State} from "./State";
|
|
||||||
|
|
||||||
export abstract class Transition<S extends State<any>> {
|
|
||||||
startingState: S
|
|
||||||
endingState: S
|
|
||||||
|
|
||||||
|
|
||||||
constructor(startingState: S, endingState: S) {
|
|
||||||
this.startingState = startingState;
|
|
||||||
this.endingState = endingState;
|
|
||||||
|
|
||||||
this.startingState.addOutgoingTransition(this);
|
|
||||||
this.endingState.addIncomingTransition(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +1,34 @@
|
|||||||
import {Gamesystem} from "./gamesystems/Gamesystem";
|
import {Gamesystem} from "./gamesystems/Gamesystem";
|
||||||
import {ScriptAccount} from "./scriptAccounts/ScriptAccount";
|
import {ScriptAccount} from "./scriptAccounts/ScriptAccount";
|
||||||
import {Transition} from "./gamesystems/Transition";
|
import {Transition} from "./gamesystems/transitions/Transition";
|
||||||
import {State} from "./gamesystems/State";
|
import {State} from "./gamesystems/states/State";
|
||||||
import {ProductGamesystem} from "./gamesystems/ProductGamesystem";
|
import {ProductGamesystem} from "./gamesystems/ProductGamesystem";
|
||||||
import {SimpleGamesystem} from "./gamesystems/SimpleGamesystem";
|
import {SimpleGamesystem} from "./gamesystems/SimpleGamesystem";
|
||||||
import {StorageModel} from "./fs/StorageModel";
|
import {StorageModel} from "./fs/StorageModel";
|
||||||
|
|
||||||
export class GameModel {
|
export class GameModel {
|
||||||
private readonly _gameModelName: string
|
gameModelName: string
|
||||||
|
|
||||||
private _gamesystems: Gamesystem<any, any>[] = [];
|
gamesystems: Gamesystem<any, any>[] = [];
|
||||||
private _scriptAccounts: ScriptAccount[] = [];
|
scriptAccounts: ScriptAccount[] = [];
|
||||||
|
|
||||||
constructor(gameModelName: string) {
|
constructor(gameModelName: string) {
|
||||||
this._gameModelName = gameModelName;
|
this.gameModelName = gameModelName;
|
||||||
}
|
|
||||||
get gameModelName(): string {
|
|
||||||
return this._gameModelName;
|
|
||||||
}
|
|
||||||
get gamesystems(): Gamesystem<any, any>[] {
|
|
||||||
return this._gamesystems;
|
|
||||||
}
|
|
||||||
get scriptAccounts(): ScriptAccount[] {
|
|
||||||
return this._scriptAccounts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addGamesystem(gamesystem: Gamesystem<any, any>) {
|
addGamesystem(gamesystem: Gamesystem<any, any>) {
|
||||||
if(this.findGamesystem(gamesystem.componentName) == undefined) {
|
if(this.findGamesystem(gamesystem.componentName) == undefined) {
|
||||||
this._gamesystems.push(gamesystem);
|
this.gamesystems.push(gamesystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeGamesystem(gamesystem : Gamesystem<any, any>) {
|
removeGamesystem(gamesystem : Gamesystem<any, any>) {
|
||||||
this._gamesystems = this._gamesystems.filter(g => g !== gamesystem);
|
if(gamesystem.parentGamesystem == undefined) {
|
||||||
|
this.gamesystems = this.gamesystems.filter(g => g !== gamesystem);
|
||||||
|
} else {
|
||||||
|
(gamesystem.parentGamesystem as ProductGamesystem).removeChildGamesystem(gamesystem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createScriptAccount(scriptAccountName: string) {
|
createScriptAccount(scriptAccountName: string) {
|
||||||
@ -72,7 +67,7 @@ export class GameModel {
|
|||||||
|
|
||||||
removeScriptAccount(scriptAccount: ScriptAccount) {
|
removeScriptAccount(scriptAccount: ScriptAccount) {
|
||||||
if(scriptAccount != undefined) {
|
if(scriptAccount != undefined) {
|
||||||
this._scriptAccounts = this.scriptAccounts.filter(s => s != scriptAccount);
|
this.scriptAccounts = this.scriptAccounts.filter(s => s != scriptAccount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,4 +89,12 @@ export class GameModel {
|
|||||||
addScriptAccount(scriptAccount: ScriptAccount) {
|
addScriptAccount(scriptAccount: ScriptAccount) {
|
||||||
this.scriptAccounts.push(scriptAccount);
|
this.scriptAccounts.push(scriptAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateProductSystemContents() {
|
||||||
|
this.gamesystems.forEach(gamesystem => {
|
||||||
|
if(gamesystem instanceof ProductGamesystem) {
|
||||||
|
gamesystem.generateFromChildsystems();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
12
src/app/project/game-model/fs/DeleteModel.ts
Normal file
12
src/app/project/game-model/fs/DeleteModel.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import {ModelComponentType} from "../ModelComponentType";
|
||||||
|
|
||||||
|
export class DeleteModel {
|
||||||
|
componentName: string
|
||||||
|
modeltype: ModelComponentType
|
||||||
|
|
||||||
|
|
||||||
|
constructor(componentName: string, modeltype: ModelComponentType) {
|
||||||
|
this.componentName = componentName;
|
||||||
|
this.modeltype = modeltype;
|
||||||
|
}
|
||||||
|
}
|
@ -47,21 +47,23 @@ export class ProcessLoadedProject {
|
|||||||
console.log("Loaded Model should be an instance of recursivemodel")
|
console.log("Loaded Model should be an instance of recursivemodel")
|
||||||
if(parsedJsonString.hasOwnProperty('states') && parsedJsonString.hasOwnProperty('transitions')) {
|
if(parsedJsonString.hasOwnProperty('states') && parsedJsonString.hasOwnProperty('transitions')) {
|
||||||
//SimpleGamesystem
|
//SimpleGamesystem
|
||||||
const simpleGamesystem: SimpleGamesystem = SimpleGamesystemParser.parseSimpleGamesystem(parsedJsonString);
|
const simpleGamesystem: SimpleGamesystem = SimpleGamesystemParser.parseSimpleGamesystem(parsedJsonString, gameModel.scriptAccounts);
|
||||||
const parentModel: ProductGamesystem = gameModel.findGamesystem(recursiveLoadModel.parentLoadModelname) as ProductGamesystem
|
const parentModel: ProductGamesystem = gameModel.findGamesystem(recursiveLoadModel.parentLoadModelname) as ProductGamesystem
|
||||||
parentModel.addChildGamesystem(simpleGamesystem);
|
parentModel.addChildGamesystem(simpleGamesystem);
|
||||||
|
simpleGamesystem.parentGamesystem = parentModel
|
||||||
} else {
|
} else {
|
||||||
console.log("Gamesystems: ", )
|
console.log("Gamesystems: ", )
|
||||||
//ProductGamesystem
|
//ProductGamesystem
|
||||||
const productGamesystem: ProductGamesystem = ProductGamesystemParser.parseProductGamesystem(parsedJsonString);
|
const productGamesystem: ProductGamesystem = ProductGamesystemParser.parseProductGamesystem(parsedJsonString);
|
||||||
const parentModel: ProductGamesystem = gameModel.findGamesystem(recursiveLoadModel.parentLoadModelname) as ProductGamesystem;
|
const parentModel: ProductGamesystem = gameModel.findGamesystem(recursiveLoadModel.parentLoadModelname) as ProductGamesystem;
|
||||||
parentModel.addChildGamesystem(productGamesystem);
|
parentModel.addChildGamesystem(productGamesystem);
|
||||||
|
productGamesystem.parentGamesystem = parentModel
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Top Gamesystem
|
//Top Gamesystem
|
||||||
if(parsedJsonString.hasOwnProperty('states') && parsedJsonString.hasOwnProperty('transitions')) {
|
if(parsedJsonString.hasOwnProperty('states') && parsedJsonString.hasOwnProperty('transitions')) {
|
||||||
//SimpleGamesystem
|
//SimpleGamesystem
|
||||||
const simpleGamesystem: SimpleGamesystem = SimpleGamesystemParser.parseSimpleGamesystem(parsedJsonString);
|
const simpleGamesystem: SimpleGamesystem = SimpleGamesystemParser.parseSimpleGamesystem(parsedJsonString, gameModel.scriptAccounts);
|
||||||
gameModel.addGamesystem(simpleGamesystem);
|
gameModel.addGamesystem(simpleGamesystem);
|
||||||
} else {
|
} else {
|
||||||
//ProductGamesystem
|
//ProductGamesystem
|
@ -0,0 +1,95 @@
|
|||||||
|
import {SimpleGamesystem} from "../../gamesystems/SimpleGamesystem";
|
||||||
|
import {SimpleState} from "../../gamesystems/states/SimpleState";
|
||||||
|
import {SimpleTransition} from "../../gamesystems/transitions/SimpleTransition";
|
||||||
|
import {ScriptAccount} from "../../scriptAccounts/ScriptAccount";
|
||||||
|
import {ScriptAccountCondition} from "../../gamesystems/conditions/ScriptAccountCondition";
|
||||||
|
import {ScriptAccountAction} from "../../gamesystems/actions/ScriptAccountAction";
|
||||||
|
|
||||||
|
export class SimpleGamesystemParser {
|
||||||
|
|
||||||
|
static parseSimpleGamesystem(jsonObject: any, scriptAccounts: ScriptAccount[] = []) : SimpleGamesystem {
|
||||||
|
const gamesystemName = jsonObject.componentName;
|
||||||
|
const gamesystemDescription = jsonObject.componentDescription;
|
||||||
|
const simpleStates = SimpleGamesystemParser.parseSimpleStates(jsonObject, scriptAccounts)
|
||||||
|
const simpleTransitions = SimpleGamesystemParser.parseSimpleTransitions(jsonObject, simpleStates, scriptAccounts);
|
||||||
|
|
||||||
|
const gamesystem = new SimpleGamesystem(gamesystemName, gamesystemDescription);
|
||||||
|
gamesystem.states = simpleStates;
|
||||||
|
gamesystem.transitions = simpleTransitions;
|
||||||
|
|
||||||
|
return gamesystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static parseSimpleStates(jsonObject: any, scriptAccounts: ScriptAccount[] = []): SimpleState[] {
|
||||||
|
const states: SimpleState[] = [];
|
||||||
|
for(let i=0; i<jsonObject.states.length; i++) {
|
||||||
|
const state = new SimpleState(jsonObject.states[i].stateLabel, jsonObject.states[i].stateDescription);
|
||||||
|
const conditions = jsonObject.states[i].conditions
|
||||||
|
state.initial = jsonObject.states[i].initial
|
||||||
|
|
||||||
|
for(let j=0; j<conditions.length; j++) {
|
||||||
|
const searchedScriptAccount = scriptAccounts.find(scriptAccount => scriptAccount.componentName === conditions[j].scriptAccount)
|
||||||
|
if(searchedScriptAccount != undefined) {
|
||||||
|
const scriptAccountCondition =
|
||||||
|
ScriptAccountCondition.constructScriptAccountCondition(searchedScriptAccount, conditions[j].minValue, conditions[j].maxValue)
|
||||||
|
|
||||||
|
state.conditions.push(scriptAccountCondition!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states.push(state);
|
||||||
|
}
|
||||||
|
return states;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static parseSimpleTransitions(jsonObject: any, states: SimpleState[], scriptAccounts: ScriptAccount[]): SimpleTransition[] {
|
||||||
|
const transitions: SimpleTransition[] = [];
|
||||||
|
for(let i=0; i<jsonObject.transitions.length; i++) {
|
||||||
|
const startingStateLabel = jsonObject.transitions[i].startingState;
|
||||||
|
const endingStateLabel = jsonObject.transitions[i].endingState;
|
||||||
|
|
||||||
|
const startingState = states.find(state => state.stateLabel === startingStateLabel);
|
||||||
|
const endingState = states.find(state => state.stateLabel === endingStateLabel);
|
||||||
|
|
||||||
|
const actions: ScriptAccountAction[] = []
|
||||||
|
for(let j=0; j<jsonObject.transitions[i].scriptAccountActions.length; j++) {
|
||||||
|
const scriptAccountName = jsonObject.transitions[i].scriptAccountActions[j].scriptAccount
|
||||||
|
const referencedScriptAccount = scriptAccounts.find(scriptAccount => scriptAccount.componentName === scriptAccountName)
|
||||||
|
|
||||||
|
if(referencedScriptAccount != undefined) {
|
||||||
|
const scriptAccountAction = new ScriptAccountAction(referencedScriptAccount!, jsonObject.transitions[i].scriptAccountActions[j].changingValue)
|
||||||
|
actions.push(scriptAccountAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const conditions: ScriptAccountCondition[] = [];
|
||||||
|
for(let j=0; j<jsonObject.transitions[i].scriptAccountConditions.length; j++) {
|
||||||
|
const scriptAccountName = jsonObject.transitions[i].scriptAccountConditions[j].scriptAccount
|
||||||
|
const referencedScriptAccount = scriptAccounts.find(scriptAccount => scriptAccount.componentName === scriptAccountName)
|
||||||
|
|
||||||
|
if(referencedScriptAccount != undefined) {
|
||||||
|
const minValue = jsonObject.transitions[i].scriptAccountConditions[j].minValue
|
||||||
|
const maxValue = jsonObject.transitions[i].scriptAccountConditions[j].maxValue
|
||||||
|
|
||||||
|
const scriptAccountCondition =
|
||||||
|
ScriptAccountCondition.constructScriptAccountCondition(referencedScriptAccount, minValue, maxValue)
|
||||||
|
|
||||||
|
conditions.push(scriptAccountCondition!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(startingState != undefined && endingState != undefined) {
|
||||||
|
const simpleTransition = new SimpleTransition(startingState, endingState);
|
||||||
|
simpleTransition.scriptAccountActions = actions;
|
||||||
|
simpleTransition.scriptAccountConditions = conditions;
|
||||||
|
|
||||||
|
transitions.push(simpleTransition);
|
||||||
|
} else {
|
||||||
|
console.error("Starting or Ending State are not defined!", startingState, endingState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return transitions;
|
||||||
|
}
|
||||||
|
}
|
@ -53,7 +53,11 @@ export class StoreProject {
|
|||||||
return value.stateLabel
|
return value.stateLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key === 'incomingTransitions' || key === 'outgoingTransitions' || key === 'unsaved' || key === 'type') {
|
if(key === "scriptAccount") {
|
||||||
|
return value.componentName
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key === 'parentGamesystem' || key === 'incomingTransitions' || key === 'outgoingTransitions' || key === 'unsaved' || key === 'type') {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
return value;
|
return value;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user