Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package puppy.hanii.bukkit.library.events;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- /**
- * Represents an event.
- *
- * The event can be raised, which then calls the onEvent method in each of the
- * event listeners registered to it. Event listeners that return true for
- * IsPrimaryListener() are supposed to represent what gets called as the primary
- * functionality of the events, with all other listeners coming after it.
- *
- * The reasoning behind this is so that the primary functionality can be
- * cancelled properly by a listener.
- * @param <T> The datatype of the event args.
- * @author Hanii Puppy <[email protected]>
- */
- public class Event<T extends EventArgs>
- {
- //<editor-fold defaultstate="collapsed" desc="Subclasses">
- public static enum ListenerPriority
- {
- VeryEarly,
- Early,
- Normal,
- Late,
- VeryLate,
- Monitor,
- Post
- }
- public static class EventWithArgs<Args extends EventArgs>
- {
- public EventWithArgs(Event<Args> event, Args args)
- {
- this.event = event;
- this.args = args;
- }
- Event<Args> event;
- Args args;
- public Event<Args> getEvent()
- { return event; }
- public Args getArgs()
- { return args; }
- }
- //</editor-fold>
- //<editor-fold defaultstate="collapsed" desc="Initialisation">
- /**
- * The constructor.
- */
- public Event()
- {
- EarlyListeners = new ArrayList<EventListener<T>>();
- Listeners = new ArrayList<EventListener<T>>();
- LateListeners = new ArrayList<EventListener<T>>();
- VeryLateListeners = new ArrayList<EventListener<T>>();
- MonitorListeners = new ArrayList<EventListener<T>>();
- PostListeners = new ArrayList<EventListener<T>>();
- ListenersBusyFlag = new Object();
- }
- //</editor-fold>
- //<editor-fold defaultstate="collapsed" desc="Variables">
- List<EventListener<T>> VeryEarlyListeners;
- List<EventListener<T>> EarlyListeners;
- List<EventListener<T>> Listeners;
- List<EventListener<T>> LateListeners;
- List<EventListener<T>> VeryLateListeners;
- List<EventListener<T>> MonitorListeners;
- List<EventListener<T>> PostListeners;
- final Object ListenersBusyFlag;
- //</editor-fold>
- //<editor-fold defaultstate="collapsed" desc="Methods">
- /**
- * Checks whether or not any of the registered listeners to the event are currently blocking (cancelling) the event.
- * @return Whether or not the event is being cancelled.
- * @example if(!SomeEvent.IsCancelled()) SomeEvent.UncheckedRaise(this, "Some text.");
- */
- public boolean IsCancelled()
- {
- synchronized(ListenersBusyFlag)
- {
- for(EventListener<T> i : VeryEarlyListeners)
- if(i.CancelsEvent())
- return true;
- for(EventListener<T> i : EarlyListeners)
- if(i.CancelsEvent())
- return true;
- for(EventListener<T> i : Listeners)
- if(i.CancelsEvent())
- return true;
- for(EventListener<T> i : LateListeners)
- if(i.CancelsEvent())
- return true;
- for(EventListener<T> i : VeryLateListeners)
- if(i.CancelsEvent())
- return true;
- for(EventListener<T> i : MonitorListeners)
- if(i.CancelsEvent())
- return true;
- // Cannot cancel from PostListener
- }
- return false; // return false if no elements in PrimaryListeners nor Listeners returns true for i.CancelsEvent(). Else return true.
- }
- /**
- * Raises the event.
- *
- * Calls the onEvent method of all Primary listeners, then the onEvent
- * method of all other listeners.
- * @param sender The object that raised the event. Should normally be "this".
- * @param args The custom arguments to be passed to the event listeners.
- * @example Event SomeEvent = new Event<String>();
- * @example SomeEvent.Raise(this, "Some text.");
- */
- public void Raise(Object sender, T args)
- { if(!IsCancelled()) UncheckedRaise(sender, args); }
- /**
- * Raises the event without checking whether or not it's cancelled.
- * @param sender The object that raised the event. Should normally be "this".
- * @param args The custom arguments to be passed to the event listeners.
- * @example Event SomeEvent = new Event<String>();
- * @example SomeEvent.UncheckedRaise(this, "Some text.");
- */
- public void UncheckedRaise(Object sender, T args)
- {
- synchronized(ListenersBusyFlag)
- {
- if(args.UsedAlreadyPreEvent)
- throw new EventArgsMultipleUseException("A fresh EventArgs should be created for every event raise. EventArgs should not be re-used.");
- args.UsedAlreadyPreEvent = true;
- for(EventListener<T> i : VeryEarlyListeners)
- i.onEvent(sender, args);
- for(EventListener<T> i : EarlyListeners)
- i.onEvent(sender, args);
- for(EventListener<T> i : Listeners)
- i.onEvent(sender, args);
- for(EventListener<T> i : LateListeners)
- i.onEvent(sender, args);
- for(EventListener<T> i : VeryLateListeners)
- i.onEvent(sender, args);
- for(EventListener<T> i : MonitorListeners)
- i.onEvent(sender, args);
- }
- }
- public void RaisePostEvent(Object sender, T args)
- {
- synchronized(ListenersBusyFlag)
- {
- if(args.UsedAlreadyPostEvent)
- throw new EventArgsMultipleUseException("A fresh EventArgs should be created for every event raise. EventArgs should not be re-used.");
- args.UsedAlreadyPostEvent = true;
- for(EventListener<T> i : PostListeners)
- i.onEvent(sender, args);
- }
- }
- /**
- * Register a new event event listener to the event.
- * @param Listener The listener to register.
- * @example Event<String> SomeEvent.Register(new EventListener<EventArgs>()
- * @example {
- * @example (at)Override
- * @example public void onEvent(object sender, EventArgs args)
- * @example { Whatever you want to happen }
- * @example });
- */
- public void Register(EventListener<T> Listener)
- {
- if(Listener == null)
- throw new NullPointerException();
- else
- {
- synchronized(ListenersBusyFlag)
- {
- switch(Listener.getPriority())
- {
- case VeryEarly: VeryEarlyListeners .add(Listener); break;
- case Early: EarlyListeners .add(Listener); break;
- case Normal: Listeners .add(Listener); break;
- case Late: LateListeners .add(Listener); break;
- case VeryLate: VeryLateListeners .add(Listener); break;
- case Monitor: MonitorListeners .add(Listener); break;
- case Post: PostListeners .add(Listener); break;
- }
- }
- }
- }
- /**
- * Deregister a previously registered listener.
- * @param Listener The listener to deregister.
- * @return Whether or not a listener was removed. If it wasn't, it's likely that it wasn't registered in the first place.
- * @example SomeEvent.Deregister(SomeListener);
- */
- public boolean Deregister(EventListener<T> Listener)
- {
- synchronized(ListenersBusyFlag)
- {
- boolean removed = VeryLateListeners.remove(Listener);
- if(!removed) removed = LateListeners.remove(Listener);
- if(!removed) removed = Listeners.remove(Listener);
- if(!removed) removed = EarlyListeners.remove(Listener);
- if(!removed) removed = VeryEarlyListeners.remove(Listener);
- if(!removed) removed = MonitorListeners.remove(Listener);
- if(!removed) removed = PostListeners.remove(Listener);
- return removed;
- }
- }
- public static void raiseMultipleEvents(Object sender, boolean shareCancellation, EventWithArgs<? extends EventArgs>... events)
- {
- boolean cancelled = false;
- // If sharing cancellation, check if any of the event-args are cancelled before being raised. If any of them are, the event args for all are cancelled.
- if(shareCancellation)
- for(int i = 0; i < events.length && !cancelled; i++)
- if(events[i].getArgs().isCancelled())
- cancelled = true;
- // Call listeners marked VeryEarly. Throw exception if args has already been used.
- // If sharing cancellation, set the arg's cancellation state to the cancelled variable before calling,
- // and set cancelled to the arg's cancellation state after.
- for(EventWithArgs<? extends EventArgs> i : events)
- if(i.getArgs().UsedAlreadyPreEvent)
- throw new EventArgsMultipleUseException("A fresh EventArgs should be created for every event raise. EventArgs should not be re-used.");
- for(EventWithArgs<? extends EventArgs> i : events)
- {
- if(shareCancellation)
- i.getArgs().setCancelled(cancelled);
- for(EventListener<? extends EventArgs> j : i.event.VeryEarlyListeners)
- //j.onEvent(sender, i.getArgs());
- j.onEvent(sender, i.getArgs());
- if(shareCancellation)
- cancelled = i.getArgs().isCancelled();
- }
- for(EventWithArgs<? extends EventArgs> i : events)
- {
- if(shareCancellation)
- i.getArgs().setCancelled(cancelled);
- for(EventListener<? extends EventArgs> j : i.event.EarlyListeners)
- j.onEvent(sender, i.getArgs());
- if(shareCancellation)
- cancelled = i.getArgs().isCancelled();
- }
- // to be finished.
- }
- //</editor-fold>
- }
Advertisement
Add Comment
Please, Sign In to add comment