package com.wordpress.salaboy.emergencyservice.worldui.slick; import com.wordpress.salaboy.context.tracking.ContextTrackingProvider; import com.wordpress.salaboy.context.tracking.ContextTrackingService; import com.wordpress.salaboy.emergencyservice.worldui.slick.listener.WorldMouseListener; import com.wordpress.salaboy.emergencyservice.worldui.slick.listener.WorldKeyListener; import com.wordpress.salaboy.emergencyservice.worldui.slick.graphicable.GraphicableEmergency; import com.wordpress.salaboy.emergencyservice.worldui.slick.graphicable.AnimationFactory; import com.wordpress.salaboy.emergencyservice.worldui.slick.graphicable.GraphicableEmergencyStatus; import com.wordpress.salaboy.emergencyservice.worldui.slick.graphicable.GraphicableFactory; import com.wordpress.salaboy.messaging.MessageConsumerWorker; import com.wordpress.salaboy.messaging.MessageConsumerWorkerHandler; import com.wordpress.salaboy.messaging.MessageFactory; import com.wordpress.salaboy.model.Hospital; import com.wordpress.salaboy.model.Vehicle; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.hornetq.api.core.HornetQException; import org.newdawn.slick.AppGameContainer; import org.newdawn.slick.BasicGame; import org.newdawn.slick.GameContainer; import org.newdawn.slick.Graphics; import org.newdawn.slick.SlickException; import org.newdawn.slick.SpriteSheet; import org.newdawn.slick.opengl.renderer.Renderer; import com.wordpress.salaboy.model.Call; import com.wordpress.salaboy.model.Emergency; import com.wordpress.salaboy.model.Emergency.EmergencyType; import com.wordpress.salaboy.model.FirefightersDepartment; import com.wordpress.salaboy.model.command.Command; import com.wordpress.salaboy.model.messages.*; import com.wordpress.salaboy.model.persistence.PersistenceService; import com.wordpress.salaboy.model.persistence.PersistenceServiceProvider; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class WorldUI extends BasicGame { // The map itself (created using Tiled) public BlockMap map; // Places for emergencies private int[] xs = new int[]{1, 7, 13, 19, 25, 31, 37}; private int[] ys = new int[]{1, 7, 13, 19, 25}; private Map<String, GraphicableEmergency> emergencies = new HashMap<String, GraphicableEmergency>(); public static SpriteSheet hospitalSheet; private final List<Command> renderCommands = Collections.synchronizedList(new ArrayList<Command>()); private EmergencyRenderer currentRenderer; private GlobalEmergenciesRenderer globalRenderer; private Map<String, ParticularEmergencyRenderer> renderers = new HashMap<String, ParticularEmergencyRenderer>(); private PersistenceService persistenceService; private ContextTrackingService trackingService; public WorldUI() { super("City Map"); this.globalRenderer = new GlobalEmergenciesRenderer(this); this.currentRenderer = globalRenderer; } @Override public void init(GameContainer gc) throws SlickException { gc.setVSync(true); // gc.setAlwaysRender(true); map = new BlockMap("data/cityMap.tmx"); map.initializeCorners(); AnimationFactory.getAmbulanceSpriteSheet(); AnimationFactory.getFireTruckSpriteSheet(); AnimationFactory.getPoliceCarSpriteSheet(); gc.getInput().addKeyListener(new WorldKeyListener(this)); gc.getInput().addMouseListener(new WorldMouseListener(this)); persistenceService = PersistenceServiceProvider.getPersistenceService(); trackingService = ContextTrackingProvider.getTrackingService(); registerMessageConsumers(); } @Override public void update(GameContainer gc, int delta) throws SlickException { this.currentRenderer.update(gc, delta); } @Override public void render(GameContainer gc, Graphics g) throws SlickException { synchronized (this.renderCommands){ //Execute any renderCommands for (Command command : this.renderCommands) { command.execute(); } //clear the renderCommands list renderCommands.clear(); } this.currentRenderer.renderPolygon(gc, g); BlockMap.tmap.render(0, 0, 0, 0, BlockMap.tmap.getWidth(), BlockMap.tmap.getHeight(), 1, true); this.currentRenderer.renderAnimation(gc, g); BlockMap.tmap.render(0, 0, 0, 0, BlockMap.tmap.getWidth(), BlockMap.tmap.getHeight(), 2, true); this.currentRenderer.renderHighlightsAnimation(gc, g); } public static void main(String[] args) throws SlickException { final WorldUI game = new WorldUI(); Renderer.setLineStripRenderer(Renderer.QUAD_BASED_LINE_STRIP_RENDERER); Renderer.getLineStripRenderer().setLineCaps(true); AppGameContainer container = new AppGameContainer(game); container.start(); System.out.println(" -> -> -> Displaying City!"); } public synchronized void removeEmergency(String callId) { this.emergencies.remove(callId); } private void registerMessageConsumers() { //worldMessages queue MessageConsumerWorker emergencyDetailsWorker = new MessageConsumerWorker("emergencyDetailsWorldUI", new MessageConsumerWorkerHandler<EmergencyDetailsMessage>() { @Override public void handleMessage(final EmergencyDetailsMessage message) { //Changes emergency animation renderCommands.add(new Command() { public void execute() { System.out.println("EmergencyDetailsMessage received"); if (emergencies.get(message.getEmergency().getCall().getId())==null){ System.out.println("Unknown emergency for call "+message.getEmergency().getCall().getId()); return; } emergencies.get(message.getEmergency().getCall().getId()).setAnimation(AnimationFactory.getEmergencyAnimation(message.getType(), message.getNumberOfPeople())); notifyAboutEmergencyStatusChange(message.getEmergency().getCall().getId(), message.getRemaining()); } }); } }); MessageConsumerWorker vehicleDispatchedWorker = new MessageConsumerWorker("vehicleDispatchedWorldUI", new MessageConsumerWorkerHandler<VehicleDispatchedMessage>() { @Override public void handleMessage(final VehicleDispatchedMessage message) { String callId = trackingService.getCallAttachedToEmergency(message.getEmergencyId()); if (callId == null){ throw new IllegalArgumentException("No Call attached to Emergency "+message.getEmergencyId()); } if (emergencies.get(callId)==null){ throw new IllegalArgumentException("Unknown emergency for call Id "+callId); } Vehicle vehicle = persistenceService.loadVehicle(message.getVehicleId()); switchToEmergency(callId); assignVehicleToEmergency(callId, vehicle); } }); MessageConsumerWorker hospitalSelectedWorker = new MessageConsumerWorker("hospitalSelectedWorldUI", new MessageConsumerWorkerHandler<HospitalSelectedMessage>() { @Override public void handleMessage(final HospitalSelectedMessage message) { //Changes emergency animation renderCommands.add(new Command() { public void execute() { if (emergencies.get(message.getCallId())==null){ System.out.println("Unknown emergency for call Id "+message.getCallId()); return; } selectHospitalForEmergency(message.getCallId(), message.getHospital()); } }); } }); MessageConsumerWorker firefigthersDepartmentWorker = new MessageConsumerWorker("firefigthersDepartmentWorldUI", new MessageConsumerWorkerHandler<FirefightersDepartmentSelectedMessage>() { @Override public void handleMessage(final FirefightersDepartmentSelectedMessage message) { //Changes emergency animation renderCommands.add(new Command() { public void execute() { if (emergencies.get(message.getCallId())==null){ System.out.println("Unknown emergency for call Id "+message.getCallId()); return; } selectFirefighterDepartmentForEmergency(message.getCallId(), message.getFirefightersDepartment()); } }); } }); MessageConsumerWorker fireTruckOutOfWaterWorker = new MessageConsumerWorker("fireTruckOutOfWaterWorkerUI", new MessageConsumerWorkerHandler<FireTruckOutOfWaterMessage>() { @Override public void handleMessage(final FireTruckOutOfWaterMessage message) { //Changes emergency animation renderCommands.add(new Command() { @Override public void execute() { String callId = trackingService.getCallAttachedToEmergency(message.getEmergencyId()); if (callId == null){ System.out.println("The emergency "+message.getEmergencyId()+" doesn't have any associated call!"); return; } if (emergencies.get(callId)==null){ System.out.println("Unknown emergency for call Id "+callId); return; } notifyAboutFireTruckOutOfWaterToEmergency(callId, message.getVehicleId()); } }); } }); MessageConsumerWorker fireTruckWaterRefilledWorker = new MessageConsumerWorker("fireTruckWaterRefilledWorkerUI", new MessageConsumerWorkerHandler<FireTruckWaterRefilledMessage>() { @Override public void handleMessage(final FireTruckWaterRefilledMessage message) { //Changes emergency animation renderCommands.add(new Command() { @Override public void execute() { String callId = trackingService.getCallAttachedToEmergency(message.getEmergencyId()); if (callId == null){ System.out.println("The emergency "+message.getEmergencyId()+" doesn't have any associated call!"); return; } if (emergencies.get(callId)==null){ System.out.println("Unknown emergency for call Id "+callId); return; } notifyAboutFireTruckWaterRefilledToEmergency(callId, message.getVehicleId()); } }); } }); hospitalSelectedWorker.start(); emergencyDetailsWorker.start(); vehicleDispatchedWorker.start(); firefigthersDepartmentWorker.start(); fireTruckOutOfWaterWorker.start(); fireTruckWaterRefilledWorker.start(); } public void addRandomGenericEmergency() throws IOException { this.addRandomEmergency(Emergency.EmergencyType.UNDEFINED, null); } public void addXYEmergency( int x, int y){ addXYEmergency(EmergencyType.UNDEFINED, null, x, y); } public void addXYEmergency(EmergencyType type,Integer nroOfPeople, int x, int y){ System.out.println("x = " + xs[x] + " -> y =" + ys[y]); Call call = new Call(x, y, new Date(System.currentTimeMillis())); PersistenceServiceProvider.getPersistenceService().storeCall(call); int callSquare[] = {1, 1, 31, 1, 31, 31, 1, 31}; BlockMap.emergencies.add(new Block(xs[call.getX()] * 16, ys[call.getY()] * 16, callSquare, "callId:" + call.getId())); GraphicableEmergency newEmergency = null; if (type == Emergency.EmergencyType.UNDEFINED){ newEmergency = GraphicableFactory.newGenericEmergency(call); }else{ newEmergency = GraphicableFactory.newEmergency(call, type, nroOfPeople); } emergencies.put(call.getId(), newEmergency); renderers.put(call.getId(), new ParticularEmergencyRenderer(this,newEmergency)); try { MessageFactory.sendMessage(new IncomingCallMessage(call)); } catch (HornetQException ex) { Logger.getLogger(WorldUI.class.getName()).log(Level.SEVERE, null, ex); } } public void addRandomEmergency(Emergency.EmergencyType emergencyType, Integer numberOfPeople) throws IOException { int randomx = 0; int randomy = 0; boolean isFreeSpace = false; //Avoid duplicated places do{ randomx = (int) (Math.random() * 10) % 7; randomy = (int) (Math.random() * 10) % 5; if (randomx == 0 && randomy == 4) { randomx = 4; } isFreeSpace = true; for (GraphicableEmergency graphicableEmergency : emergencies.values()) { if (graphicableEmergency.getCallX() == randomx && graphicableEmergency.getCallY() == randomy){ isFreeSpace = false; } } } while (!isFreeSpace); addXYEmergency(emergencyType, numberOfPeople,randomx, randomy); } public Map<String, GraphicableEmergency> getEmergencies() { return emergencies; } public void emergencyClicked(String callId) { this.switchToEmergency(callId); } private void switchToEmergency(String callId){ this.currentRenderer = renderers.get(callId); } public void goToGlobalMap(){ this.currentRenderer = this.globalRenderer; } public void assignVehicleToEmergency(String callId, Vehicle vehicle){ this.renderers.get(callId).addVehicle(vehicle); } public EmergencyRenderer getCurrentRenderer() { return currentRenderer; } public void selectHospitalForEmergency(String callId, Hospital hospital) { this.renderers.get(callId).selectHospital(hospital); } public void selectFirefighterDepartmentForEmergency(String callId, FirefightersDepartment firefigthersDepartment) { this.renderers.get(callId).selectFirefighterDepartment(firefigthersDepartment); } public void notifyAboutFireTruckOutOfWaterToEmergency(String callId, String vehicleId){ this.renderers.get(callId).onFireTruckOutOfWater(vehicleId); } public void notifyAboutFireTruckWaterRefilledToEmergency(String callId, String vehicleId){ this.renderers.get(callId).onFireTruckWaterRefilled(vehicleId); } public void notifyAboutEmergencyStatusChange(String callId, int remaining){ this.renderers.get(callId).updateStatus(remaining); } public PersistenceService getPersistenceService() { return persistenceService; } public ContextTrackingService getTrackingService() { return trackingService; } public void addRenderCommand(Command element) { synchronized (renderCommands){ renderCommands.add(element); } } }