2012-08-05 05:45:31 +00:00
|
|
|
package net.minecraftforge.event;
|
|
|
|
|
2012-10-22 07:29:28 +00:00
|
|
|
import static java.lang.annotation.ElementType.TYPE;
|
|
|
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|
|
|
|
|
|
|
import java.lang.annotation.Retention;
|
|
|
|
import java.lang.annotation.Target;
|
2013-03-26 17:38:55 +00:00
|
|
|
import java.util.Map;
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
2012-10-22 07:29:28 +00:00
|
|
|
|
2012-08-05 05:45:31 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Base Event class that all other events are derived from
|
|
|
|
*/
|
|
|
|
public class Event
|
|
|
|
{
|
2012-10-22 07:29:28 +00:00
|
|
|
@Retention(value = RUNTIME)
|
|
|
|
@Target(value = TYPE)
|
|
|
|
public @interface HasResult{}
|
|
|
|
|
2012-09-27 04:18:18 +00:00
|
|
|
public enum Result
|
|
|
|
{
|
|
|
|
DENY,
|
|
|
|
DEFAULT,
|
|
|
|
ALLOW
|
|
|
|
}
|
|
|
|
|
2012-08-05 05:45:31 +00:00
|
|
|
private boolean isCanceled = false;
|
2012-08-07 08:24:06 +00:00
|
|
|
private final boolean isCancelable;
|
2012-10-22 07:29:28 +00:00
|
|
|
private Result result = Result.DEFAULT;
|
|
|
|
private final boolean hasResult;
|
2012-08-05 05:45:31 +00:00
|
|
|
private static ListenerList listeners = new ListenerList();
|
2013-03-26 17:38:55 +00:00
|
|
|
|
|
|
|
private static final Map<Class, Map<Class, Boolean>> annotationMap = new ConcurrentHashMap<Class, Map<Class, Boolean>>();
|
2012-08-05 05:45:31 +00:00
|
|
|
|
|
|
|
public Event()
|
|
|
|
{
|
|
|
|
setup();
|
2012-10-22 07:29:28 +00:00
|
|
|
isCancelable = hasAnnotation(Cancelable.class);
|
|
|
|
hasResult = hasAnnotation(HasResult.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean hasAnnotation(Class annotation)
|
|
|
|
{
|
2013-03-26 17:38:55 +00:00
|
|
|
Class me = this.getClass();
|
|
|
|
Map<Class, Boolean> list = annotationMap.get(me);
|
|
|
|
if (list == null)
|
|
|
|
{
|
|
|
|
list = new ConcurrentHashMap<Class, Boolean>();
|
|
|
|
annotationMap.put(me, list);
|
|
|
|
}
|
|
|
|
|
|
|
|
Boolean cached = list.get(annotation);
|
|
|
|
if (cached != null)
|
|
|
|
{
|
|
|
|
return cached;
|
|
|
|
}
|
|
|
|
|
|
|
|
Class cls = me;
|
2012-08-07 08:24:06 +00:00
|
|
|
while (cls != Event.class)
|
|
|
|
{
|
2013-03-26 17:38:55 +00:00
|
|
|
if (cls.isAnnotationPresent(annotation))
|
2012-08-07 08:24:06 +00:00
|
|
|
{
|
2013-03-26 17:38:55 +00:00
|
|
|
list.put(annotation, true);
|
2012-10-22 07:29:28 +00:00
|
|
|
return true;
|
2012-08-07 08:24:06 +00:00
|
|
|
}
|
2012-08-09 23:47:35 +00:00
|
|
|
cls = cls.getSuperclass();
|
2012-08-07 08:24:06 +00:00
|
|
|
}
|
2013-03-26 17:38:55 +00:00
|
|
|
|
|
|
|
list.put(annotation, false);
|
2012-10-22 07:29:28 +00:00
|
|
|
return false;
|
2012-08-05 05:45:31 +00:00
|
|
|
}
|
2012-10-22 07:29:28 +00:00
|
|
|
|
2012-08-05 05:45:31 +00:00
|
|
|
/**
|
|
|
|
* Determine if this function is cancelable at all.
|
|
|
|
* @return If access to setCanceled should be allowed
|
|
|
|
*/
|
|
|
|
public boolean isCancelable()
|
|
|
|
{
|
2012-08-07 08:24:06 +00:00
|
|
|
return isCancelable;
|
2012-08-05 05:45:31 +00:00
|
|
|
}
|
2012-10-22 07:29:28 +00:00
|
|
|
|
2012-08-05 05:45:31 +00:00
|
|
|
/**
|
|
|
|
* Determine if this event is canceled and should stop executing.
|
|
|
|
* @return The current canceled state
|
|
|
|
*/
|
|
|
|
public boolean isCanceled()
|
|
|
|
{
|
|
|
|
return isCanceled;
|
|
|
|
}
|
2012-10-22 07:29:28 +00:00
|
|
|
|
2012-08-05 05:45:31 +00:00
|
|
|
/**
|
|
|
|
* Sets the state of this event, not all events are cancelable, and any attempt to
|
|
|
|
* cancel a event that can't be will result in a IllegalArgumentException.
|
|
|
|
*
|
|
|
|
* The functionality of setting the canceled state is defined on a per-event bases.
|
|
|
|
*
|
|
|
|
* @param cancel The new canceled value
|
|
|
|
*/
|
|
|
|
public void setCanceled(boolean cancel)
|
|
|
|
{
|
|
|
|
if (!isCancelable())
|
|
|
|
{
|
|
|
|
throw new IllegalArgumentException("Attempted to cancel a uncancelable event");
|
|
|
|
}
|
|
|
|
isCanceled = cancel;
|
|
|
|
}
|
2012-10-22 07:29:28 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines if this event expects a significant result value.
|
|
|
|
*/
|
|
|
|
public boolean hasResult()
|
|
|
|
{
|
|
|
|
return hasResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the value set as the result of this event
|
|
|
|
*/
|
|
|
|
public Result getResult()
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the result value for this event, not all events can have a result set, and any attempt to
|
|
|
|
* set a result for a event that isn't expecting it will result in a IllegalArgumentException.
|
|
|
|
*
|
|
|
|
* The functionality of setting the result is defined on a per-event bases.
|
|
|
|
*
|
|
|
|
* @param value The new result
|
|
|
|
*/
|
|
|
|
public void setResult(Result value)
|
|
|
|
{
|
|
|
|
result = value;
|
|
|
|
}
|
2012-08-05 05:45:31 +00:00
|
|
|
/**
|
|
|
|
* Called by the base constructor, this is used by ASM generated
|
|
|
|
* event classes to setup various functionality such as the listener's list.
|
|
|
|
*/
|
|
|
|
protected void setup()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a ListenerList object that contains all listeners
|
|
|
|
* that are registered to this event.
|
|
|
|
*
|
|
|
|
* @return Listener List
|
|
|
|
*/
|
|
|
|
public ListenerList getListenerList()
|
|
|
|
{
|
|
|
|
return listeners;
|
|
|
|
}
|
|
|
|
}
|