001    package net.minecraftforge.event;
002    
003    import static java.lang.annotation.ElementType.TYPE;
004    import static java.lang.annotation.RetentionPolicy.RUNTIME;
005    
006    import java.lang.annotation.Retention;
007    import java.lang.annotation.Target;
008    
009    
010    /**
011     * Base Event class that all other events are derived from
012     */
013    public class Event
014    {
015        @Retention(value = RUNTIME)
016        @Target(value = TYPE)
017        public @interface HasResult{}
018    
019        public enum Result
020        {
021            DENY,
022            DEFAULT,
023            ALLOW
024        }
025    
026        private boolean isCanceled = false;
027        private final boolean isCancelable;
028        private Result result = Result.DEFAULT;
029        private final boolean hasResult;
030        private static ListenerList listeners = new ListenerList();
031        
032        public Event()
033        {
034            setup();
035            isCancelable = hasAnnotation(Cancelable.class);
036            hasResult = hasAnnotation(HasResult.class);
037        }
038    
039        private boolean hasAnnotation(Class annotation)
040        {
041            Class cls = this.getClass();
042            while (cls != Event.class)
043            {
044                if (cls.isAnnotationPresent(Cancelable.class))
045                {
046                    return true;
047                }
048                cls = cls.getSuperclass();
049            }
050            return false;
051        }
052    
053        /**
054         * Determine if this function is cancelable at all. 
055         * @return If access to setCanceled should be allowed
056         */
057        public boolean isCancelable()
058        {
059            return isCancelable;
060        }
061    
062        /**
063         * Determine if this event is canceled and should stop executing.
064         * @return The current canceled state
065         */
066        public boolean isCanceled()
067        {
068            return isCanceled;
069        }
070    
071        /**
072         * Sets the state of this event, not all events are cancelable, and any attempt to
073         * cancel a event that can't be will result in a IllegalArgumentException.
074         * 
075         * The functionality of setting the canceled state is defined on a per-event bases.
076         * 
077         * @param cancel The new canceled value
078         */
079        public void setCanceled(boolean cancel)
080        {
081            if (!isCancelable())
082            {
083                throw new IllegalArgumentException("Attempted to cancel a uncancelable event");
084            }
085            isCanceled = cancel;
086        }
087    
088        /**
089         * Determines if this event expects a significant result value.
090         */
091        public boolean hasResult()
092        {
093            return hasResult;
094        }
095    
096        /**
097         * Returns the value set as the result of this event
098         */
099        public Result getResult()
100        {
101            return result;
102        }
103    
104        /**
105         * Sets the result value for this event, not all events can have a result set, and any attempt to
106         * set a result for a event that isn't expecting it will result in a IllegalArgumentException.
107         * 
108         * The functionality of setting the result is defined on a per-event bases.
109         * 
110         * @param value The new result
111         */
112        public void setResult(Result value)
113        {
114            result = value;
115        }
116        /**
117         * Called by the base constructor, this is used by ASM generated 
118         * event classes to setup various functionality such as the listener's list.
119         */
120        protected void setup()
121        {
122        }
123        
124        /**
125         * Returns a ListenerList object that contains all listeners
126         * that are registered to this event.
127         * 
128         * @return Listener List
129         */
130        public ListenerList getListenerList()
131        {
132            return listeners;
133        }
134    }