/*******************************************************************************
* Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*
* Contributors:
* Mathew A. Nelson
* - Initial API and implementation
* Flemming N. Larsen
* - Optimized for Java 5
* - Updated Javadocs
* - Removed try-catch(ClassCastException) from compareTo()
* - Changed compareTo() to first and foremost compare the events based on
* their event times, and secondly to compare the priorities if the event
* times are equals. Previously, the priorities were compared first, and
* secondly the event times if the priorities were equal.
* This change was made to sort the event queues of the robots in
* chronological so that the older events are listed before newer events
*******************************************************************************/
package robocode;
import net.sf.robocode.peer.IRobotStatics;
import net.sf.robocode.security.IHiddenEventHelper;
import net.sf.robocode.io.Logger;
import robocode.robotinterfaces.IBasicRobot;
import java.awt.*;
import java.io.Serializable;
/**
* The superclass of all Robocode events.
*
* @author Mathew A. Nelson (original)
* @author Flemming N. Larsen (contributor)
*/
public abstract class Event implements Comparable<Event>, Serializable {
private static final long serialVersionUID = 1L;
private static final int DEFAULT_PRIORITY = 80;
private long time;
private int priority;
// time is valid only after adding to event manager on proxy side, we do not update it on Battle side
private transient boolean addedToQueue;
/**
* Called by the game to create a new Event.
*/
public Event() {
super();
}
/**
* Compares this event to another event regarding precedence.
* The event precedence is first and foremost determined by the event time,
* secondly the event priority, and lastly specific event information.
* <p/>
* This method will first compare the time of each event. If the event time
* is the same for both events, then this method compared the priority of
* each event. If the event priorities are equals, then this method will
* compare the two event based on specific event information.
* <p/>
* This method is called by the game in order to sort the event queue of a
* robot to make sure the events are listed in chronological order.
* <p/>
*
* @param event the event to compare to this event.
* @return a negative value if this event has higher precedence, i.e. must
* be listed before the specified event. A positive value if this event
* has a lower precedence, i.e. must be listed after the specified event.
* 0 means that the precedence of the two events are equal.
*/
public int compareTo(Event event) {
// Compare the time difference which has precedence over priority.
int timeDiff = (int) (time - event.time);
if (timeDiff != 0) {
return timeDiff; // Time differ
}
// Same time -> Compare the difference in priority
int priorityDiff = event.getPriority() - getPriority();
if (priorityDiff != 0) {
return priorityDiff; // Priority differ
}
// Same time and priority -> Compare specific event types
// look at overrides in ScannedRobotEvent and HitRobotEvent
// No difference found
return 0;
}
/**
* Returns the priority of this event.
* An event priority is a value from 0 - 99. The higher value, the higher
* priority. The default priority is 80.
*
* @return the priority of this event
*/
public int getPriority() {
return priority;
}
/**
* Returns the time this event occurred.
*
* @return the time this event occurred.
*/
// We rolled back the use of 'final' here due to Bug [2928688], where some old robots do override getTime()
// with their own events that inherits from robocode.Event.
public /* final*/long getTime() {
return time;
}
/**
* Called by the game to set the priority of an event to the priority your
* robot specified for this type of event (or the default priority).
* <p/>
* An event priority is a value from 0 - 99. The higher value, the higher
* priority. The default priority is 80.
*
* Could be called by robot on events which are not managed by game.
* If the event is added into EventQueue, the time will be overridden.
*
* @param newPriority the new priority of this event
* @see AdvancedRobot#setEventPriority(String, int)
*/
public final void setPriority(int newPriority) {
if (addedToQueue) {
Logger.printlnToRobotsConsole("SYSTEM: After the event was added to queue, priority can't be changed.");
return;
}
if (newPriority < 0) {
Logger.printlnToRobotsConsole("SYSTEM: Priority must be between 0 and 99");
Logger.printlnToRobotsConsole("SYSTEM: Priority for " + this.getClass().getName() + " will be 0");
newPriority = 0;
} else if (newPriority > 99) {
Logger.printlnToRobotsConsole("SYSTEM: Priority must be between 0 and 99");
Logger.printlnToRobotsConsole("SYSTEM: Priority for " + this.getClass().getName() + " will be 99");
newPriority = 99;
}
priority = newPriority;
}
/**
* Sets the time when this event occurred.
*
* @param time the time when this event occurred.
*/
// this method is invisible on RobotAPI
private void setTimeHidden(long time) {
// we do not replace time which is set by robot to the future
if (this.time < time) {
this.time = time;
}
addedToQueue = true;
}
/**
* Could be caled by robot to assign the time to events which are not managed by game.
* If the event is added into EventQueue, the time could be overriden
*
* @param newTime the time this event occurred
*/
public void setTime(long newTime) {
if (!addedToQueue) {
time = newTime;
} else {
Logger.printlnToRobotsConsole("SYSTEM: After the event was added to queue, time can't be changed.");
}
}
/**
* Dispatch this event for a robot, it's statistics, and graphics context.
*
* @param robot the robot to dispatch to.
* @param statics the statistics to dispatch to.
* @param graphics the graphics to dispatch to.
*/
// this method is invisible on RobotAPI
void dispatch(IBasicRobot robot, IRobotStatics statics, Graphics2D graphics) {}
/**
* Returns the default priority of this event class.
*
* @return the default priority of this event class.
*/
// this method is invisible on RobotAPI
int getDefaultPriority() {
return DEFAULT_PRIORITY;
}
/**
* Checks if this event must be delivered event after timeout.
*
* @return {@code true} when this event must be delivered even after timeout; {@code false} otherwise.
*/
// this method is invisible on RobotAPI
boolean isCriticalEvent() {
return false;
}
// this method is invisible on RobotAPI
byte getSerializationType() {
throw new Error("Serialization not supported on this event type");
}
/**
* Creates a hidden event helper for accessing hidden methods on this object.
*
* @return a hidden event helper.
*/
// this method is invisible on RobotAPI
static IHiddenEventHelper createHiddenHelper() {
return new HiddenEventHelper();
}
// this class is invisible on RobotAPI
private static class HiddenEventHelper implements IHiddenEventHelper {
public void setTime(Event event, long newTime) {
event.setTimeHidden(newTime);
}
public void setDefaultPriority(Event event) {
event.setPriority(event.getDefaultPriority());
}
public void setPriority(Event event, int newPriority) {
event.setPriority(newPriority);
}
public boolean isCriticalEvent(Event event) {
return event.isCriticalEvent();
}
public void dispatch(Event event, IBasicRobot robot, IRobotStatics statics, Graphics2D graphics) {
event.dispatch(robot, statics, graphics);
}
public byte getSerializationType(Event event) {
return event.getSerializationType();
}
}
}