package gameEngine; import algorithms.TypeInference; import gameEngine.entites.EditorEntity; import gameEngine.entites.Entity; import gameEngine.entites.editorComponents.EntityView; import gameEngine.geometry.Transform; import gameEngine.scenes.EditorScene; import gameEngine.scenes.Scene; import gameEngine.views.Window; import models.algebra.Constant; import models.algebra.Expression; import models.algebra.Variable; import models.dataConstraintModel.*; import models.dataFlowModel.DataTransferChannel; import models.dataFlowModel.DataTransferModel; import parser.Parser; import parser.Parser.TokenStream; import parser.exceptions.*; import simulator.Event; import simulator.ResourceIdentifier; import simulator.Simulator; import gameEngine.simulator.interfaces.GameEnginePresenter; import simulator.SystemState; import simulator.interfaces.timers.TimerService; import javax.xml.crypto.Data; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class GameEngineModelFileGenerator { private DataTransferModel model; private final String modelFilePath = "GameEngine/resources/"; Parser.TokenStream stream = new Parser.TokenStream(); Parser parser = new Parser(stream); public void generate(){ try { EditorScene editorScene = (EditorScene) Window.get().getScene(); model = new DataTransferModel(); ResourcePath scene = new ResourcePath("scene"); // "scene" ResourcePath scene_time = new ResourcePath(scene, "time"); // "scene.time" ResourcePath scene_camera = new ResourcePath(scene, "camera"); // "scene.camera" ResourcePath scene_camera_transform = new ResourcePath(scene_camera, "transform"); // "scene.camera.transform" ResourcePath scene_camera_transform_position = new ResourcePath(scene_camera_transform, "position"); // "scene.camera.transform.position" ResourcePath scene_camera_transform_rotation = new ResourcePath(scene_camera_transform, "rotation"); // "scene.camera.transform.rotation" ResourcePath scene_camera_transform_scale = new ResourcePath(scene_camera_transform, "scale"); // "scene.camera.transform.scale" ResourcePath scene_camera_projection = new ResourcePath(scene_camera, "projection"); // "scene.camera.projection" ResourcePath entities = new ResourcePath(scene, "entities"); // "scene.entities" ResourcePath entity = new ResourcePath(entities, new Variable("eid", DataConstraintModel.typeString)); // "scene.entities.{eid}" ResourcePath entity_transform = new ResourcePath(entity, "transform"); // "scene.entities.{eid}.transform" ResourcePath entity_transform_position = new ResourcePath(entity_transform, "position"); // "scene.entities.{eid}.transform.position" ResourcePath entity_transform_rotation = new ResourcePath(entity_transform, "rotation"); // "scene.entities.{eid}.transform.rotation" ResourcePath entity_transform_scale = new ResourcePath(entity_transform, "scale"); // "scene.entities.{eid}.transform.scale" ResourcePath entity_mesh = new ResourcePath(entity, "mesh"); // "scene.entities.{eid}.mesh" ResourcePath keys = new ResourcePath(scene, "keys"); // "scene.keys" ResourcePath key = new ResourcePath(keys, new Variable("kno", DataConstraintModel.typeInt)); // "scene.keys.{kno}" ResourcePath key_state = new ResourcePath(key, "state"); // "scene.keys.{kno}.state ResourcePath timers = new ResourcePath("timers"); // "timers" ResourcePath timer = new ResourcePath(timers, new Variable("tid", DataConstraintModel.typeString)); // "timers.{tid}" ResourcePath timer_count = new ResourcePath(timer, "count"); //"timer.{tid}.count List<ResourcePath> enemy = new ArrayList<>(); List<ResourcePath> enemy_transform = new ArrayList<>(); List<ResourcePath> enemy_transform_position = new ArrayList<>(); List<ResourcePath> enemy_transform_rotation = new ArrayList<>(); List<ResourcePath> enemy_move = new ArrayList<>(); List<ResourcePath> enemy_move_type = new ArrayList<>(); List<ResourcePath> enemy_move_speed = new ArrayList<>(); List<ResourcePath> enemy_eid = new ArrayList<>(); for (int i = 1; i < editorScene.editorEntities.size(); i++) { EditorEntity editorEntity = (EditorEntity) editorScene.getEditorEntity("" + i); String id = editorEntity.getId(); ResourcePath e = new ResourcePath("enemy" + id); ResourcePath et = new ResourcePath(e, "transform"); ResourcePath etp = new ResourcePath(et, "position"); ResourcePath etr = new ResourcePath(et, "rotation"); ResourcePath em = new ResourcePath(e,"move"); ResourcePath emt = new ResourcePath(em,"type"); ResourcePath ems = new ResourcePath(em,"speed"); ResourcePath eid = new ResourcePath(e, "eid"); enemy.add(e); enemy_transform.add(et); enemy_transform_position.add(etp); enemy_transform_rotation.add(etr); enemy_move.add(em); enemy_move_type.add(emt); enemy_move_speed.add(ems); enemy_eid.add(eid); } model.addResourcePath(scene_time); model.addResourcePath(scene_camera); model.addResourcePath(scene_camera_transform); model.addResourcePath(scene_camera_transform_position); model.addResourcePath(scene_camera_transform_rotation); model.addResourcePath(scene_camera_transform_scale); model.addResourcePath(scene_camera_projection); model.addResourcePath(entity_transform); model.addResourcePath(entity_transform_position); model.addResourcePath(entity_transform_rotation); model.addResourcePath(entity_transform_scale); model.addResourcePath(entity_mesh); model.addResourcePath(key_state); model.addResourcePath(timers); model.addResourcePath(timer_count); for (ResourcePath et : enemy_transform) model.addResourcePath(et); for (ResourcePath etp : enemy_transform) model.addResourcePath(etp); for (ResourcePath etr : enemy_transform) model.addResourcePath(etr); for (ResourcePath em : enemy_transform) model.addResourcePath(em); for (ResourcePath emt : enemy_transform) model.addResourcePath(emt); for (ResourcePath ems : enemy_transform) model.addResourcePath(ems); addInit(); addNativeChannel( new DataTransferChannel("SceneUpdateEvent"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, scene_time, "time: Long", "updateEvent(dt: Long)", "time + dt" ) ); addNativeChannel( new DataTransferChannel("SceneUpdate"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, scene, "curSc: Json", "update(curSc, nextSc)", "nextSc" ) ); addNativeChannel( new DataTransferChannel("CameraPositionUpdate"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, scene_camera_transform_position, "curPos: Json", "updatePosition(nextPos.x, nextPos.y, nextPos.z)", "nextPos" ) ); addNativeChannel( new DataTransferChannel("CameraRotationUpdate"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, scene_camera_transform_rotation, "curRot: Json", "updateRotation(nextRot.x, nextRot.y, nextRot.z)", "nextRot" ) ); addNativeChannel( new DataTransferChannel("CameraScaleUpdate"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, scene_camera_transform_scale, "curScale: Json", "updateScale(nextScale.x, nextScale.y, nextScale.z)", "nextScale" ) ); addNativeChannel( new DataTransferChannel("CameraProjectionUpdate"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, scene_camera_projection, "curProj: Json", "updateProjection(curProj, nextProj)", "nextProj" ) ); addNativeChannel( new DataTransferChannel("EntityPositionUpdate", new Variable("eid", DataConstraintModel.typeString)), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, entity_transform_position, "curPos: Json", "updatePosition(nextPos.x, nextPos.y, nextPos.z)", "nextPos" ) ); addNativeChannel( new DataTransferChannel("EntityRotationUpdate", new Variable("eid", DataConstraintModel.typeString)), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, entity_transform_rotation, "curRot: Json", "updateRotation(nextRot.x, nextRot.y, nextRot.z)", "nextRot" ) ); addNativeChannel( new DataTransferChannel("EntityScaleUpdate", new Variable("eid", DataConstraintModel.typeString)), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, entity_transform_scale, "curScale: Json", "updateScale(nextScale.x, nextScale.y, nextScale.z)", "nextScale" ) ); addNativeChannel( new DataTransferChannel("EntitySpriteUpdate", new Variable("eid", DataConstraintModel.typeString)), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, entity_mesh, "curMesh: Json", "updateSprite(spritePath: Str)", "{\"type\": \"sprite\", \"sprite\": spritePath}" ) ); addNativeChannel( new DataTransferChannel("KeyEvent", new Variable("kno", DataConstraintModel.typeInt)), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, key_state, "curState: Int", "keyEvent(nextState)", "nextState" ) ); addNativeChannel( new DataTransferChannel("TimersUpdated"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, timers, "curTimers: Map", "update(curTimers, nextTimers)", "nextTimers" ) ); addNativeChannel( new DataTransferChannel("TimerEvent", new Variable("tid", DataConstraintModel.typeString)), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, timer_count, "count: Long", "tick()", "count + 1" ) ); addChannel( new DataTransferChannel("UpdateCameraPosition"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, scene_camera_transform_position, "curPos: Json", "updateCameraPosition(x: Double, y: Double, z: Double)", "{\"x\": x, \"y\": y, \"z\": z}") ); for (int i = 1; i < editorScene.editorEntities.size(); i++) { EditorEntity editorEntity = (EditorEntity) editorScene.getEditorEntity("" + i); String id = editorEntity.getId(); if (editorEntity.getEditorComponent(EntityView.class) != null) { addChannel( new DataTransferChannel("UpdateEnemy" + id, new Variable("tid", DataConstraintModel.typeString)), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, timer_count, "curCount: Long", "updateEnemy" + id + "(type, speed)", "nextCount"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Ref, enemy_move_type.get(i - 1), "type: Str", "updateEnemy" + id + "(type, speed)"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Ref, enemy_move_speed.get(i - 1), "speed: Float", "updateEnemy" + id + "(type, speed)"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, enemy_transform_position.get(i - 1), "curPos: Json", "updateEnemy" + id + "(type, speed)", "{\"x\": curPos.x, \"y\": curPos.y + speed, \"z\": curPos.z}") ); addChannel( new DataTransferChannel("MoveEnemy" + id), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, enemy_transform_position.get(i - 1), "curPos: Json", "moveEnemy" + id + "(nextPos, eid)", "nextPos"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Ref, enemy_eid.get(i - 1), "eid", "moveEnemy" + id + "(nextPos, eid)"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, entity_transform_position, "curPos: Json", "moveEnemy" + id + "(nextPos, eid)", "nextPos") ); addChannel( new DataTransferChannel("RotateEnemy" + id), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.In, enemy_transform_rotation.get(i - 1), "curRot: Json", "rotateEnemy" + id + "(nextRot, eid)", "nextRot"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Ref, enemy_eid.get(i - 1), "eid", "rotateEnemy" + id + "(nextRot, eid)"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, entity_transform_rotation, "curRot: Json", "rotateEnemy" + id + "(nextRot, eid)", "nextRot") ); } } DataTransferChannel startTimerChannel = addChannel( new DataTransferChannel("StartTimer"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, timers, "timers: Map", "startTimer(tid: Str, interval: Long)", "insert(timers, tid, {\"interval\": interval, \"count\": 0})") ); addChannel( new DataTransferChannel("ClearTimer"), new ChannelMemberDefinition( ChannelMemberDefinition.ChannelMemberType.Out, timers, "timers: Map", "clearTimer(tid: Str)", "delete(timers, tid)") ); if (stream.hasNext()) stream.next(); save(); TypeInference.infer(model); Simulator simulator = new Simulator(model); Window window = Window.get(); window.changeScene(2); GameEnginePresenter presenter = new GameEnginePresenter(window.getScene(), simulator); TimerService timerService = new TimerService(simulator); SystemState initialState = simulator.init(); stream.addLine("startTimer(\"000\", 100)"); Expression messageStartTimer = parser.parseTerm(stream, model); Event startTimer = new Event(startTimerChannel, messageStartTimer, timer, initialState.getResource(ResourceIdentifier.createFrom(timer))); simulator.transition(startTimer); } catch (Exception e) { e.printStackTrace(); } } private JsonTerm createTransformTerm(Transform transform){ JsonTerm positionTerm = new JsonTerm(); positionTerm.addMember("x", new Constant(String.valueOf(transform.position.x))); positionTerm.addMember("y", new Constant(String.valueOf(transform.position.y))); positionTerm.addMember("z", new Constant(String.valueOf(transform.position.z))); JsonTerm rotationTerm = new JsonTerm(); rotationTerm.addMember("x", new Constant(String.valueOf(transform.rotation.x))); rotationTerm.addMember("y", new Constant(String.valueOf(transform.rotation.y))); rotationTerm.addMember("z", new Constant(String.valueOf(transform.rotation.z))); JsonTerm scaleTerm = new JsonTerm(); scaleTerm.addMember("x", new Constant(String.valueOf(transform.scale.x))); scaleTerm.addMember("y", new Constant(String.valueOf(transform.scale.y))); scaleTerm.addMember("z", new Constant(String.valueOf(transform.scale.z))); JsonTerm transformTerm = new JsonTerm(); transformTerm.addMember("position", positionTerm); transformTerm.addMember("rotation", rotationTerm); transformTerm.addMember("scale", scaleTerm); return transformTerm; } public JsonTerm createEnemyJsonTerm(Entity entity){ EditorEntity editorEntity = (EditorEntity) entity; JsonTerm moveTerm = new JsonTerm(); JsonTerm meshTerm = new JsonTerm(); JsonTerm enemyTerm = new JsonTerm(); enemyTerm.addMember("transform", createTransformTerm(entity.transform)); enemyTerm.addMember("eid", new Constant(entity.getId(), DataConstraintModel.typeString)); for(EditorEntity.Connectiontype connectionType: editorEntity.ComponentConnections) { if (connectionType == EditorEntity.Connectiontype.Mesh) { meshTerm.addMember("type", new Constant("sprite", DataConstraintModel.typeString)); meshTerm.addMember("sprite", new Constant(Window.resourcePath + "enemy1.png", DataConstraintModel.typeString)); enemyTerm.addMember("mesh", meshTerm); } if (connectionType == EditorEntity.Connectiontype.Move) { moveTerm.addMember("type", new Constant("straight")); moveTerm.addMember("speed", new Constant(String.valueOf(5.0))); enemyTerm.addMember("move", moveTerm); } } return enemyTerm; } public JsonTerm createPlayerJsonTerm(){ JsonTerm meshTerm = new JsonTerm(); meshTerm.addMember("type", new Constant("sprite", DataConstraintModel.typeString)); meshTerm.addMember("sprite", new Constant(Window.resourcePath + "enemy1.png", DataConstraintModel.typeString)); JsonTerm playerTerm = new JsonTerm(); playerTerm.addMember("transform", createTransformTerm(new Transform())); playerTerm.addMember("mesh", meshTerm); return playerTerm; } // public JsonTerm createSceneTerm(){ // // // } private void addInit() { EditorScene editorScene = (EditorScene) Window.get().getScene(); ResourceHierarchy playerHierarchy = new ResourceHierarchy("player", DataConstraintModel.typeJson); playerHierarchy = model.getOrPutResourceHierarchy(playerHierarchy); JsonTerm playerRightTerm = createPlayerJsonTerm(); playerHierarchy.setInitialValue(playerRightTerm); playerHierarchy.setInitText(playerRightTerm.toString()); ResourceHierarchy sceneHierarchy = new ResourceHierarchy("scene", DataConstraintModel.typeJson); sceneHierarchy = model.getOrPutResourceHierarchy(sceneHierarchy); JsonTerm entitiesTerm = new JsonTerm(); // 0番はカメラのため for (int i = 1; i < editorScene.editorEntities.size(); i++) { EditorEntity editorEntity = (EditorEntity) editorScene.getEditorEntity("" + i); if(editorEntity.getEditorComponent(EntityView.class) != null) { ResourceHierarchy enemyHierarchy = new ResourceHierarchy("enemy" + editorScene.getEditorEntity("" + i).getId(), DataConstraintModel.typeJson); enemyHierarchy = model.getOrPutResourceHierarchy(enemyHierarchy); JsonTerm enemyTerm = createEnemyJsonTerm(editorScene.getEditorEntity("" + i)); entitiesTerm.addMember(editorScene.getEditorEntity("" + i).getId() ,enemyTerm); enemyHierarchy.setInitialValue(enemyTerm); enemyHierarchy.setInitText(enemyTerm.toString()); } } JsonTerm sceneTerm = new JsonTerm(); sceneTerm.addMember("entities", entitiesTerm); sceneHierarchy.setInitialValue(sceneTerm); sceneHierarchy.setInitText(sceneTerm.toString()); } public void save() { String outputFileName = modelFilePath + File.separator + "GameEngineTest.model"; try { File file = new File(outputFileName); FileWriter fileWriter = new FileWriter(file); fileWriter.write(model.getSourceText()); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } public DataTransferChannel addNativeChannel(DataTransferChannel dataTransferChannel, ChannelMemberDefinition... definitions) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { dataTransferChannel.setNative(true); return addChannel(dataTransferChannel, definitions); } public DataTransferChannel addChannel(DataTransferChannel dataTransferChannel, ChannelMemberDefinition... definitions) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { DataTransferChannel channel = dataTransferChannel; boolean hasInputChannel = false; for (ChannelMemberDefinition def : definitions) { if (def.channelType == ChannelMemberDefinition.ChannelMemberType.Out) { ChannelMember member = addChannelMember(stream, parser, def.path, def.curStateName, def.messageName, def.nextStateName); channel.addChannelMemberAsOutput(member); } else if (def.channelType == ChannelMemberDefinition.ChannelMemberType.In) { ChannelMember member = addChannelMember(stream, parser, def.path, def.curStateName, def.messageName, def.nextStateName); channel.addChannelMemberAsInput(member); hasInputChannel = true; } else if (def.channelType == ChannelMemberDefinition.ChannelMemberType.Ref){ ChannelMember member = addChannelMember(stream, parser, def.path, def.curStateName, def.messageName); channel.addChannelMemberAsReference(member); } } if(hasInputChannel) model.addChannel(channel); else model.addInputChannel(channel); return channel; } //inが一つでもあればInputChannel private ChannelMember addChannelMember(TokenStream stream, Parser parser, ResourcePath path, String curStateName, String messageName, String nextStateName) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { ChannelMember member = new ChannelMember(path); stream.addLine(curStateName); Expression curState = parser.parseTerm(stream, model); stream.addLine(messageName); Expression message = parser.parseTerm(stream, model); stream.addLine(nextStateName); Expression nextState = parser.parseTerm(stream, model); member.getStateTransition().setCurStateExpression(curState); member.getStateTransition().setMessageExpression(message); member.getStateTransition().setNextStateExpression(nextState); return member; } private ChannelMember addChannelMember(TokenStream stream, Parser parser, ResourcePath path, String curStateName, String messageName) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { ChannelMember member = new ChannelMember(path); stream.addLine(curStateName); Expression curState = parser.parseTerm(stream, model); stream.addLine(messageName); Expression message = parser.parseTerm(stream, model); member.getStateTransition().setCurStateExpression(curState); member.getStateTransition().setMessageExpression(message); return member; } public class ChannelMemberDefinition { public enum ChannelMemberType {In, Out, Ref} public final ChannelMemberType channelType; public final ResourcePath path; public final String curStateName; public final String messageName; public String nextStateName; public ChannelMemberDefinition(ChannelMemberType channelType, ResourcePath path , String curStateName, String messageName, String nextStateName) { this.path = path; this.channelType = channelType; this.curStateName = curStateName; this.messageName = messageName; this.nextStateName = nextStateName; } public ChannelMemberDefinition(ChannelMemberType channelType, ResourcePath path , String curStateName, String messageName) { this.path = path; this.channelType = channelType; this.curStateName = curStateName; this.messageName = messageName; } } }