HaniiPuppy

Event class

Mar 10th, 2014
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.40 KB | None | 0 0
  1. package puppy.hanii.bukkit.library.events;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import java.util.List;
  6.  
  7. /**
  8.  * Represents an event.
  9.  *
  10.  * The event can be raised, which then calls the onEvent method in each of the
  11.  * event listeners registered to it. Event listeners that return true for
  12.  * IsPrimaryListener() are supposed to represent what gets called as the primary
  13.  * functionality of the events, with all other listeners coming after it.
  14.  *
  15.  * The reasoning behind this is so that the primary functionality can be
  16.  * cancelled properly by a listener.
  17.  * @param <T> The datatype of the event args.
  18.  * @author Hanii Puppy <[email protected]>
  19.  */
  20. public class Event<T extends EventArgs>
  21. {
  22.     //<editor-fold defaultstate="collapsed" desc="Subclasses">
  23.     public static enum ListenerPriority
  24.     {
  25.         VeryEarly,
  26.         Early,
  27.         Normal,
  28.         Late,
  29.         VeryLate,
  30.         Monitor,
  31.         Post
  32.     }
  33.    
  34.     public static class EventWithArgs<Args extends EventArgs>
  35.     {
  36.         public EventWithArgs(Event<Args> event, Args args)
  37.         {
  38.             this.event = event;
  39.             this.args = args;
  40.         }
  41.        
  42.         Event<Args> event;
  43.         Args args;
  44.        
  45.         public Event<Args> getEvent()
  46.         { return event; }
  47.        
  48.         public Args getArgs()
  49.         { return args; }
  50.     }
  51.     //</editor-fold>
  52.  
  53.     //<editor-fold defaultstate="collapsed" desc="Initialisation">
  54.     /**
  55.      * The constructor.
  56.      */
  57.     public Event()
  58.     {
  59.         EarlyListeners = new ArrayList<EventListener<T>>();
  60.         Listeners = new ArrayList<EventListener<T>>();
  61.         LateListeners = new ArrayList<EventListener<T>>();
  62.         VeryLateListeners = new ArrayList<EventListener<T>>();
  63.         MonitorListeners = new ArrayList<EventListener<T>>();
  64.         PostListeners = new ArrayList<EventListener<T>>();
  65.  
  66.         ListenersBusyFlag = new Object();
  67.     }
  68.     //</editor-fold>
  69.  
  70.     //<editor-fold defaultstate="collapsed" desc="Variables">
  71.     List<EventListener<T>> VeryEarlyListeners;
  72.     List<EventListener<T>> EarlyListeners;
  73.     List<EventListener<T>> Listeners;
  74.     List<EventListener<T>> LateListeners;
  75.     List<EventListener<T>> VeryLateListeners;
  76.     List<EventListener<T>> MonitorListeners;
  77.     List<EventListener<T>> PostListeners;
  78.  
  79.     final Object ListenersBusyFlag;
  80.     //</editor-fold>
  81.  
  82.     //<editor-fold defaultstate="collapsed" desc="Methods">
  83.     /**
  84.      * Checks whether or not any of the registered listeners to the event are currently blocking (cancelling) the event.
  85.      * @return Whether or not the event is being cancelled.
  86.      * @example if(!SomeEvent.IsCancelled()) SomeEvent.UncheckedRaise(this, "Some text.");
  87.      */
  88.     public boolean IsCancelled()
  89.     {
  90.         synchronized(ListenersBusyFlag)
  91.         {
  92.             for(EventListener<T> i : VeryEarlyListeners)
  93.                 if(i.CancelsEvent())
  94.                     return true;
  95.            
  96.             for(EventListener<T> i : EarlyListeners)
  97.                 if(i.CancelsEvent())
  98.                     return true;
  99.  
  100.             for(EventListener<T> i : Listeners)
  101.                 if(i.CancelsEvent())
  102.                     return true;
  103.  
  104.             for(EventListener<T> i : LateListeners)
  105.                 if(i.CancelsEvent())
  106.                     return true;
  107.  
  108.             for(EventListener<T> i : VeryLateListeners)
  109.                 if(i.CancelsEvent())
  110.                     return true;
  111.  
  112.             for(EventListener<T> i : MonitorListeners)
  113.                 if(i.CancelsEvent())
  114.                     return true;
  115.            
  116.             // Cannot cancel from PostListener
  117.         }
  118.  
  119.         return false; // return false if no elements in PrimaryListeners nor Listeners returns true for i.CancelsEvent(). Else return true.
  120.     }
  121.  
  122.     /**
  123.      * Raises the event.
  124.      *
  125.      * Calls the onEvent method of all Primary listeners, then the onEvent
  126.      * method of all other listeners.
  127.      * @param sender The object that raised the event. Should normally be "this".
  128.      * @param args The custom arguments to be passed to the event listeners.
  129.      * @example Event SomeEvent = new Event<String>();
  130.      * @example SomeEvent.Raise(this, "Some text.");
  131.      */
  132.     public void Raise(Object sender, T args)
  133.     { if(!IsCancelled()) UncheckedRaise(sender, args); }
  134.  
  135.     /**
  136.      * Raises the event without checking whether or not it's cancelled.
  137.      * @param sender The object that raised the event. Should normally be "this".
  138.      * @param args The custom arguments to be passed to the event listeners.
  139.      * @example Event SomeEvent = new Event<String>();
  140.      * @example SomeEvent.UncheckedRaise(this, "Some text.");
  141.      */
  142.     public void UncheckedRaise(Object sender, T args)
  143.     {
  144.         synchronized(ListenersBusyFlag)
  145.         {
  146.             if(args.UsedAlreadyPreEvent)
  147.                 throw new EventArgsMultipleUseException("A fresh EventArgs should be created for every event raise. EventArgs should not be re-used.");
  148.            
  149.             args.UsedAlreadyPreEvent = true;
  150.            
  151.             for(EventListener<T> i : VeryEarlyListeners)
  152.                 i.onEvent(sender, args);
  153.            
  154.             for(EventListener<T> i : EarlyListeners)
  155.                 i.onEvent(sender, args);
  156.  
  157.             for(EventListener<T> i : Listeners)
  158.                 i.onEvent(sender, args);
  159.  
  160.             for(EventListener<T> i : LateListeners)
  161.                 i.onEvent(sender, args);
  162.  
  163.             for(EventListener<T> i : VeryLateListeners)
  164.                 i.onEvent(sender, args);
  165.  
  166.             for(EventListener<T> i : MonitorListeners)
  167.                 i.onEvent(sender, args);
  168.         }
  169.     }
  170.    
  171.     public void RaisePostEvent(Object sender, T args)
  172.     {
  173.         synchronized(ListenersBusyFlag)
  174.         {
  175.             if(args.UsedAlreadyPostEvent)
  176.                 throw new EventArgsMultipleUseException("A fresh EventArgs should be created for every event raise. EventArgs should not be re-used.");
  177.            
  178.             args.UsedAlreadyPostEvent = true;
  179.            
  180.             for(EventListener<T> i : PostListeners)
  181.                 i.onEvent(sender, args);
  182.         }
  183.     }
  184.  
  185.     /**
  186.      * Register a new event event listener to the event.
  187.      * @param Listener The listener to register.
  188.      * @example Event<String> SomeEvent.Register(new EventListener<EventArgs>()
  189.      * @example {
  190.      * @example (at)Override
  191.      * @example public void onEvent(object sender, EventArgs args)
  192.      * @example { Whatever you want to happen }
  193.      * @example });
  194.      */
  195.     public void Register(EventListener<T> Listener)
  196.     {
  197.         if(Listener == null)
  198.             throw new NullPointerException();
  199.         else
  200.         {
  201.             synchronized(ListenersBusyFlag)
  202.             {
  203.                 switch(Listener.getPriority())
  204.                 {
  205.                     case VeryEarly: VeryEarlyListeners  .add(Listener); break;
  206.                     case Early:     EarlyListeners      .add(Listener); break;
  207.                     case Normal:    Listeners           .add(Listener); break;
  208.                     case Late:      LateListeners       .add(Listener); break;
  209.                     case VeryLate:  VeryLateListeners   .add(Listener); break;
  210.                     case Monitor:   MonitorListeners    .add(Listener); break;
  211.                     case Post:      PostListeners       .add(Listener); break;
  212.                 }
  213.             }
  214.         }
  215.     }
  216.  
  217.     /**
  218.      * Deregister a previously registered listener.
  219.      * @param Listener The listener to deregister.
  220.      * @return Whether or not a listener was removed. If it wasn't, it's likely that it wasn't registered in the first place.
  221.      * @example SomeEvent.Deregister(SomeListener);
  222.      */
  223.     public boolean Deregister(EventListener<T> Listener)
  224.     {
  225.         synchronized(ListenersBusyFlag)
  226.         {
  227.             boolean removed = VeryLateListeners.remove(Listener);
  228.             if(!removed) removed = LateListeners.remove(Listener);
  229.             if(!removed) removed = Listeners.remove(Listener);
  230.             if(!removed) removed = EarlyListeners.remove(Listener);
  231.             if(!removed) removed = VeryEarlyListeners.remove(Listener);
  232.             if(!removed) removed = MonitorListeners.remove(Listener);
  233.             if(!removed) removed = PostListeners.remove(Listener);
  234.  
  235.             return removed;
  236.         }
  237.     }
  238.    
  239.     public static void raiseMultipleEvents(Object sender, boolean shareCancellation, EventWithArgs<? extends EventArgs>... events)
  240.     {
  241.         boolean cancelled = false;
  242.        
  243.         // 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.
  244.         if(shareCancellation)
  245.             for(int i = 0; i < events.length && !cancelled; i++)
  246.                 if(events[i].getArgs().isCancelled())
  247.                     cancelled = true;
  248.        
  249.         // Call listeners marked VeryEarly. Throw exception if args has already been used.
  250.         // If sharing cancellation, set the arg's cancellation state to the cancelled variable before calling,
  251.         // and set cancelled to the arg's cancellation state after.
  252.        
  253.         for(EventWithArgs<? extends EventArgs> i : events)
  254.             if(i.getArgs().UsedAlreadyPreEvent)
  255.                 throw new EventArgsMultipleUseException("A fresh EventArgs should be created for every event raise. EventArgs should not be re-used.");
  256.        
  257.         for(EventWithArgs<? extends EventArgs> i : events)
  258.         {
  259.             if(shareCancellation)
  260.                 i.getArgs().setCancelled(cancelled);
  261.            
  262.             for(EventListener<? extends EventArgs> j : i.event.VeryEarlyListeners)
  263.                 //j.onEvent(sender, i.getArgs());
  264.                 j.onEvent(sender, i.getArgs());
  265.            
  266.             if(shareCancellation)
  267.                 cancelled = i.getArgs().isCancelled();
  268.         }
  269.        
  270.         for(EventWithArgs<? extends EventArgs> i : events)
  271.         {
  272.             if(shareCancellation)
  273.                 i.getArgs().setCancelled(cancelled);
  274.            
  275.             for(EventListener<? extends EventArgs> j : i.event.EarlyListeners)
  276.                 j.onEvent(sender, i.getArgs());
  277.            
  278.             if(shareCancellation)
  279.                 cancelled = i.getArgs().isCancelled();
  280.         }
  281.        
  282.         // to be finished.
  283.     }
  284.     //</editor-fold>
  285. }
Advertisement
Add Comment
Please, Sign In to add comment