Class EventListeners<T extends Event>

java.lang.Object
com.prineside.tdi2.events.EventListeners<T>
Type Parameters:
T - type of listener class

public final class EventListeners<T extends Event> extends Object

Contains a list of listeners for a specific event type. Thread safe.

Listeners may have up to 8 different (binary) flags set to control their behavior. Flags are being set as a bit mask which takes 1 byte:

  • 0b1 / 1 / 1 << 1 / FLAG_AUTO_PRIORITY - set by the EventListeners automatically, ignored if set manually. Marks listeners to decide their auto-priority
  • 0b10 / 2 / 1 << 2 / FLAG_AFFECTS_STATE - can be used to denote listener as state-affecting, normally used only in a game session. By default, all listeners are not considered to be state-affecting, thus will not be serialized (will throw exception if you try), will not affect the order and priorities of the state-affecting listeners and will not be compared during sync checks. For example, if your listener gives score to the player = state-affecting, forces some graphics / ui to update = not-state-affecting. Do not add state-affecting listeners from non-state code like UI events as this will result in a desync.
  • 0b100 / 4 / 1 << 3 / FLAG_PERSISTENT - listeners marked with this flag will survive `EventDispatcher.reset(false)`
  • Other flags / bytes (0b11111000) may depend on custom implementation of EventDispatcher. By default, you are free to use them as you wish with the default implementation of EventDispatcher
  • Field Details

  • Constructor Details

    • EventListeners

      public EventListeners(Class<?> eventClass)
  • Method Details

    • getEntriesBackingArray

      public EventListeners.Entry<T>[] getEntriesBackingArray()
      Iterate from 0 to size(), may contain nulls
      
               for (int i = 0; i < listeners.size(); i++) {
                   EventListeners.Entry<?> entry = listeners.getEntriesBackingArray()[i];
                   if (entry == null) continue;
                   ...
               }
       
    • trigger

      public void trigger(T event)
      Notify listeners about the event
      Parameters:
      event - event to pass to the listeners
    • getEventClass

      public Class<?> getEventClass()
      Returns:
      event type which is handled by this instance and is being passed to listeners
    • contains

      public boolean contains(Listener<T> listener)
      Check if listener group contains a listener
      Parameters:
      listener - listener to check
      Returns:
      true if listener is added to this group
    • getStateHash

      public int getStateHash()
    • getStateAffectingEntriesCount

      public int getStateAffectingEntriesCount()
      Returns:
      number of state-affecting listeners
    • getNonStateAffectingEntriesCount

      public int getNonStateAffectingEntriesCount()
      Returns:
      number of non-state-affecting listeners
    • getLoops

      public int getLoops()
      Returns:
      loop depth of the current `trigger` iteration. Will be 0 if event is not being triggered at the moment. Same event type can be triggered while it is being notified about (for example, some listener of EnemyDie kills some other enemy, which in turn triggers a new EnemyDie event), in which case this value will be higher than 1.
    • add

      public EventListeners.Entry<T> add(Listener<T> listener)
      Add listener without flags, with auto priority. Note: listener will only get FLAG_AUTO_PRIORITY (not state-affecting, not persistent etc). Warning: listener won't be serialized.
      Returns:
      added entry, which can be configured (for example, given a name or description)
    • addWithPriority

      public EventListeners.Entry<T> addWithPriority(Listener<T> listener, int priority)
      Add listener without flags, with manual priority. Note: flags will be 0 (not state-affecting, not persistent etc). Warning: listener won't be serialized.
      Returns:
      added entry, which can be configured (for example, given a name or description)
    • addStateAffectingWithPriority

      public EventListeners.Entry<T> addStateAffectingWithPriority(Listener<T> listener, int priority)
      Add listener with STATE_AFFECTING flag, with manual priority. Listener will be serialized.
      Returns:
      added entry, which can be configured (for example, given a name or description)
    • addWithFlags

      public EventListeners.Entry<T> addWithFlags(Listener<T> listener, int flags)
      Add listener and set its priority automatically (will be lower than priority of any of the existing listeners in stateful / not stateful groups) Throws exception if listener is already added. Checks for AFFECTS_STATE flag.
      Parameters:
      flags - will be set on the listener with FLAG_AUTO_PRIORITY set to true. Its AFFECTS_STATE bit will be checked to decide its priority among the listeners of the same state-affection Note: resulting flags will be exactly the same as in `flags` param but with FLAG_AUTO_PRIORITY set to true
      Returns:
      added entry, which can be configured (for example, given a name or description)
    • addStateAffecting

      public EventListeners.Entry<T> addStateAffecting(Listener<T> listener)
      Add state-affecting listener with an automatic priority. Will be serialized.
      Returns:
      added entry, which can be configured (for example, given a name or description)
    • addWithFlagsAndPriority

      public EventListeners.Entry<T> addWithFlagsAndPriority(Listener<T> listener, int flags, int priority)
      Throws exception if listener does not affect game state but has been added during iteration.
      Returns:
      added entry, which can be configured (for example, given a name or description)
    • remove

      public boolean remove(Listener<T> listener)
      Remove (unsubscribe) the listener. If event is being triggered, the listener will be removed at the end of the loop. Note: method references / lambdas are dynamic in Java, do not pass method references as listeners if you want to remove them later (or store them in some field first) as it is impossible to find a subscribed listener by method reference (new object is being created each time)
      Returns:
      true if listener has been removed, false if it was not scheduled and was not in the list of listeners to be added
    • getEventsTriggered

      public int getEventsTriggered()
      Returns:
      number of triggers (begin() calls)
    • getEventsStopped

      public int getEventsStopped()
      Returns:
      number of events stopped by listeners
    • size

      public int size()
      Returns:
      total number of listeners in the group
    • clear

      public void clear()
      Remove all listeners from this group. Will throw an exception if currently in a loop (getLoops() > 0)
    • describe

      public StringBuilder describe()
      Returns:
      string description of this group, for debugging purposes