Annotation Interface EventMethod


@Target(METHOD) @Retention(RUNTIME) public @interface EventMethod
Annotation to mark a method to be called by an event. The name of the method is irrelevant. Make sure the method does only have a single parameter, and that the parameter is an instance of Event.
Optionally you can also specify the threading model
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Defines how the event should be called.
  • Element Details

    • value

      Threading value
      Defines how the event should be called. If Threading is set to Sync, all event calls will be synchronized, so you can safely access variables from various event calls. This mode has a negative impact on performance, since other threads which call an event will be blocked while another event call is still active.

      If the threading model is set to Async, events will be called directly, i.e there is no penalty in terms of performance, but event calls will not be thread-safe.
      Returns:
      the threading type.
      Example: Achieve thread-safety, option 1: Synchronzied events
      1//All events with the "Sync" threading model are safe to access the
      2//"playerNames" ArrayList.
      3public class MyEventListener implements Listener{
      4 private ArrayList<String> playerNames = new ArrayList<>();
      5
      6 @EventMethod(Threading.Sync)
      7 public void onPlayerCommand(PlayerCommandEvent event){
      8 Player p = event.getPlayer();
      9 testList.add(p.getName());
      10 //do something else
      11 }
      12
      13 @EventMethod(Threading.Sync)
      14 public void onPlayerChat(PlayerChatEvent event){
      15 //do something
      16 Player p = event.getPlayer();
      17 testList.add(p.getName());
      18 //do something else
      19 }
      20
      21 @EventMethod(Threading.Sync)
      22 public void onPlayerRespawn(PlayerRespawnEvent event){
      23 Player p = event.getPlayer();
      24 testList.add(p.getName());
      25 }
      26}

      Example: Achieve thread-safety, option 2: Synchronized blocks
      1//You can use a synchronized-block in order to just synchronize the access
      2//to the ArrayList. Please note that this is just a nonsensical example to
      3//demonstrate how to use synchronized blocks.
      4public class MyEventListener implements Listener{
      5 private final ArrayList<String> playerNames = new ArrayList<>();
      6
      7 @EventMethod
      8 public void onPlayerCommand(PlayerCommandEvent event){
      9 synchronized(playerNames){
      10 Player p = event.getPlayer();
      11 testList.add(p.getName());
      12 }
      13 //do something else
      14 }
      15
      16 @EventMethod
      17 public void onPlayerChat(PlayerChatEvent event){
      18 //do something
      19 synchronized(playerNames){
      20 Player p = event.getPlayer();
      21 testList.add(p.getName());
      22 }
      23 //do something else
      24 }
      25
      26 @EventMethod
      27 public void onPlayerRespawn(PlayerRespawnEvent event){
      28 synchronized(playerNames){
      29 Player p = event.getPlayer();
      30 testList.add(p.getName());
      31 }
      32 }
      33}

      Example: Achieve thread-safety, option 3: Use thread-safe collection
      1//Since an ArrayList is not thread-safe, you could use a thread-safe
      2//collection instead, for example a Vector (obsolete) or CopyOnWriteArrayList
      3//(or anything else from the "java.util.concurrent" package).
      4//Note that you should ONLY use a thread-safe collection when thread-safety
      5//is required, otherwise just use an ArrayList, since it provides better
      6//performance.
      7public class MyEventListener implements Listener{
      8
      9 private Plugin plugin;
      10 private final Vector<String> playerNames = new Vector<>();
      11
      12 public MyEventListener(Plugin plugin){
      13 //Reference to plugin, needed to call plugin methods
      14 this.plugin = plugin;
      15 }
      16
      17 @EventMethod
      18 public void onPlayerCommand(PlayerCommandEvent event){
      19 Player p = event.getPlayer();
      20 Vector.add(p.getName());
      21 }
      22
      23 @EventMethod
      24 public void onPlayerChat(PlayerChatEvent event){
      25 Player p = event.getPlayer();
      26 Vector.add(p.getName());
      27 }
      28
      29 @EventMethod
      30 public void onPlayerRespawn(PlayerRespawnEvent event){
      31 Player p = event.getPlayer();
      32 Vector.add(p.getName());
      33 }
      34}

      Example: Achieve thread-safety, option 4: Enqueue Runnable
      1//All events with the "Sync" threading model are safe to access the
      2//"playerNames" ArrayList. Note that this method has quite some overhead
      3public class MyEventListener implements Listener{
      4
      5 private Plugin plugin;
      6 private final ArrayList<String> playerNames = new ArrayList<>();
      7
      8 public MyEventListener(Plugin plugin){
      9 //Reference to plugin, needed to call plugin methods
      10 this.plugin = plugin;
      11 }
      12
      13 @EventMethod
      14 public void onPlayerCommand(PlayerCommandEvent event){
      15 plugin.enqueue(() -> {
      16 Player p = event.getPlayer();
      17 testList.add(p.getName());
      18 });
      19 //do something else
      20 }
      21
      22 @EventMethod
      23 public void onPlayerChat(PlayerChatEvent event){
      24 //do something
      25 plugin.enqueue(() -> {
      26 Player p = event.getPlayer();
      27 testList.add(p.getName());
      28 });
      29 //do something else
      30 }
      31
      32 @EventMethod
      33 public void onPlayerRespawn(PlayerRespawnEvent event){
      34 plugin.enqueue(() -> {
      35 Player p = event.getPlayer();
      36 testList.add(p.getName());
      37 });
      38 }
      39}
      Default:
      Async