Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Enhancement) Better event priority system #131

Open
fan87 opened this issue Apr 18, 2022 · 0 comments
Open

(Enhancement) Better event priority system #131

fan87 opened this issue Apr 18, 2022 · 0 comments

Comments

@fan87
Copy link

fan87 commented Apr 18, 2022

Here's an example code:

Events.subscribe(PlayerJoinEvent.class)
    .name("listenerA") // Optional, and by adding it you can reference it
    .handler(e -> e.setJoinMessage("A"));

Events.subscribe(PlayerJoinEvent.class)
    .name("listenerB")
    .mustRunAfter("listenerA") // Still: Optional. This will ensure that the event will be handled after listener A
    .mustRunBefore("listenerC") // You get the idea: it will ensure that the event will be handled before listenerB
    .handler(e -> e.setJoinMessage("B"));

Events.enableUnexistingListenerWarning(); // Check the code below

Events.subscribe(PlayerJoinEvent.class)
    .name("listenerC")
    .mustRunBefore("listenerB") // B must run before C, and C also must run before B: conflict. 
    // Throwing an exception with stack to let the developer know what is causing it 
    // (Sometimes it can get really complicated, for example, A must run after B must run after C... and must run after A)
    .mustRunAfter("listenerThatDoesntExist") // If listener doesn't exist and listener has been registered for over
    // <a configurable value> seconds, it will send a warning message to the console to let the developer know they probably
    // mistyped the listener name
    // Well, if it's in production state, developers probably don't want there to be a warning message in user's terminal,
    // that's why there's a function: `enableUnexistingListenerWarning()`, so developer can check if it's development build,
    // and enable it if needed
    .disableListenerNotExistingWarning() // With this, the listener can be not existing, and it won't print a warning message
    // So if listener is going to be registered later, it won't print the message
    .handler(e -> e.setJoinMessage("B"));

You can do it with a topological sorting algorithm, it would help a lot of developers.

(In my previous plugins, event priority gets really complicated and gets more than 5 layers, so in the end, I decided to code my own Event system instead of using an existing one, and having to figure out which priority should it be is very annoying and very hard to refactor. For example: If you want to insert an listener between A and B, you'll have to change everything before A or everything after B, having mustRunAfter and mustRunBefoer makes it way easier, so if plugin developers want to do something like damage processing in order, they can do it without painfully figuring out what priority should it be.)

I know it sounds impossible because Bukkit's event system is really not that great.

The only way I can think of to implement it is to have a custom event system, and have the main listener that listens to every single event, and call listeners.
But I don't really know how you actually listen to every event since there can be custom events, a way would be attaching to the server JVM instance, modifying the bytecode of "callEvent" and adding instructions that call an inner function of this library.

Another way to listen to all events is by using reflection, going through every plugin class loader, and finding every class that extends Event class. It sounds more possible but there can be some limitations like

  1. takes around 1~2 seconds to start the server
  2. Hacks like plugman won't work
    But it's less stupid than attaching into JVM and adding bytecodes, but it will be slower. Probably make 2 of them and make it configurable?

It may sound really stupid, but it will actually help a lot of people trying to develop complicated plugins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant