/* * Minha.pt: middleware testing platform. * Copyright (c) 2011-2014, Universidade do Minho. * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package pt.minha.kernel.simulation; /** * A work unit in the event-driven simulation. Event code runs at * a specific simulation time in the context of a simulation timeline. * It can freely inspect and modify simulation state associated with * the timeline without concurrency issues. */ public abstract class Event implements Runnable, Comparable<Event> { private Timeline timeline; long time; /** * Create an event on a specific simulation time line. * @param timeline */ public Event(Timeline timeline) { this.timeline = timeline; this.time = -1; } /** * Utility method available while executing run(). * @return */ public Timeline getTimeline() { return timeline; } /** * Event code. */ public abstract void run(); /** * Reschedule the event. Can only be called from the event's target * timeline or when the simulation is stopped. This can be called even * if this event is currently scheduled. * * @param delay time delay in simulated nanoseconds */ public void schedule(long delay) { timeline.schedule(this, delay); } /** * Schedule the event using a (possibly) different timeline as * a reference. This should be used whenever there is no * guarantee that the event's target timeline is the same as * the currently running. This can only be called if the event * is not currently scheduled. * * @param delay time delay in simulated nanoseconds */ public void scheduleFrom(Timeline base, long delay) { base.schedule(this, delay); } void execute() { assert(time >= 0); time = -1; run(); } /** * Total order of events, sorted first by time and second by * object id. Assumes that Object.hashCode() is unique, a least * w.h.p. for events found concurrently within the same queue, thus * providing an unique id. */ @Override public int compareTo(Event other) { if (time != other.time) return Long.signum(time-other.time); return Integer.signum(hashCode()-other.hashCode()); } public String toString() { return super.toString()+"@["+time+"ns]"; } }