Class Event<T>

java.lang.Object
org.quiltmc.qsl.base.api.event.Event<T>
Type Parameters:
T - the type of the invoker used to execute an event and the type of the callback

public final class Event<T> extends Object
An object which stores event callbacks.

The factory methods for Event allows the user to provide an implementation of T which is used to execute the callbacks stored in this event instance. This allows a user to control how iteration works, whether an event is cancelled after a specific callback is executed or to make an event parameter invoking.

Generally T should be a type which is a functional interface to allow callbacks registered to the event to be specified in a lambda, method reference form or implemented onto a class. A way to ensure that an interface is a functional interface is to place a FunctionalInterface annotation on the type. You can let T not be a functional interface, however it heavily complicates the process of implementing an invoker and only allows callback implementations to be done by implementing an interface onto a class or extending a class.

An Event can have phases, each callback is attributed to a phase (DEFAULT_PHASE if unspecified), and each phase can have a defined ordering. Each event phase is identified by a Identifier, ordering is done by explicitly stating that event phase A will run before event phase B, for example. See addPhaseOrdering(Identifier, Identifier) for more information.

The most common use of an event will be registering a callback which is executed by the event. To register a callback, pass an instance of T into register(T).


 // Events should use a dedicated functional interface for T rather than overloading multiple events to the same type
 // to allow those who implement using a class to implement multiple events.
 @FunctionalInterface
 public interface Example {
     void doSomething();
 }

 // You can also return this instance of Event from a method, may be useful where a parameter is needed to get
 // the right instance of Event.
 public static final Event<Example> EXAMPLE = Event.create(...); // implementation

 public void registerEvents() {
     // Since T is a functional interface, we can use the lambda form.
     EXAMPLE.register(() -> {
         // Do something
     });

     // Or we can use a method reference.
     EXAMPLE.register(this::runSomething);

     // Or implement T using a class.
     // You can also use an anonymous class here; for brevity that is not included.
     EXAMPLE.register(new ImplementedOntoClass());
 }

 public void runSomething() {
     // Do something else
 }

 // When implementing onto a class, the class must implement the same type as the event invoker.
 class ImplementedOntoClass implements Example {
     public void doSomething() {
         // Do something else again
     }
 }
 

Example: Executing an event

Executing an event is done by calling a method on the event invoker. Where T is Example, executing an event is done through the following:


 EXAMPLE.invoker().doSomething();
 
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final net.minecraft.util.Identifier
    The identifier of the default phase.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    addPhaseOrdering(@NotNull net.minecraft.util.Identifier firstPhase, @NotNull net.minecraft.util.Identifier secondPhase)
    Request that callbacks registered for one phase be executed before callbacks registered for another phase.
    static <T> @NotNull Event<T>
    create(@NotNull Class<? super T> type, @NotNull Function<T[],T> implementation)
    Creates a new instance of Event.
    static <T> @NotNull Event<T>
    create(@NotNull Class<? super T> type, T emptyImplementation, @NotNull Function<T[],T> implementation)
    Creates a new instance of Event.
    static <T> @NotNull Event<T>
    createWithPhases(@NotNull Class<? super T> type, @NotNull Function<T[],T> implementation, @NotNull net.minecraft.util.Identifier... defaultPhases)
    Create a new instance of Event with a list of default phases that get invoked in order.
    @NotNull Class<? super T>
    Returns the class of the type of the invoker used to execute an event and the class of the type of the callback.
    Returns the invoker instance used to execute callbacks.
    static void
    listenAll(@NotNull Object listener, @NotNull Event<?>... events)
    Registers the given listener of the listed events.
    void
    register(@NotNull net.minecraft.util.Identifier phaseIdentifier, T callback)
    Registers a callback to a specific phase of the event.
    void
    register(T callback)
    Register a callback to the event.
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

  • Method Details

    • create

      @NotNull public static <T> @NotNull Event<T> create(@NotNull @NotNull Class<? super T> type, @NotNull @NotNull Function<T[],T> implementation)
      Creates a new instance of Event.
      Type Parameters:
      T - the type of the invoker executed by the event
      Parameters:
      type - the class representing the type of the invoker that is executed by the event
      implementation - a function which generates an invoker implementation using an array of callbacks
      Returns:
      a new event instance
    • create

      @NotNull public static <T> @NotNull Event<T> create(@NotNull @NotNull Class<? super T> type, @NotNull T emptyImplementation, @NotNull @NotNull Function<T[],T> implementation)
      Creates a new instance of Event.

      This method adds a emptyImplementation parameter which provides an implementation of the invoker when no callbacks are registered. Generally this method should only be used when the code path is very hot, such as the render or tick loops. Otherwise the other create(Class, Function) method should work in 99% of cases with little to no performance overhead.

      Type Parameters:
      T - the type of the invoker executed by the event
      Parameters:
      type - the class representing the type of the invoker that is executed by the event
      emptyImplementation - the implementation of T to use when the array event has no callback registrations
      implementation - a function which generates an invoker implementation using an array of callbacks
      Returns:
      a new event instance
    • createWithPhases

      @NotNull public static <T> @NotNull Event<T> createWithPhases(@NotNull @NotNull Class<? super T> type, @NotNull @NotNull Function<T[],T> implementation, @NotNull @NotNull net.minecraft.util.Identifier... defaultPhases)
      Create a new instance of Event with a list of default phases that get invoked in order. Exposing the identifiers of the default phases as public static final constants is encouraged.

      An event phase is a named group of callbacks, which may be ordered before or after other groups of callbacks. This allows some callbacks to take priority over other callbacks. Adding separate events should be considered before making use of multiple event phases.

      Phases may be freely added to events created with any of the factory functions, however using this function is preferred for widely used event phases. If more phases are necessary, discussion with the author of the event is encouraged.

      Refer to addPhaseOrdering(net.minecraft.util.Identifier, net.minecraft.util.Identifier) for an explanation of event phases.

      Type Parameters:
      T - the type of the invoker executed by the event
      Parameters:
      type - the class representing the type of the invoker that is executed by the event
      implementation - a function which generates an invoker implementation using an array of callbacks
      defaultPhases - the default phases of this event, in the correct order. Must contain DEFAULT_PHASE
      Returns:
      a new event instance
    • listenAll

      public static void listenAll(@NotNull @NotNull Object listener, @NotNull @NotNull Event<?>... events)
      Registers the given listener of the listed events.

      The registration of the listener will be refused if one of the listed event involves generics in its callback type, as checking for valid registration is just too expensive, please use the regular register(Object) method for those as the Java compiler will be able to do the checks itself.

      Parameters:
      listener - the listener of events
      events - the events to listen
      Throws:
      IllegalArgumentException - if the listener doesn't listen one of the events to listen
      See Also:
    • getType

      @Contract(pure=true) @NotNull public @NotNull Class<? super T> getType()
      Returns the class of the type of the invoker used to execute an event and the class of the type of the callback.
      Returns:
      the class of the type of the invoker used to execute an event and the class of the type of the callback
    • register

      public void register(@NotNull T callback)
      Register a callback to the event.
      Parameters:
      callback - the callback
      See Also:
    • register

      public void register(@NotNull @NotNull net.minecraft.util.Identifier phaseIdentifier, @NotNull T callback)
      Registers a callback to a specific phase of the event.
      Parameters:
      phaseIdentifier - the phase identifier
      callback - the callback
    • invoker

      @Contract(pure=true) @NotNull public T invoker()
      Returns the invoker instance used to execute callbacks.

      You should avoid storing the result of this method since the invoker may become invalid at any time. Use this method to obtain the invoker when you intend to execute an event.

      Returns:
      the invoker instance
    • addPhaseOrdering

      public void addPhaseOrdering(@NotNull @NotNull net.minecraft.util.Identifier firstPhase, @NotNull @NotNull net.minecraft.util.Identifier secondPhase)
      Request that callbacks registered for one phase be executed before callbacks registered for another phase. Relying on the default phases supplied to createWithPhases(java.lang.Class<? super T>, java.util.function.Function<T[], T>, net.minecraft.util.Identifier...) should be preferred over manually registering phase ordering dependencies.

      Incompatible ordering constraints such as cycles will lead to inconsistent behavior: some constraints will be respected and some will be ignored. If this happens, a warning will be logged.

      Parameters:
      firstPhase - the identifier of the phase that should run before the other. It will be created if it didn't exist yet
      secondPhase - the identifier of the phase that should run after the other. It will be created if it didn't exist yet
    • toString

      public String toString()
      Overrides:
      toString in class Object