/* * 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; import java.util.LinkedList; import java.util.List; import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.impl.simengine.Simulator; import de.tudarmstadt.maki.simonstrator.api.Event; import de.tudarmstadt.maki.simonstrator.api.EventHandler; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationListener; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationSensor; /** * Update 15.03.16 added support for multiple listeners (however, frequency * etc. is immune after the first request is registered.) * * @author Bjoern Richerzhagen * @version 1.0, Mar 15, 2016 */ public class LocationRequestImpl implements LocationRequest, EventHandler { private boolean immune = false; private long interval = 1 * Simulator.MINUTE_UNIT; private int priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY; private Location lastLocation = null; private List listeners = new LinkedList(); private int eventTypeSeq = 0; private SimHost host; private LocationSensor locationSensor; public LocationRequestImpl(SimHost host, LocationSensor locationSensor) { this.host = host; this.locationSensor = locationSensor; } protected void cancel(LocationListener listener) { boolean removed = listeners.remove(listener); if (listeners.isEmpty()) { // upcoming event is no longer valid! eventTypeSeq++; } assert removed; } protected void immunizeAndStart(LocationListener listener) { immune = true; assert interval > 0; if (listeners.isEmpty()) { // Only start once! lastLocation = null; Event.scheduleImmediately(this, null, eventTypeSeq); } else { // Fire each new listener at least once listener.onLocationChanged(host, locationSensor.getLastLocation()); } listeners.add(listener); } @Override public void setInterval(long interval) { if (!immune) { this.interval = interval; } } @Override public void setPriority(int priority) { if (!immune) { this.priority = priority; } } @Override public void eventOccurred(Object content, int type) { if (eventTypeSeq != type) { /* * Discard invalid events caused when a client cancels updates * but reactivates the request within the update frequency * interval. In this case, the old events continue rescheduling * themselves. */ return; } if (!listeners.isEmpty()) { // Only reschedule, if at least one listener is ... listening Location newLoc = locationSensor.getLastLocation(); listeners.forEach((LocationListener listener) -> listener .onLocationChanged(host, newLoc)); lastLocation = newLoc; Event.scheduleWithDelay(interval, this, null, eventTypeSeq); } } }