Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / gameEngine / GameEngineModelFileGenerator.java
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 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 {

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

            addChannel(
                    new DataTransferChannel("MoveEnemy", new Variable("eid", DataConstraintModel.typeString)),
                    new ChannelMemberDefinition(
                            ChannelMemberDefinition.ChannelMemberType.In,
                            enemy_transform_position,
                            "curPos: Json",
                            "moveEnemy(nextPos)",
                            "nextPos"),
                    new ChannelMemberDefinition(
                            ChannelMemberDefinition.ChannelMemberType.Out,
                            entity_transform_position,
                            "curPos: Json",
                            "moveEnemy(nextPos)",
                            "nextPos")
            );

            addChannel(
                    new DataTransferChannel("RotateEnemy", new Variable("eid", DataConstraintModel.typeString)),
                        new ChannelMemberDefinition(
                                ChannelMemberDefinition.ChannelMemberType.In,
                                enemy_transform_rotation,
                                "curRot: Json",
                                "rotateEnemy(nextRot)",
                                "nextRot"),
                        new ChannelMemberDefinition(
                                ChannelMemberDefinition.ChannelMemberType.Out,
                                enemy_transform_rotation,
                                "curRot: Json",
                                "rotateEnemy(nextRot)",
                                "nextRot")
            );

            addChannel(
                    new DataTransferChannel("UpdateEnemy", Arrays.asList(
                            new Variable("tid", DataConstraintModel.typeString),
                            new Variable("eid", DataConstraintModel.typeString))),
                                new ChannelMemberDefinition(
                                        ChannelMemberDefinition.ChannelMemberType.In,
                                        timer_count,
                                        "curCount: Long",
                                        "updateEnemy(type, speed)",
                                        "nextCount"),
                            new ChannelMemberDefinition(
                                    ChannelMemberDefinition.ChannelMemberType.Ref,
                                    enemy_move_type,
                                    "type: Str",
                                    "updateEnemy(type, speed)"),
                            new ChannelMemberDefinition(
                                    ChannelMemberDefinition.ChannelMemberType.Ref,
                                    enemy_move_speed,
                                    "speed: Float",
                                    "updateEnemy(type, speed)"),
                            new ChannelMemberDefinition(
                                    ChannelMemberDefinition.ChannelMemberType.Out,
                                    enemy_transform_position,
                                    "curPos: Json",
                                    "updateEnemy(type, speed)",
                                    "{\"x\": curPos.x, \"y\": curPos.y + speed, \"z\": curPos.z}")
            );

            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(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, 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;
        }

    }

}