diff --git a/app/RecursiveLoadModel.js b/app/RecursiveLoadModel.js new file mode 100644 index 0000000..7599083 --- /dev/null +++ b/app/RecursiveLoadModel.js @@ -0,0 +1,12 @@ +"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 \ No newline at end of file diff --git a/app/RecursiveLoadModel.ts b/app/RecursiveLoadModel.ts new file mode 100644 index 0000000..1b9d251 --- /dev/null +++ b/app/RecursiveLoadModel.ts @@ -0,0 +1,12 @@ +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; + } +} diff --git a/app/SaveProject.js b/app/SaveProject.js index 5b32ad8..0e77adc 100644 --- a/app/SaveProject.js +++ b/app/SaveProject.js @@ -3,8 +3,10 @@ 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)) { @@ -29,7 +31,8 @@ class SaveProject { }); } static loadProject(projectDir) { - const loadedScriptAccounts = SaveProject.loadScriptAccounts(projectDir); + let loadedScriptAccounts = SaveProject.loadScriptAccounts(projectDir); + loadedScriptAccounts = loadedScriptAccounts.concat(SaveProject.loadGamesystems(projectDir)); return new LoadedProject_1.LoadedProject(path.basename(projectDir), loadedScriptAccounts); } static loadScriptAccounts(projectDir) { @@ -49,6 +52,49 @@ class SaveProject { }); 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 \ No newline at end of file diff --git a/app/SaveProject.ts b/app/SaveProject.ts index cfe06cd..7c010d3 100644 --- a/app/SaveProject.ts +++ b/app/SaveProject.ts @@ -3,8 +3,8 @@ import * as fs from "fs"; import * as path from "node:path"; import {LoadModel} from "./LoadModel"; import {ModelComponentType} from "../src/app/game-model/ModelComponentType"; -import {BrowserWindow} from "electron"; import {LoadedProject} from "./LoadedProject"; +import {RecursiveLoadModel} from "./RecursiveLoadModel"; export class SaveProject { @@ -33,8 +33,8 @@ export class SaveProject { } static loadProject(projectDir: string) { - const loadedScriptAccounts: LoadModel[] = SaveProject.loadScriptAccounts(projectDir) - + let loadedScriptAccounts: LoadModel[] = SaveProject.loadScriptAccounts(projectDir) + loadedScriptAccounts = loadedScriptAccounts.concat(SaveProject.loadGamesystems(projectDir)) return new LoadedProject(path.basename(projectDir), loadedScriptAccounts); } @@ -60,4 +60,51 @@ export class SaveProject { 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; + } + } diff --git a/e2e/game-model/gamesystems/productGamesystems/ProductStateTrainer.ts b/e2e/game-model/gamesystems/productGamesystems/ProductStateTrainer.ts index a0d09a4..e473f9f 100644 --- a/e2e/game-model/gamesystems/productGamesystems/ProductStateTrainer.ts +++ b/e2e/game-model/gamesystems/productGamesystems/ProductStateTrainer.ts @@ -16,13 +16,13 @@ export class ProductStateTrainer { static PRODUCT_GAMESYSTEM_NAME = "Product Gamesystem"; static givenFullProductGamesystemWithTwoStates() { - const letter_Gamesystem = new SimpleGamesystem(this.LETTERS_GAMESYSTEM_NAME); + const letter_Gamesystem = new SimpleGamesystem(this.LETTERS_GAMESYSTEM_NAME, ""); const letter_1 = letter_Gamesystem.createState(this.INNERSTATE_LETTER_1, "")!; const letter_2 = letter_Gamesystem.createState(this.INNERSTATE_LETTER_2, "")!; - const number_gamesystem = new SimpleGamesystem(this.NUMBERS_GAMESYSTEM_NAME); + const number_gamesystem = new SimpleGamesystem(this.NUMBERS_GAMESYSTEM_NAME, ""); const number_1 = number_gamesystem.createState(this.INNERSTATE_NUMBER_1, "")!; const number_2 = number_gamesystem.createState(this.INNERSTATE_NUMBER_2, "")!; - const productGamesystem = new ProductGamesystem(this.PRODUCT_GAMESYSTEM_NAME); + const productGamesystem = new ProductGamesystem(this.PRODUCT_GAMESYSTEM_NAME, ""); productGamesystem.states.push(new ProductState( [letter_1, number_1])); productGamesystem.states.push(new ProductState( [letter_1, number_2])); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 012ba8f..2c24f78 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -63,25 +63,6 @@ export class AppComponent implements OnInit{ electronService.ipcRenderer.on('open-project', (event: any, loadedProject: LoadedProject) => { this.gameModel = ProcessLoadedProject.processLoadedProject(loadedProject) - const weather = new SimpleGamesystem("Weather"); - const season = new SimpleGamesystem("Season"); - - const springState = season.createState("Spring", "Spring, also known as springtime, is one of the four temperate seasons, succeeding winter and preceding summer."); - const summerState = season.createState("Summer", "Summer is the hottest and brightest of the four temperate seasons, occurring after spring and before autumn. "); - - const sunnyState = weather.createState("Sunny", "The sun is shining. No clouds, no rain, no storm."); - const rainingState = weather.createState("Raining", "It rains") - - season.createTransition(springState!, summerState!); - weather.createTransition(sunnyState!, rainingState!); - - const weather_season = new ProductGamesystem("Weather-Season"); - weather_season.addChildGamesystem(weather); - weather_season.addChildGamesystem(season); - - weather_season.createState([springState!, sunnyState!]); - - this.gameModel.addGamesystem(weather_season); }) } else { console.log('Run in browser'); diff --git a/src/app/game-model/GameModel.ts b/src/app/game-model/GameModel.ts index 0b1a189..487f53f 100644 --- a/src/app/game-model/GameModel.ts +++ b/src/app/game-model/GameModel.ts @@ -50,7 +50,7 @@ export class GameModel { createGamesystem(gamesystemName: string, parentGamesystemName: string | undefined) { if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) { - const simpleGamesystem = new SimpleGamesystem(gamesystemName); + const simpleGamesystem = new SimpleGamesystem(gamesystemName, ""); if(parentGamesystemName != undefined) { const parentGamesystem = this.findGamesystem(parentGamesystemName); if(parentGamesystem instanceof SimpleGamesystem) { diff --git a/src/app/game-model/fs/ProcessLoadedProject.ts b/src/app/game-model/fs/ProcessLoadedProject.ts index 3aca7ac..0d379df 100644 --- a/src/app/game-model/fs/ProcessLoadedProject.ts +++ b/src/app/game-model/fs/ProcessLoadedProject.ts @@ -3,6 +3,11 @@ import {LoadedProject} from "../../../../app/LoadedProject"; import {LoadModel} from "../../../../app/LoadModel"; import {ModelComponentType} from "../ModelComponentType"; import {ScriptAccount} from "../scriptAccounts/ScriptAccount"; +import {RecursiveLoadModel} from "../../../../app/RecursiveLoadModel"; +import {SimpleGamesystemParser} from "./parser/SimpleGamesystemParser"; +import {SimpleGamesystem} from "../gamesystems/SimpleGamesystem"; +import {ProductGamesystem} from "../gamesystems/ProductGamesystem"; +import {ProductGamesystemParser} from "./parser/ProductGamesystemParser"; export class ProcessLoadedProject { @@ -25,6 +30,36 @@ export class ProcessLoadedProject { } static processLoadedGamesystem(gameModel: GameModel, loadedModel: LoadModel) { - + const parsedJsonString = JSON.parse(loadedModel.jsonString); + if(loadedModel.hasOwnProperty('parentLoadModelname')) { + const recursiveLoadModel = loadedModel as RecursiveLoadModel + console.log("Loaded Model should be an instance of recursivemodel") + if(parsedJsonString.hasOwnProperty('states') && parsedJsonString.hasOwnProperty('transitions')) { + //SimpleGamesystem + const simpleGamesystem: SimpleGamesystem = SimpleGamesystemParser.parseSimpleGamesystem(parsedJsonString); + const parentModel: ProductGamesystem = gameModel.findGamesystem(recursiveLoadModel.parentLoadModelname) as ProductGamesystem + parentModel.addChildGamesystem(simpleGamesystem); + } else { + console.log("Gamesystems: ", ) + //ProductGamesystem + const productGamesystem: ProductGamesystem = ProductGamesystemParser.parseProductGamesystem(parsedJsonString); + const parentModel: ProductGamesystem = gameModel.findGamesystem(recursiveLoadModel.parentLoadModelname) as ProductGamesystem; + parentModel.addChildGamesystem(productGamesystem); + } + } else { + //Top Gamesystem + if(parsedJsonString.hasOwnProperty('states') && parsedJsonString.hasOwnProperty('transitions')) { + //SimpleGamesystem + const simpleGamesystem: SimpleGamesystem = SimpleGamesystemParser.parseSimpleGamesystem(parsedJsonString); + gameModel.addGamesystem(simpleGamesystem); + } else { + //ProductGamesystem + const productGamesystem = ProductGamesystemParser.parseProductGamesystem(parsedJsonString); + console.log("Generated Productsystem: ", productGamesystem) + gameModel.addGamesystem(productGamesystem); + } + } } + + } diff --git a/src/app/game-model/fs/parser/ProductGamesystemParser.ts b/src/app/game-model/fs/parser/ProductGamesystemParser.ts new file mode 100644 index 0000000..612f7bd --- /dev/null +++ b/src/app/game-model/fs/parser/ProductGamesystemParser.ts @@ -0,0 +1,9 @@ +import {ProductGamesystem} from "../../gamesystems/ProductGamesystem"; + +export class ProductGamesystemParser { + static parseProductGamesystem(jsonObject: any): ProductGamesystem { + const componentName = jsonObject.componentName; + const componentDescript = jsonObject.componentDescription; + return new ProductGamesystem(componentName, componentDescript); + } +} diff --git a/src/app/game-model/fs/parser/SimpleGamesystemParser.ts b/src/app/game-model/fs/parser/SimpleGamesystemParser.ts new file mode 100644 index 0000000..b36c282 --- /dev/null +++ b/src/app/game-model/fs/parser/SimpleGamesystemParser.ts @@ -0,0 +1,47 @@ +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 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; + } +} diff --git a/src/app/game-model/gamesystems/Gamesystem.ts b/src/app/game-model/gamesystems/Gamesystem.ts index a1f0d5c..e182c25 100644 --- a/src/app/game-model/gamesystems/Gamesystem.ts +++ b/src/app/game-model/gamesystems/Gamesystem.ts @@ -7,8 +7,8 @@ export abstract class Gamesystem extends ModelComponent{ states: S[] = []; transitions: T[] = []; - constructor(gamesystemName: string) { - super(gamesystemName, "", ModelComponentType.GAMESYTEM); + constructor(gamesystemName: string, gamesystemDescription: string) { + super(gamesystemName, gamesystemDescription, ModelComponentType.GAMESYTEM); } abstract createTransition(startingState: S, endingState: S): T|undefined; diff --git a/src/app/game-model/gamesystems/ProductGamesystem.ts b/src/app/game-model/gamesystems/ProductGamesystem.ts index ecef1d3..b81b194 100644 --- a/src/app/game-model/gamesystems/ProductGamesystem.ts +++ b/src/app/game-model/gamesystems/ProductGamesystem.ts @@ -14,7 +14,7 @@ export class ProductGamesystem extends Gamesystem 0) { @@ -77,7 +77,7 @@ export class ProductGamesystem extends Gamesystem, rightSystem: Gamesystem, left_temp: boolean, integratedSystems: Gamesystem[]) { - const productGamesystem = new ProductGamesystem("Temporary Gamesystem"); + const productGamesystem = new ProductGamesystem("Temporary Gamesystem", ""); integratedSystems.forEach(integratedSystem => productGamesystem.addChildGamesystem(integratedSystem)); leftSystem.states.forEach(leftState => { diff --git a/src/app/game-model/gamesystems/SimpleGamesystem.ts b/src/app/game-model/gamesystems/SimpleGamesystem.ts index e9e73b0..d5b4f1f 100644 --- a/src/app/game-model/gamesystems/SimpleGamesystem.ts +++ b/src/app/game-model/gamesystems/SimpleGamesystem.ts @@ -10,6 +10,8 @@ export class SimpleGamesystem extends Gamesystem parentGamesystem: ProductGamesystem | undefined + + createState(label: string, description: string): SimpleState | undefined { if(label == null) { return undefined;