package gameEngine;
import algorithms.TypeInference;
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;
public class GameEngineModelFileGenerator {
private DataTransferModel model;
private final String modelFilePath = "GameEngine/resources/";
public void generate(){
try {
Parser.TokenStream stream = new Parser.TokenStream();
Parser parser = new Parser(stream);
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
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);
addInit();
addNativeInputChannel(stream, parser, scene_time, new DataTransferChannel("SceneUpdateEvent"), "time: Long", "updateEvent(dt: Long)", "time + dt");
DataTransferChannel sceneUpdateChannel = addNativeOutputChannel(stream, parser, scene,new DataTransferChannel("SceneUpdate"), "curSc: Json", "update(curSc, nextSc)", "nextSc");
addNativeOutputChannel(stream, parser, scene_camera_transform_position,new DataTransferChannel("CameraPositionUpdate"),"curPos: Json","updatePosition(nextPos.x, nextPos.y, nextPos.z)","nextPos");
addNativeOutputChannel(stream, parser, scene_camera_transform_rotation,new DataTransferChannel("CameraRotationUpdate"),"curRot: Json","updateRotation(nextRot.x, nextRot.y, nextRot.z)","nextRot");
addNativeOutputChannel(stream, parser, scene_camera_transform_scale,new DataTransferChannel("CameraScaleUpdate"),"curScale: Json","updateScale(nextScale.x, nextScale.y, nextScale.z)","nextScale");
addNativeOutputChannel(stream, parser, scene_camera_projection,new DataTransferChannel("CameraProjectionUpdate"),"curProj: Json","updateProjection(curProj, nextProj)","nextProj");
addNativeOutputChannel(stream, parser, entity_transform_position, new DataTransferChannel("EntityPositionUpdate", new Variable("eid", DataConstraintModel.typeString)),"curPos: Json","updatePosition(nextPos.x, nextPos.y, nextPos.z)","nextPos");
addNativeOutputChannel(stream, parser, entity_transform_rotation,new DataTransferChannel("EntityRotationUpdate", new Variable("eid", DataConstraintModel.typeString)),"curRot: Json","updateRotation(nextRot.x, nextRot.y, nextRot.z)","nextRot");
addNativeOutputChannel(stream, parser, entity_transform_scale,new DataTransferChannel("EntityScaleUpdate", new Variable("eid", DataConstraintModel.typeString)),"curScale: Json","updateScale(nextScale.x, nextScale.y, nextScale.z)","nextScale");
addNativeOutputChannel (stream, parser, entity_mesh,new DataTransferChannel("EntitySpriteUpdate", new Variable("eid", DataConstraintModel.typeString)),"curMesh: Json","updateSprite(spritePath: Str)","{\"type\": \"sprite\", \"sprite\": spritePath}");
addNativeInputChannel(stream, parser, key_state,new DataTransferChannel("KeyEvent", new Variable("kno", DataConstraintModel.typeInt)),"curState: Int","keyEvent(nextState)","nextState");
addNativeOutputChannel(stream, parser, timers ,new DataTransferChannel("TimersUpdated"),"curTimers: Map","update(curTimers, nextTimers)","nextTimers");
addNativeInputChannel(stream, parser, timer_count,new DataTransferChannel("TimerEvent" , new Variable("tid", DataConstraintModel.typeString)),"count: Long","tick()","count + 1");
DataTransferChannel updateCameraPosChannel = addInputChannel(stream,parser,scene_camera_transform_position, new DataTransferChannel("UpdateCameraPosition"), "curPos: Json","updateCameraPosition(x: Double, y: Double, z: Double)", "{\"x\": x, \"y\": y, \"z\": z}");
if (stream.hasNext()) stream.next();
save();
TypeInference.infer(model);
Simulator simulator = new Simulator(model);
Window window = Window.get();
window.changeScene(1);
GameEnginePresenter presenter = new GameEnginePresenter(window.getScene(), simulator);
TimerService timerService = new TimerService(simulator);
SystemState initialState = simulator.init();
// stream.addLine("updateCameraPosition(0.0,0.0,0.0)");
// Expression messageUpdateCPos = parser.parseTerm(stream, model);
// Event updateCameraPos = new Event(updateCameraPosChannel, messageUpdateCPos, scene_camera_transform_position, initialState.getResource(ResourceIdentifier.createFrom(scene_camera_transform_position)));
// simulator.transition(updateCameraPos);
} catch (Exception e) {
e.printStackTrace();
}
}
public JsonTerm createJsonTerm(){
JsonTerm positionTerm = new JsonTerm();
positionTerm.addMember("x", new Constant(String.valueOf(0.0)));
positionTerm.addMember("y", new Constant(String.valueOf(0.0)));
positionTerm.addMember("z", new Constant(String.valueOf(0.0)));
JsonTerm rotationTerm = new JsonTerm();
rotationTerm.addMember("x", new Constant(String.valueOf(0.0)));
rotationTerm.addMember("y", new Constant(String.valueOf(0.0)));
rotationTerm.addMember("z", new Constant(String.valueOf(0.0)));
JsonTerm scaleTerm = new JsonTerm();
scaleTerm.addMember("x", new Constant(String.valueOf(1.0)));
scaleTerm.addMember("y", new Constant(String.valueOf(1.0)));
scaleTerm.addMember("z", new Constant(String.valueOf(1.0)));
JsonTerm transformTerm = new JsonTerm();
transformTerm.addMember("position", positionTerm);
transformTerm.addMember("rotation", rotationTerm);
transformTerm.addMember("scale", scaleTerm);
JsonTerm meshTerm = new JsonTerm();
meshTerm.addMember("type", new Constant("sprite", DataConstraintModel.typeString));
meshTerm.addMember("sprite", new Constant(Window.resourcePath + "enemy1.png", DataConstraintModel.typeString));
JsonTerm entityTerm = new JsonTerm();
entityTerm.addMember("transform", transformTerm);
entityTerm.addMember("mesh", meshTerm);
JsonTerm entitiesTerm = new JsonTerm();
entitiesTerm.addMember("001", entityTerm);
entitiesTerm.addMember("002", entityTerm);
JsonTerm sceneTerm = new JsonTerm();
sceneTerm.addMember("entities",entitiesTerm);
return sceneTerm;
}
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();
}
}
private void addInit(){
ResourceHierarchy hierarchy = new ResourceHierarchy("scene", DataConstraintModel.typeJson);
hierarchy = model.getOrPutResourceHierarchy(hierarchy);
JsonTerm rightTerm = createJsonTerm();
hierarchy.setInitialValue(rightTerm);
hierarchy.setInitText(rightTerm.toString());
}
private DataTransferChannel addNativeOutputChannel(TokenStream stream, Parser parser, ResourcePath path,
DataTransferChannel dataTransferChannel, String curStateName, String messageName, String nextStateName) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation {
DataTransferChannel outputChannel = dataTransferChannel;
outputChannel.setNative(true);
ChannelMember out = 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);
out.getStateTransition().setCurStateExpression(curState);
out.getStateTransition().setMessageExpression(message);
out.getStateTransition().setNextStateExpression(nextState);
outputChannel.addChannelMemberAsInput(out);
model.addChannel(outputChannel);
return outputChannel;
}
private DataTransferChannel addNativeInputChannel(TokenStream stream, Parser parser, ResourcePath path,
DataTransferChannel dataTransferChannel, String curStateName, String messageName, String nextStateName) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation {
DataTransferChannel inputChannel = dataTransferChannel;
inputChannel.setNative(true);
ChannelMember in = 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);
in.getStateTransition().setCurStateExpression(curState);
in.getStateTransition().setMessageExpression(message);
in.getStateTransition().setNextStateExpression(nextState);
inputChannel.addChannelMemberAsOutput(in);
model.addInputChannel(inputChannel);
return inputChannel;
}
private DataTransferChannel addOutputChannel(TokenStream stream, Parser parser, ResourcePath path,
DataTransferChannel dataTransferChannel, String curStateName, String messageName, String nextStateName) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation {
DataTransferChannel outputChannel = dataTransferChannel;
outputChannel.setNative(false);
ChannelMember out = 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);
out.getStateTransition().setCurStateExpression(curState);
out.getStateTransition().setMessageExpression(message);
out.getStateTransition().setNextStateExpression(nextState);
outputChannel.addChannelMemberAsInput(out);
model.addChannel(outputChannel);
return outputChannel;
}
private DataTransferChannel addInputChannel(TokenStream stream, Parser parser, ResourcePath path,
DataTransferChannel dataTransferChannel, String curStateName, String messageName, String nextStateName) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation {
DataTransferChannel inputChannel = dataTransferChannel;
inputChannel.setNative(false);
ChannelMember in = 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);
in.getStateTransition().setCurStateExpression(curState);
in.getStateTransition().setMessageExpression(message);
in.getStateTransition().setNextStateExpression(nextState);
inputChannel.addChannelMemberAsOutput(in);
model.addInputChannel(inputChannel);
return inputChannel;
}
}