package gameEngine.simulator.interfaces; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import gameEngine.entites.*; import gameEngine.entites.gameComponents.*; import gameEngine.scenes.Scene; import gameEngine.views.Sprite; import models.algebra.Expression; import models.algebra.Term; import models.dataConstraintModel.JsonTerm; import models.dataConstraintModel.MapTerm; import models.dataFlowModel.DataTransferChannel; import simulator.Event; import simulator.Resource; import simulator.Simulator; import simulator.SystemState; import simulator.interfaces.INativeReceiver; public class GameEnginePresenter implements INativeReceiver { public final String sceneUpdateChannelName = "SceneUpdate"; public final String cameraPositionUpdateChannelName = "CameraPositionUpdate"; public final String cameraRotationUpdateChannelName = "CameraRotationUpdate"; public final String cameraScaleUpdateChannelName = "CameraScaleUpdate"; public final String cameraProjectionUpdateChannelName = "CameraProjectionUpdate"; public final String entityPositionUpdateChannelName = "EntityPositionUpdate"; public final String entityRotationUpdateChannelName = "EntityRotationUpdate"; public final String entityScaleUpdateChannelName = "EntityScaleUpdate"; public final String spriteUpdateChannelName = "SpriteUpdate"; public final String sceneUpdateEventChannelName = "SceneUpdateEvent"; public final String keyEventChannelName = "KeyEvent"; protected Scene scene; protected Simulator simulator; protected DataTransferChannel sceneUpdateChannel; protected DataTransferChannel cameraPositionUpdateChannel; protected DataTransferChannel cameraRotationUpdateChannel; protected DataTransferChannel cameraScaleUpdateChannel; protected DataTransferChannel cameraProjectionUpdateChannel; protected DataTransferChannel entityPositionUpdateChannel; protected DataTransferChannel entityRotationUpdateChannel; protected DataTransferChannel entityScaleUpdateChannel; protected DataTransferChannel spriteUpdateChannel; protected DataTransferChannel sceneUpdateEventChannel; protected DataTransferChannel keyEventChannel; protected Map<DataTransferChannel, Map<String, Resource>> channelAndResourcesForEntityReceiving = new HashMap<>(); protected Map<DataTransferChannel, Resource> channelAndResourcesForCameraReceiving = new HashMap<>(); public GameEnginePresenter(Scene scene, Simulator simulator) { this.scene = scene; this.simulator = simulator; sceneUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(sceneUpdateChannelName); cameraPositionUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraPositionUpdateChannelName); cameraRotationUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraRotationUpdateChannelName); cameraScaleUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraScaleUpdateChannelName); cameraProjectionUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(cameraProjectionUpdateChannelName); entityPositionUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(entityPositionUpdateChannelName); entityRotationUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(entityRotationUpdateChannelName); entityScaleUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(entityScaleUpdateChannelName); spriteUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(spriteUpdateChannelName); sceneUpdateEventChannel = (DataTransferChannel) simulator.getModel().getInputChannel(sceneUpdateEventChannelName); keyEventChannel = (DataTransferChannel) simulator.getModel().getInputChannel(keyEventChannelName); simulator.addNativeReceiver(this, sceneUpdateChannel); } @Override public void onReceiveFromModel(Event event, SystemState nextSystemState) { Expression message = event.getMessage(); if (message instanceof Term && ((Term) message).getChildren().size() >= 2) { Expression curScExp = ((Term) message).getChild(0); Expression nextScExp = ((Term) message).getChild(1); if (curScExp instanceof JsonTerm && nextScExp instanceof JsonTerm) { JsonTerm curSc = (JsonTerm) curScExp; JsonTerm nextSc = (JsonTerm) nextScExp; Resource sceneResource = nextSystemState.getResource(event.getInputResource().getResourceIdentifier()); Expression cameraExp = nextSc.get("camera"); if (cameraExp != null && cameraExp instanceof JsonTerm) { // Connect camera and model. JsonTerm camera = (JsonTerm) cameraExp; Resource cameraResource = sceneResource.getChildrenMap().get("camera"); Camera cameraObj = scene.getCamera(); Resource cameraTransformResource = cameraResource.getChildrenMap().get("transform"); Resource cameraProjectionResource = cameraResource.getChildrenMap().get("projection"); Resource cameraPositionResource = cameraTransformResource.getChildrenMap().get("position"); Resource cameraRotationResource = cameraTransformResource.getChildrenMap().get("rotation"); Resource cameraScaleResource = cameraTransformResource.getChildrenMap().get("scale"); if (channelAndResourcesForCameraReceiving.get(cameraPositionUpdateChannel) == null) { CameraPositionReceiver nativePositionReceiver = new CameraPositionReceiver(cameraObj); simulator.addNativeReceiver(nativePositionReceiver, cameraPositionUpdateChannel, cameraPositionResource); channelAndResourcesForCameraReceiving.put(cameraPositionUpdateChannel, cameraPositionResource); } if (channelAndResourcesForCameraReceiving.get(cameraRotationUpdateChannel) == null) { CameraRotationReceiver nativeRotationReceiver = new CameraRotationReceiver(cameraObj); simulator.addNativeReceiver(nativeRotationReceiver, cameraRotationUpdateChannel, cameraRotationResource); channelAndResourcesForCameraReceiving.put(cameraRotationUpdateChannel, cameraRotationResource); } if (channelAndResourcesForCameraReceiving.get(cameraScaleUpdateChannel) == null) { CameraScaleReceiver nativeScaleReceiver = new CameraScaleReceiver(cameraObj); simulator.addNativeReceiver(nativeScaleReceiver, cameraScaleUpdateChannel, cameraScaleResource); channelAndResourcesForCameraReceiving.put(cameraScaleUpdateChannel, cameraScaleResource); } if (channelAndResourcesForCameraReceiving.get(cameraProjectionUpdateChannel) == null) { CameraProjectionReceiver nativeProjectionReceiver = new CameraProjectionReceiver(cameraObj); simulator.addNativeReceiver(nativeProjectionReceiver, cameraProjectionUpdateChannel, cameraProjectionResource); channelAndResourcesForCameraReceiving.put(cameraProjectionUpdateChannel, cameraProjectionResource); } } Expression oldEntities = curSc.get("entities"); Expression newEntities = nextSc.get("entities"); Set<String> oldEidSet = new HashSet<>(((MapTerm) oldEntities).keySet()); Set<String> newEidSet = new HashSet<>(((MapTerm) newEntities).keySet()); oldEidSet.removeAll(((MapTerm) newEntities).keySet()); newEidSet.removeAll(((MapTerm) oldEntities).keySet()); if (!oldEidSet.isEmpty() || !newEidSet.isEmpty()) { // If the set of scene entities is changed. // Remove old entities and their native receivers. for (String oldEid: oldEidSet) { scene.removeEntity(oldEid); } for (DataTransferChannel channel: channelAndResourcesForEntityReceiving.keySet()) { Map<String, Resource> widToResource = channelAndResourcesForEntityReceiving.get(channel); for (String oldEid: oldEidSet) { Resource resource = widToResource.remove(oldEid); if (resource != null) { } simulator.removeNativeReceiver(channel, resource); } } // Add new entities. Resource entitiesResource = sceneResource.getChildrenMap().get("entities"); for (String newEid: newEidSet) { Expression entityExp = ((MapTerm) newEntities).get(newEid); if (entityExp instanceof JsonTerm) { JsonTerm entity = (JsonTerm) entityExp; Resource entityResource = entitiesResource.getChildrenMap().get(newEid); Expression transformExp = entity.get("transform"); Expression meshExp = entity.get("mesh"); if (transformExp instanceof JsonTerm && meshExp instanceof JsonTerm) { JsonTerm transform = (JsonTerm) transformExp; JsonTerm mesh = (JsonTerm) meshExp; Resource transformResource = entityResource.getChildrenMap().get("transform"); Resource meshResource = entityResource.getChildrenMap().get("mesh"); Expression positionExp = transform.get("position"); Expression rotationExp = transform.get("rotation"); Expression scaleExp = transform.get("scale"); Resource positionResource = transformResource.getChildrenMap().get("position"); Resource rotationResource = transformResource.getChildrenMap().get("rotation"); Resource scaleResource = transformResource.getChildrenMap().get("scale"); if (positionExp instanceof JsonTerm && rotationExp instanceof JsonTerm && scaleExp instanceof JsonTerm) { JsonTerm position = (JsonTerm) positionExp; JsonTerm rotation = (JsonTerm) rotationExp; JsonTerm scale = (JsonTerm) scaleExp; GameObject gameObj = new GameObject(newEid);//新しいIDが必要あり gameObj.transform.setPosition(Float.parseFloat(position.get("x").toString()), Float.parseFloat(position.get("y").toString()), Float.parseFloat(position.get("z").toString())); gameObj.transform.setRotation(Float.parseFloat(rotation.get("x").toString()), Float.parseFloat(rotation.get("y").toString()), Float.parseFloat(rotation.get("z").toString())); gameObj.transform.setScale(Float.parseFloat(scale.get("x").toString()), Float.parseFloat(scale.get("y").toString()), Float.parseFloat(scale.get("z").toString())); Expression type = mesh.get("type"); if (type.toString().equals("\"sprite\"")) { String texturePath = mesh.get("sprite").toString().replace("\"", ""); Mesh meshObj = new Mesh(gameObj, Mesh.MeshType.SPRITE, texturePath); gameObj.addComponent(meshObj); SpriteReceiver nativeSpriteReceiver = new SpriteReceiver(meshObj); simulator.addNativeReceiver(nativeSpriteReceiver, spriteUpdateChannel, meshResource); Map<String, Resource> resources = channelAndResourcesForEntityReceiving.get(spriteUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(spriteUpdateChannel, resources); } resources.put(newEid, meshResource); } scene.addEntity(newEid, gameObj); // Connect game entity and model. EntityPositionReceiver nativePositionReceiver = new EntityPositionReceiver(gameObj); simulator.addNativeReceiver(nativePositionReceiver, entityPositionUpdateChannel, positionResource); Map<String, Resource> resources = channelAndResourcesForEntityReceiving.get(entityPositionUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(entityPositionUpdateChannel, resources); } resources.put(newEid, positionResource); EntityRotationReceiver nativeRotationReceiver = new EntityRotationReceiver(gameObj); simulator.addNativeReceiver(nativeRotationReceiver, entityRotationUpdateChannel, rotationResource); resources = channelAndResourcesForEntityReceiving.get(entityRotationUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(entityRotationUpdateChannel, resources); } resources.put(newEid, rotationResource); EntityScaleReceiver nativeScaleReceiver = new EntityScaleReceiver(gameObj); simulator.addNativeReceiver(nativeScaleReceiver, entityScaleUpdateChannel, scaleResource); resources = channelAndResourcesForEntityReceiving.get(entityScaleUpdateChannel); if (resources == null) { resources = new HashMap<>(); channelAndResourcesForEntityReceiving.put(entityScaleUpdateChannel, resources); } resources.put(newEid, scaleResource); } } } } } } } } }