Load Gamesystems from Filesystem
All checks were successful
E2E Testing / test (push) Successful in 1m34s

This commit is contained in:
Sebastian Böckelmann 2024-02-17 14:32:19 +01:00
parent e873688cb7
commit 3b0d4e0194
13 changed files with 223 additions and 32 deletions

12
app/RecursiveLoadModel.js Normal file
View File

@ -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

12
app/RecursiveLoadModel.ts Normal file
View File

@ -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;
}
}

View File

@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.SaveProject = void 0; exports.SaveProject = void 0;
const fs = require("fs"); const fs = require("fs");
const path = require("node:path"); const path = require("node:path");
const LoadModel_1 = require("./LoadModel");
const ModelComponentType_1 = require("../src/app/game-model/ModelComponentType"); const ModelComponentType_1 = require("../src/app/game-model/ModelComponentType");
const LoadedProject_1 = require("./LoadedProject"); const LoadedProject_1 = require("./LoadedProject");
const RecursiveLoadModel_1 = require("./RecursiveLoadModel");
class SaveProject { class SaveProject {
static saveProject(projectDir, storageModels) { static saveProject(projectDir, storageModels) {
if (!fs.existsSync(projectDir)) { if (!fs.existsSync(projectDir)) {
@ -29,7 +31,8 @@ class SaveProject {
}); });
} }
static loadProject(projectDir) { 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); return new LoadedProject_1.LoadedProject(path.basename(projectDir), loadedScriptAccounts);
} }
static loadScriptAccounts(projectDir) { static loadScriptAccounts(projectDir) {
@ -49,6 +52,49 @@ class SaveProject {
}); });
return loadedScriptAccounts; 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; exports.SaveProject = SaveProject;
//# sourceMappingURL=SaveProject.js.map //# sourceMappingURL=SaveProject.js.map

View File

@ -3,8 +3,8 @@ import * as fs from "fs";
import * as path from "node:path"; import * as path from "node:path";
import {LoadModel} from "./LoadModel"; import {LoadModel} from "./LoadModel";
import {ModelComponentType} from "../src/app/game-model/ModelComponentType"; import {ModelComponentType} from "../src/app/game-model/ModelComponentType";
import {BrowserWindow} from "electron";
import {LoadedProject} from "./LoadedProject"; import {LoadedProject} from "./LoadedProject";
import {RecursiveLoadModel} from "./RecursiveLoadModel";
export class SaveProject { export class SaveProject {
@ -33,8 +33,8 @@ export class SaveProject {
} }
static loadProject(projectDir: string) { 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); return new LoadedProject(path.basename(projectDir), loadedScriptAccounts);
} }
@ -60,4 +60,51 @@ export class SaveProject {
return loadedScriptAccounts; 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;
}
} }

View File

@ -16,13 +16,13 @@ export class ProductStateTrainer {
static PRODUCT_GAMESYSTEM_NAME = "Product Gamesystem"; static PRODUCT_GAMESYSTEM_NAME = "Product Gamesystem";
static givenFullProductGamesystemWithTwoStates() { 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_1 = letter_Gamesystem.createState(this.INNERSTATE_LETTER_1, "")!;
const letter_2 = letter_Gamesystem.createState(this.INNERSTATE_LETTER_2, "")!; 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_1 = number_gamesystem.createState(this.INNERSTATE_NUMBER_1, "")!;
const number_2 = number_gamesystem.createState(this.INNERSTATE_NUMBER_2, "")!; 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_1]));
productGamesystem.states.push(new ProductState( [letter_1, number_2])); productGamesystem.states.push(new ProductState( [letter_1, number_2]));

View File

@ -63,25 +63,6 @@ export class AppComponent implements OnInit{
electronService.ipcRenderer.on('open-project', (event: any, loadedProject: LoadedProject) => { electronService.ipcRenderer.on('open-project', (event: any, loadedProject: LoadedProject) => {
this.gameModel = ProcessLoadedProject.processLoadedProject(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 { } else {
console.log('Run in browser'); console.log('Run in browser');

View File

@ -50,7 +50,7 @@ export class GameModel {
createGamesystem(gamesystemName: string, parentGamesystemName: string | undefined) { createGamesystem(gamesystemName: string, parentGamesystemName: string | undefined) {
if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) { if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) {
const simpleGamesystem = new SimpleGamesystem(gamesystemName); const simpleGamesystem = new SimpleGamesystem(gamesystemName, "");
if(parentGamesystemName != undefined) { if(parentGamesystemName != undefined) {
const parentGamesystem = this.findGamesystem(parentGamesystemName); const parentGamesystem = this.findGamesystem(parentGamesystemName);
if(parentGamesystem instanceof SimpleGamesystem) { if(parentGamesystem instanceof SimpleGamesystem) {

View File

@ -3,6 +3,11 @@ import {LoadedProject} from "../../../../app/LoadedProject";
import {LoadModel} from "../../../../app/LoadModel"; import {LoadModel} from "../../../../app/LoadModel";
import {ModelComponentType} from "../ModelComponentType"; import {ModelComponentType} from "../ModelComponentType";
import {ScriptAccount} from "../scriptAccounts/ScriptAccount"; 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 { export class ProcessLoadedProject {
@ -25,6 +30,36 @@ export class ProcessLoadedProject {
} }
static processLoadedGamesystem(gameModel: GameModel, loadedModel: LoadModel) { 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);
}
}
} }
} }

View File

@ -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);
}
}

View File

@ -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<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;
}
}

View File

@ -7,8 +7,8 @@ export abstract class Gamesystem<S, T> extends ModelComponent{
states: S[] = []; states: S[] = [];
transitions: T[] = []; transitions: T[] = [];
constructor(gamesystemName: string) { constructor(gamesystemName: string, gamesystemDescription: string) {
super(gamesystemName, "", ModelComponentType.GAMESYTEM); super(gamesystemName, gamesystemDescription, ModelComponentType.GAMESYTEM);
} }
abstract createTransition(startingState: S, endingState: S): T|undefined; abstract createTransition(startingState: S, endingState: S): T|undefined;

View File

@ -14,7 +14,7 @@ export class ProductGamesystem extends Gamesystem<ProductState, ProductTransitio
parentGamesystem: ProductGamesystem | undefined parentGamesystem: ProductGamesystem | undefined
static constructFromSimpleGamesystem(simpleGamesystem: SimpleGamesystem, gameModel: GameModel) { static constructFromSimpleGamesystem(simpleGamesystem: SimpleGamesystem, gameModel: GameModel) {
const productGamesystem = new ProductGamesystem(simpleGamesystem.componentName); const productGamesystem = new ProductGamesystem(simpleGamesystem.componentName, simpleGamesystem.componentDescription);
const parentGamesystem = simpleGamesystem.parentGamesystem; const parentGamesystem = simpleGamesystem.parentGamesystem;
if(simpleGamesystem.states.length > 0) { if(simpleGamesystem.states.length > 0) {
@ -77,7 +77,7 @@ export class ProductGamesystem extends Gamesystem<ProductState, ProductTransitio
} }
static generateFromChildsystems(leftSystem: Gamesystem<any, any>, rightSystem: Gamesystem<any, any>, left_temp: boolean, integratedSystems: Gamesystem<any, any>[]) { static generateFromChildsystems(leftSystem: Gamesystem<any, any>, rightSystem: Gamesystem<any, any>, left_temp: boolean, integratedSystems: Gamesystem<any, any>[]) {
const productGamesystem = new ProductGamesystem("Temporary Gamesystem"); const productGamesystem = new ProductGamesystem("Temporary Gamesystem", "");
integratedSystems.forEach(integratedSystem => productGamesystem.addChildGamesystem(integratedSystem)); integratedSystems.forEach(integratedSystem => productGamesystem.addChildGamesystem(integratedSystem));
leftSystem.states.forEach(leftState => { leftSystem.states.forEach(leftState => {

View File

@ -10,6 +10,8 @@ export class SimpleGamesystem extends Gamesystem<SimpleState, SimpleTransition>
parentGamesystem: ProductGamesystem | undefined parentGamesystem: ProductGamesystem | undefined
createState(label: string, description: string): SimpleState | undefined { createState(label: string, description: string): SimpleState | undefined {
if(label == null) { if(label == null) {
return undefined; return undefined;