Registering a lot of listeners?

Discussion in 'Plugin Development' started by Milkywayz, Aug 9, 2012.

?

Which method do you find to be better?

  1. The trusted, bulky one

    100.0%
  2. The experimental, slimed down version

    0 vote(s)
    0.0%
Thread Status:
Not open for further replies.
  1. Offline

    Milkywayz

    I have found two ways of registering listeners. The first way is trusted, but not very organized. The second way is experimental but surely easier.
    The first and trusted:
    Code:
    getServer().getPluginManager().registerEvents(new DispenserListener(),
                    this);
            getServer().getPluginManager().registerEvents(new BlockPlaceListener(),
                    this);
            getServer().getPluginManager()
                    .registerEvents(new LoginListener(), this);
            getServer().getPluginManager().registerEvents(new TradingHandler(),
                    this);
            getServer().getPluginManager().registerEvents(new SpawnEggListener(),
                    this);
            getServer().getPluginManager().registerEvents(
                    new EntitySpawnListener(), this);
            getServer().getPluginManager().registerEvents(new TargetListener(),
                    this);
            getServer().getPluginManager().registerEvents(new ExplosionListener(),
                    this);
            getServer().getPluginManager()
                    .registerEvents(new ThrowListener(), this);
            getServer().getPluginManager().registerEvents(new ExpListener(), this);
            getServer().getPluginManager().registerEvents(
                    new EnchantmentListener(), this);
            getServer().getPluginManager().registerEvents(new EntitiesListener(),
                    this);
            getServer().getPluginManager().registerEvents(new DropHandler(), this);
            getServer().getPluginManager()
                    .registerEvents(new WorldListener(), this);
    Now generally speaking thats a condensed form of registering listeners all in it self despite the shear volume of listeners. Now the second way I haven't tested which is why i come here
    The second experimental way:
    Code:
            Listener[] listeners = { new DispenserListener(),
                    new BlockPlaceListener(), new LoginListener(),
                    new SpawnEggListener(), new EntitySpawnListener(),
                    new TargetListener(), new ExplosionListener(),
                    new ExpListener(), new EnchantmentListener(),
                    new EntitiesListener(), new DropHandler(), new WorldListener() };
            for (Listener l : listeners) {
                getServer().getPluginManager().registerEvents(l, this);
                listeners = (Listener[]) ArrayUtils.removeElement(listeners, l);
            }
    Also since the Listener's instance is stored in an array, would removing the instance cause problems? I mean I would remove the instance after its registered, but you can't be too sure.. Thanks for any help.
     
  2. Offline

    skore87

    I could easily be mistaken, but even though you remove the value from the array, it should still have passed the reference to the actual object to that method, thus causing no issues. One way to know for certain is to test it =)


    Personally I, now, register all my events in one collective listener class.
     
  3. Offline

    evilmidget38

    What's the benefit of removing the items from the array?
     
  4. Offline

    skore87

    My assumption is that for whatever reason he would want to remove the listeners without explicitly doing so.
     
  5. Offline

    Ziden

    Im not 100% sure of this, however in bukkits JavaPluginLoader class , at createRegisteredListeners method the listener is stored @ here:

    Code:
    eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled()));
    Means the listener instance is still stored, so garbage collector wouldnt remove it i guess.

    If your shot is because ur storing the listener methods in an array, i belive yeah you can store the methods and clear the related class instance freeing up a lil bit of memory but i am not sure. Ima test this out.
     
  6. Offline

    Milkywayz

    Ziden skore87 evilmidget38 The idea is to register the listeners quickly with the for loop, then remove the listeners instance from memory although GC might do that, theres no harm in explicitly doing so right?
     
  7. Offline

    evilmidget38

    What's happening to your listeners(are you unregistering them at a later point?) that you don't want them kept in memory?
     
  8. Offline

    Builder4Free

    Code:
    PluginManager pm = this.getServer().getPluginManager();
     
    pm.registerEvents(new Listener(), this);
    pm.registerEvents(new Listener1(), this);
    pm.registerEvents(new Listener2(), this);
    That's (^) how I do it.
     
  9. Offline

    Milkywayz

    That's not an option, I prefer organization not to mention the one listener class would be over 5k lines likely which would drive the person reviewing your file nuts, xD.

    Nope they stay registered but the listeners instance is stored in a Listener array. I tested the above code using a small debug code and it works perfectly. This discussion is primarily focused on wether removing them from the array helps even a little bit.

    Sure but this method works just fine with a lot less lines if you have a lot of listeners which I do and cannot get around.

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

    Ziden

    I think it wouldnt make a difference. the instance of the new Listener() is stored in that event map so the GC will not collect those instances cause there are still references to it (the map!) The reference u have on your onEnable method will be cleared anyway, if you dont do something like Listener myListener = new Listener(), but thats just a reference anyway so no big deal, the object is still there anyway. You dont even have to remove the element from the array, the array will be declared to collect by the end of onEnable method, and its references are still stored on the map.

    I think if bukkit stored only the class methods instead the whole class could free a 'nothing' of memory indeed, if those methods dont get cleared when the listener instance gets collected.

    The loop for adding listeners is way cooler to look at then dozens of registerevents =]
     
  11. Offline

    Builder4Free

    Use one Listener class then?
     
  12. Offline

    p000ison

    I think its not very organized with anonymous objects. Also now because the event system is updated you basically need only one listener.
     
  13. Offline

    Milkywayz

    https://github.com/milkywayz/EntityManager/tree/master/src/net/milkycraft/listeners
    Compramise organization for the sake of easier registration? Worthless. Not to mention that the method that I previously thought wouldnt work infact does so theres no reason to compact all my code into one listener.
     
  14. Offline

    Sagacious_Zed Bukkit Docs

    Register the Listener in the Listener itself, that way, all you have to do is construct a new instance in onEnable, unless you really need to pass references around thats my solution.
     
  15. I was about to suggest that. To get even MORE compact, you could actually create an abstract class implementing Listener, that automatically registers itself in its constructor. Then, make all your listeners extend that class instead of implementing Listener by themselves, and BAM, as long as the constructor doesn't take any parameters, it is implicitly invoked by the sub-class, so you don't even need to write any constructor for that ;)

    Dunno what the point of that would be, though :p


    And I can't possibly imagine a sane reason why you would want your event listeners to be garbage collected while they are in use :confused:
    I mean ... why try to let something be collected that you still need?
     
  16. Offline

    Sagacious_Zed Bukkit Docs

    On that note, it is impossible for a listener that bukkit is using to be garbage collected, because bukkit is holding onto it, assuming it is not holding onto it via a weak reference.
     
  17. Another good way is to pass the plugin to the constructor of the listener and have it register itself. Generally clean enough for me
     
Thread Status:
Not open for further replies.

Share This Page