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.Simulator;
import gameEngine.simulator.interfaces.GameEnginePresenter;
import simulator.SystemState;
import simulator.interfaces.timers.TimerService;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
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 {
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
ResourcePath enemies = new ResourcePath("enemies");
ResourcePath enemy = new ResourcePath(enemies, new Variable("eid", DataConstraintModel.typeString));
ResourcePath enemy_transform = new ResourcePath(enemy, "transform");
ResourcePath enemy_transform_position = new ResourcePath(enemy_transform, "position");
ResourcePath enemy_transform_rotation = new ResourcePath(enemy_transform, "rotation");
ResourcePath enemy_move = new ResourcePath(enemy, "move");
ResourcePath enemy_move_type = new ResourcePath(enemy_move, "type");
ResourcePath enemy_move_speed = new ResourcePath(enemy_move, "speed");
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);
model.addResourcePath(enemy_transform);
model.addResourcePath(enemy_transform_position);
model.addResourcePath(enemy_transform_rotation);
model.addResourcePath(enemy_move);
model.addResourcePath(enemy_move_type);
model.addResourcePath(enemy_move_speed);
addInit();
addNativeChannel(
new DataTransferChannel("SceneUpdateEvent"),
new ChannelDefinition(
ChannelDefinition.ChannelType.In,
scene_time,
"time: Long",
"updateEvent(dt: Long)",
"time + dt"
)
);
addNativeChannel(
new DataTransferChannel("SceneUpdate"),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
scene,
"curSc: Json",
"update(curSc, nextSc)",
"nextSc"
)
);
addNativeChannel(
new DataTransferChannel("CameraPositionUpdate"),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
scene_camera_transform_position,
"curPos: Json",
"updatePosition(nextPos.x, nextPos.y, nextPos.z)",
"nextPos"
)
);
addNativeChannel(
new DataTransferChannel("CameraRotationUpdate"),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
scene_camera_transform_rotation,
"curRot: Json",
"updateRotation(nextRot.x, nextRot.y, nextRot.z)",
"nextRot"
)
);
addNativeChannel(
new DataTransferChannel("CameraScaleUpdate"),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
scene_camera_transform_scale,
"curScale: Json",
"updateScale(nextScale.x, nextScale.y, nextScale.z)",
"nextScale"
)
);
addNativeChannel(
new DataTransferChannel("CameraProjectionUpdate"),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
scene_camera_projection,
"curProj: Json",
"updateProjection(curProj, nextProj)",
"nextProj"
)
);
addNativeChannel(
new DataTransferChannel("EntityPositionUpdate", new Variable("eid", DataConstraintModel.typeString)),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
entity_transform_position,
"curPos: Json",
"updatePosition(nextPos.x, nextPos.y, nextPos.z)",
"nextPos"
)
);
addNativeChannel(
new DataTransferChannel("EntityRotationUpdate", new Variable("eid", DataConstraintModel.typeString)),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
entity_transform_rotation,
"curRot: Json",
"updateRotation(nextRot.x, nextRot.y, nextRot.z)",
"nextRot"
)
);
addNativeChannel(
new DataTransferChannel("EntityScaleUpdate", new Variable("eid", DataConstraintModel.typeString)),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
entity_transform_scale,
"curScale: Json",
"updateScale(nextScale.x, nextScale.y, nextScale.z)",
"nextScale"
)
);
addNativeChannel(
new DataTransferChannel("EntitySpriteUpdate", new Variable("eid", DataConstraintModel.typeString)),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
entity_mesh,
"curMesh: Json",
"updateSprite(spritePath: Str)",
"{\"type\": \"sprite\", \"sprite\": spritePath}"
)
);
addNativeChannel(
new DataTransferChannel("KeyEvent", new Variable("kno", DataConstraintModel.typeInt)),
new ChannelDefinition(
ChannelDefinition.ChannelType.In,
key_state,
"curState: Int",
"keyEvent(nextState)",
"nextState"
)
);
addNativeChannel(
new DataTransferChannel("TimersUpdated"),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
timers,
"curTimers: Map",
"update(curTimers, nextTimers)",
"nextTimers"
)
);
addNativeChannel(
new DataTransferChannel("TimerEvent", new Variable("tid", DataConstraintModel.typeString)),
new ChannelDefinition(
ChannelDefinition.ChannelType.In,
timer_count,
"count: Long",
"tick()",
"count + 1"
)
);
addChannel(
new DataTransferChannel("UpdateCameraPosition"),
new ChannelDefinition(
ChannelDefinition.ChannelType.In,
scene_camera_transform_position,
"curPos: Json",
"updateCameraPosition(x: Double, y: Double, z: Double)",
"{\"x\": x, \"y\": y, \"z\": z}")
);
addChannel(
new DataTransferChannel("MoveEnemy", new Variable("eid", DataConstraintModel.typeString)),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
enemy_transform_position,
"curPos: Json",
"moveEnemy(nextPos)",
"nextPos"),
new ChannelDefinition(
ChannelDefinition.ChannelType.In,
entity_transform_position,
"curPos: Json",
"moveEnemy(nextPos)",
"nextPos")
);
addChannel(
new DataTransferChannel("RotateEnemy", new Variable("eid", DataConstraintModel.typeString)),
new ChannelDefinition(
ChannelDefinition.ChannelType.Out,
enemy_transform_rotation,
"curRot: Json",
"rotateEnemy(nextRot)",
"nextRot"),
new ChannelDefinition(
ChannelDefinition.ChannelType.In,
enemy_transform_rotation,
"curRot: Json",
"rotateEnemy(nextRot)",
"nextRot")
);
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();
}
}
private JsonTerm createTransformTerm(){
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);
return transformTerm;
}
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());
playerTerm.addMember("mesh", meshTerm);
return playerTerm;
}
public JsonTerm createEnemyJsonTerm(){
JsonTerm moveTerm = new JsonTerm();
moveTerm.addMember("type", new Constant("straight"));
moveTerm.addMember("speed", new Constant(String.valueOf(5.0)));
JsonTerm meshTerm = new JsonTerm();
meshTerm.addMember("type", new Constant("sprite", DataConstraintModel.typeString));
meshTerm.addMember("sprite", new Constant(Window.resourcePath + "enemy1.png", DataConstraintModel.typeString));
JsonTerm enemyTerm = new JsonTerm();
enemyTerm.addMember("transform", createTransformTerm());
enemyTerm.addMember("mesh", meshTerm);
enemyTerm.addMember("move", moveTerm);
JsonTerm enemiesTerm = new JsonTerm();
enemiesTerm.addMember("001", enemyTerm);
enemiesTerm.addMember("002", enemyTerm);
return enemiesTerm;
}
public JsonTerm createTimrsJsonTerm(){
JsonTerm timerTerm = new JsonTerm();
timerTerm.addMember("interval", new Constant(String.valueOf(100)));
timerTerm.addMember("count", new Constant(String.valueOf(0)));
JsonTerm timersTerm = new JsonTerm();
timersTerm.addMember("000",timerTerm);
return timersTerm;
}
private void addInit(){
ResourceHierarchy timersHierarchy = new ResourceHierarchy("timers", DataConstraintModel.typeJson);
timersHierarchy = model.getOrPutResourceHierarchy(timersHierarchy);
JsonTerm timersRightTerm = createTimrsJsonTerm();
timersHierarchy.setInitialValue(timersRightTerm);
timersHierarchy.setInitText(timersRightTerm.toString());
ResourceHierarchy playerHierarchy = new ResourceHierarchy("player", DataConstraintModel.typeJson);
playerHierarchy = model.getOrPutResourceHierarchy(playerHierarchy);
JsonTerm playerRightTerm = createPlayerJsonTerm();
playerHierarchy.setInitialValue(playerRightTerm);
playerHierarchy.setInitText(playerRightTerm.toString());
ResourceHierarchy enemyHierarchy = new ResourceHierarchy("enemy", DataConstraintModel.typeJson);
enemyHierarchy = model.getOrPutResourceHierarchy(enemyHierarchy);
JsonTerm enemyRightTerm = createEnemyJsonTerm();
enemyHierarchy.setInitialValue(enemyRightTerm);
enemyHierarchy.setInitText(enemyRightTerm.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, ChannelDefinition... definitions) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation {
dataTransferChannel.setNative(true);
return addChannel(dataTransferChannel, definitions);
}
public DataTransferChannel addChannel(DataTransferChannel dataTransferChannel, ChannelDefinition... definitions)
throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation {
DataTransferChannel channel = dataTransferChannel;
for (ChannelDefinition def : definitions) {
ChannelMember member = addChannelMember(stream, parser, def.path, def.curStateName, def.messageName, def.nextStateName);
if (def.channelType == ChannelDefinition.ChannelType.Out) {
channel.addChannelMemberAsInput(member);
model.addChannel(channel);
} else if (def.channelType == ChannelDefinition.ChannelType.In) {
channel.addChannelMemberAsOutput(member);
model.addInputChannel(channel);
} else if (def.channelType == ChannelDefinition.ChannelType.Ref){
channel.addChannelMemberAsReference(member);
model.addChannel(channel);
}
}
return channel;
}
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;
}
public class ChannelDefinition {
public enum ChannelType{In, Out, Ref}
public final ChannelType channelType;
public final ResourcePath path;
public final String curStateName;
public final String messageName;
public final String nextStateName;
public ChannelDefinition(ChannelType channelType, ResourcePath path ,String curStateName, String messageName, String nextStateName) {
this.path = path;
this.channelType = channelType;
this.curStateName = curStateName;
this.messageName = messageName;
this.nextStateName = nextStateName;
}
}
}