New Event System

Discussion in 'Resources' started by md_5, Jan 17, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    md_5

    Some of you may have noticed that we have introduced a new way of handling events in Bukkit. Those of you that haven't noticed sure will when you next open your IDE and find a bunch of big yellow deprecation warnings :p
    Anyway lets start with the old way of using listeners, or more specifically how I do it in all of my projects.
    Code:java
    1. package com.md_5.noclip.listeners;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.event.Event;
    5. import org.bukkit.event.EventHandler;
    6. import org.bukkit.event.EventPriority;
    7. import org.bukkit.event.player.PlayerJoinEvent;
    8. import org.bukkit.event.player.PlayerListener;
    9.  
    10. public class NoClipPlayerListener extends PlayerListener{
    11.  
    12. public NoClipPlayerListener() {
    13. Bukkit.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_JOIN, this, Event.Priority.Normal, plugin);
    14. }
    15. @Override
    16. public void onPlayerJoin(final PlayerJoinEvent event) {
    17. }
    18. }
    19.  

    Looking at the code we have a listening class that extends PlayerListener, we then have a constructor which registers the events and some methods to execute the events. The way I use this class is to simply call: new NoClipPlayerListener() : In my onEnable() method. But now how do we replace this with the new event system you ask? Well lets take a look at the same method again:

    Code:java
    1. package com.md_5.noclip.listeners;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.event.EventHandler;
    5. import org.bukkit.event.EventPriority;
    6. import org.bukkit.event.Listener;
    7. import org.bukkit.event.player.PlayerJoinEvent;
    8.  
    9. public class NoClipPlayerListener implements Listener {
    10.  
    11. public NoClipPlayerListener() {
    12. Bukkit.getServer().getPluginManager().registerEvents(this, plugin);
    13. }
    14.  
    15. @EventHandler(priority = EventPriority.LOW)
    16. public void onPlayerJoin(final PlayerJoinEvent event) {
    17. }
    18. }
    19.  

    Well aside from the lack of big warnings several things have changed. The first being we no longer extend PlayerListener, instead all Listeners, no matter what their type implement Listener. Now instead of registering each event individually in the constructor we can simply call registerEvents() and get all the events we use registered for us. Another bonus of this system is you can name your methods anything you like. Now how do we actually go about registering these new events? Well instead of using the @Override tag to replace the listening methods you add a new tag:
    @EventHandler();
    The syntax goes like this:
    Code:
        @EventHandler(event = NAMEOFEVENT.class, priority = EventPriority.WHATPRIORITY)
    So say I wanted to add a new event, say playermove it is as simple as adding this method:
    Code:java
    1. @EventHandler(priority = EventPriority.LOW)
    2. public void whenThePlayerMoves(final PlayerMoveEvent event) {
    3. }
    4.  

    Notice here how I can call the method anything I like. Using these new listeners in your plugin is exactly the same as before: new MYListener();

    I hope this is a brief tutorial on how to upgrade your plugins to the new event system.
     
  2. Thanks for this :)

    Correct me if I'm wrong but does this mean we can bundle all listeners in one class? Although I wouldn't want to I'm just curious.

    Also are we able to have multiple classes implementing listener or will that cause an issue?
     
  3. Offline

    md_5

    yep
     
  4. Offline

    Zeerix

    No issues. You can have as many listeners as you like. Just call pm.registerEvents(listener, plugin); for all of them
     
  5. Offline

    TopGear93

    ffs, really another major change? Whats the need in having to screw up something thats not broken? LOL. sorry if im being harsh but this makes me very angry.
     
    moose517 likes this.
  6. Offline

    Zeerix

    It was broken.
     
  7. Offline

    TopGear93

    Let me guess NOTCH is to blame?
     
  8. Offline

    zml2008

    No, the old events system handled custom events terribly and was fairly sluggish, but wasn't written by Notch.
     
  9. Offline

    Sagacious_Zed Bukkit Docs

    Out of curiosity, as listeners ever removed?
     
  10. Offline

    feildmaster

    To answer your question:

    @EventHandler(event = Event.class)
    public void functionMain(Event event) {} // The main event

    @EventHandler(event = Event.class, priority = EventPriority.LOW)
    public void functionCopy(Event event) {functionMain(event);} // The copy

    as what?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 23, 2016
  11. Offline

    Sagacious_Zed Bukkit Docs

    The more correct termed question. Are Listeners ever unregistered? either during plugin disable or something explicit. If I remember correctly the old event system API lacked a way to unregister listeners.
     
  12. Offline

    feildmaster

    They are now unregistered on disable.
     
  13. Offline

    obnoxint

    It isn't really a major change. After I got the hang of it, it took me a bit more than few seconds to refactor a single listener. And I also was able to combine classes which I was forced to declare in separate files before.

    md_5 : Can you give us an example about how to throw custom events? I used instances of Observer / Observable before (because they are better than the previous crappy system) and want to refactor them in order to use Bukkits event system.
     
  14. Offline

    Zeerix

    For example:
    https://github.com/sk89q/commandboo...m/sk89q/commandbook/events/MOTDSendEvent.java

    You send and accept those events just like normal events:
    Code:
    @EventHandler
    void onMOTDEvent(MOTDSendEvent event) {
       // ...
    }
    Code:
    Event event = new MOTDSendEvent( /* parameters */ );
    Bukkit.getPluginManager().callEvent(event);
    
     
    obnoxint likes this.
  15. Offline

    md_5

    Yes I will tomorrow along with the wiki.
    For now though we have another depreceation!
    Code:
      @EventHandler(priority = EventPriority.WHATPRIORITY)
    event= NAMEOFEVENT is now deprecated and not needed. priority is not needed for Normal priority.
     
    obnoxint likes this.
  16. Offline

    ZNickq

    :confused: well that's awesome :D
     
  17. Offline

    croxis

    More of a general java question: My event register is in the constructor. For onEnable can I just have
    Code:
    new LiftRedstoneListener(this);
            new LiftPlayerListener(this);
    Is that ok or will it be swept away by the garbage collection?
     
  18. Offline

    obnoxint

    This should be ok, because there is still the handler holding a reference.
    But just to be absolutely sure, I would store the object reference in an instance variable I can control directly.
     
  19. Offline

    Sleaker

    md_5 - in your examples you fail to pass in the plugin variable resulting in minor confusion :p
     
  20. Offline

    matejdro

    So, do I need "event = NAMEOFEVENT.class" part or not?
     
  21. Offline

    md_5

    Everyone tells me that. It is STUPID to pass the plugin variable and I don't know why the wiki does it. To me it just results in messy code. I may make it passs the variable when I edit the wiki.
    You don't
     
  22. Offline

    Sleaker

    md_5 - the issue is that you reference the plugin variable in your example, but it doesn't exist... So how are you referencing it in the constructor of a listener if you don't pass it as an argument?

    Basically, the OP example = non-functional, that's all I'm saying.
     
  23. Offline

    md_5

    Good question, I use a static variable in the main class:
    Code:
    Bukkit.getServer().getPluginManager().registerListeners(this, Pluginn.instance);
     
  24. Offline

    Sleaker

    mkay, it's just confusing cause you reference a plugin variable non-statically and without defining or instantiating it in the example of the Original post. Can you please fix this?
     
  25. Offline

    feildmaster

  26. So custom events are super awesome sauce now?
    Image below is for the bukkit team.
    [​IMG]
    This will vastly improve the functionality I can offer with my plugins :)
     
  27. Offline

    croxis

    Looks like the event parameter is now required.
     
  28. Then we now need to improve the system further and add a way of unregistering listeners not needed anymore while the Server is still running :)
     
  29. Offline

    obnoxint

    YourEvent.getHandlerList().unregister(yourListener);

    ;)
     
    Lathanael likes this.
  30. Offline

    zml2008

    You've just got an old version of Bukkit locally. Go update.
     
  31. Offline

    croxis

    I'm using maven and eclipse, which should be updating snapshots automatically, no?
     
Thread Status:
Not open for further replies.

Share This Page