/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PeerfactSim.KOM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.topology.movement; import java.io.File; import java.io.FileNotFoundException; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Scanner; import de.tud.kom.p2psim.api.scenario.ConfigurationException; import de.tud.kom.p2psim.api.topology.movement.MovementModel; import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator; import de.tud.kom.p2psim.impl.topology.movement.modularosm.IAttractionBasedMovementAnalyzer; import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.IAttractionGenerator; import de.tud.kom.p2psim.impl.topology.movement.modularosm.mapvisualization.IMapVisualization; import de.tud.kom.p2psim.impl.topology.util.PositionVector; import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector; import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Time; public class TracefileMovementModel implements MovementModel, EventHandler { public static String tracefileFolder ="smarter/tracefiles/"; public static String tracefilePrefix = "smarterTraceFile-"; protected final int EVENT_MOVE = 1; protected long timeBetweenMoveOperations; protected IMapVisualization mapVisualization; protected IAttractionGenerator attractionGenerator; protected boolean initialized = false; private final LinkedHashMap> components; private LinkedList tracefiles; private boolean first = true; public TracefileMovementModel() { components = new LinkedHashMap>(); tracefiles = new LinkedList(); } public void initialize() { if(initialized) { return; } File folder = new File(tracefileFolder); if (!folder.exists()) { throw new UnsupportedOperationException("Tracefile folder not found"); } for(File tracefile : folder.listFiles()) { if(tracefile.getName().contains(tracefilePrefix)) { tracefiles.add(tracefile); } } if (mapVisualization != null) { VisualizationInjector.injectComponent(mapVisualization); } initialized = true; Event.scheduleWithDelay(timeBetweenMoveOperations, this, null, EVENT_MOVE); } @Override public void eventOccurred(Object content, int type) { if (type == EVENT_MOVE) { move(); } } private void move() { if(first) { components.forEach((component, steps) -> { component.updateCurrentLocation(new PositionVector(-1, -1)); }); } // as the files contain the timestamp in seconds, the current time needs to be converted in seconds long currentTime = Time.getCurrentTime() / Time.SECOND; LinkedList toRemove = new LinkedList<>(); components.forEach((component, steps) -> { Step step = steps.peek(); if (step != null) { if(currentTime < step.timestamp) { //component.updateCurrentLocation(new PositionVector(-1, -1)); } else { step = steps.pop(); component.updateCurrentLocation(new PositionVector(step.x, step.y)); } } else { System.out.println("Component "+component.getHost().getId()+" left the area at " + Time.getFormattedTime()); component.updateCurrentLocation(new PositionVector(-1, -1)); toRemove.add(component); } }); for (SimLocationActuator simLocationActuator : toRemove) { components.remove(simLocationActuator); } Event.scheduleWithDelay(timeBetweenMoveOperations, this, null, EVENT_MOVE); if(first) { System.out.println("first with " + components.keySet().size() + " hosts"); // Inform analyzer of resolved movement if(Monitor.hasAnalyzer(IAttractionBasedMovementAnalyzer.class)) { Monitor.getOrNull(IAttractionBasedMovementAnalyzer.class).onAllNodeInitializationCompleted(components.keySet()); } first =false; } } @Override public void addComponent(SimLocationActuator actuator) { if (!initialized) { initialize(); } associateTracefile(actuator); } private void associateTracefile(SimLocationActuator actuator) { if(tracefiles.isEmpty()) { throw new UnsupportedOperationException("List of tracefiles is empty, thus cannot initiate the component!"); } if(components.containsKey(actuator)) { throw new UnsupportedOperationException("Component was already assigned!"); } LinkedList stepQueue = new LinkedList(); File tracefile = tracefiles.pop(); Scanner filescanner; try { filescanner = new Scanner(tracefile); while(filescanner.hasNextLine()) { String line = filescanner.nextLine(); String[] split = line.split(" "); long timestamp = Long.valueOf(split[0]); //double lat = Double.valueOf(split[1]); //double lon = Double.valueOf(split[2]); double x = Double.valueOf(split[3]); double y = Double.valueOf(split[4]); Step s = new Step(timestamp, x, y); stepQueue.add(s); } filescanner.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (Exception e) { System.err.println(tracefile.getName()); e.printStackTrace(); } System.out.println(actuator.getHost().getId() + " <> " + tracefile.getName()); components.put(actuator, stepQueue); } @Override public void placeComponent(SimLocationActuator actuator) { // Initial placement actuator.updateCurrentLocation(new PositionVector(-1, -1)); } @Override public void setTimeBetweenMoveOperations(long time) { this.timeBetweenMoveOperations = time; } public void setIMapVisualization(IMapVisualization mapVisualization) { this.mapVisualization = mapVisualization; } public void setIAttractionGenerator(IAttractionGenerator attractionGenerator) { if (attractionGenerator == null) { throw new ConfigurationException( "AttractionGenerator is missing in ModularMovementModel!"); } this.attractionGenerator = attractionGenerator; } private class Step { public final double x; public final double y; public final long timestamp; public Step(long timestamp, double x, double y) { this.x = x; this.y = y; this.timestamp = timestamp; } } }