Tutorial Getting your priorities straight!

Discussion in 'Resources' started by xZeroMCPE, Jul 31, 2017.

  1. xZeroMCPE

    xZeroMCPE Witch

    Messages:
    65
    GitHub:
    xZeroMCPE
    So priority takes an important role, I haven't seen anyone on the pmmp forums talk about priorities, I've only seen threads that include it in their code but no explanation, but some people may not understand what it is, the purpose of this thread is to explain such matters. I've gathered some information to assist all of you guys.​

    When you register events in PMMP, you can assign it a priority. Most people use Priority NORMAL without knowing because that's the default priority until you define it, and that just makes sense, right? Normal's normal. Until you think about other plugins.

    There are 6 priorities in PMMP (Just like Bukkit/Spigot)

    Those are:

    Highest
    High
    Normal
    Low
    Lowest
    Monitor

    They're actually called in this order:
    Lowest
    low
    Normal
    High
    Highest
    Monitor

    They look sane, right? Except for that obvious bolded "Monitor" one which just sticks out. Not just because it's bold. Really. I'll get to that in a second.

    The theory behind this system is, every plugin gets a say in what happens, and every plugin must get a chance to know the outcome of an event. So, we pass events to plugins even after they've been canceled. A plugin can actually uncanceled an event after another plugin canceled it. This is where priorities become really important.

    Let's say a BLOCK_PLACE event is being handled. The lowest priority listener is called to get its say in whether it should be canceled or not. Then the low priority listener is called to see if it wants to override the low, etc. Eventually, it hits monitor, and at this point, nothing should change the outcome of the event. The monitor should be used to see the outcome of an event, without changing any aspect of it.

    If we have three plugins enabled; one is a basic area protection plugin, one is a fancy plugin using signs, and another is a logging plugin.

    The protection plugin listens on Priority::LOWEST. It says they can't place blocks in this area and cancels the event.
    The fancy sign plugin listens on Priority::NORMAL. It says they can place signs here, and un cancels the event.
    The log plugin listens on Priority::MONITOR. It seems that the event was actually allowed, and logs it.

    If you want to choose a priority for an event just add this just before it (replace <PRIORITY> with priority name):

    Code:
        /**
         * @priority <PRIORITY>
         */
    Basically, if you want to change the outcome of an event, choose very carefully from LOWEST to HIGHEST. I'd suggest generalized protection plugins on lowest, more specific plugins on normal, and override plugins on high.

    If you want to act when an event happens, but not change the outcome, use monitor. It's really really important that you use the monitor, or an event might get canceled after you've acted from it, and it's even more important that you don't change the outcome of the event on the monitor or it'll break other plugins.

    I could explain this better, but I'm hoping you'll get the idea. Any questions or comments?
     
  2. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,894
    GitHub:
    sof3
    Actually not. Depending on how you interpret their meanings, some people believe "highest" should execute before "lowest", which is not the case.
    Unless with the @ignoreCancelled tag set to true.

    P.S. It is an unofficially planned feature on Poggit to show a list of what events are handled in what plugins at what priority to help developers determine the priority they want to use.
     
  3. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,894
    GitHub:
    sof3
    The current event system has some defects.
    One obvious problem is with event listeners that replace the execution of the event. Let's look at this example.
    I have a plugin that changes all chat messages into tips (sendTip() instead of sendMessage()). How do I implement it? I have to override PlayerChatEvent, cancel it and call sendTip() in my event listener.
    Now, what event priority should I use?
    If one of LOWEST to HIGHEST is used, some event listeners (especially MONITOR listeners) of PlayerChatEvent will see the event as cancelled and fail to work (e.g. not logging chat).
    If MONITOR is used, this violates the rule that you must not cancel/modify events at MONITOR. In addition, the execution order of multiple MONITOR event listeners is undefined, i.e. if you're unlucky (e.g. if the filesystem sorts the plugins such that the logger plugin is loaded before your plugin is loaded), your MONITOR listener may be executed after other listeners. This order may rely on many factors, such as:
    • plugin loader (PharPluginLoader? FolderPluginLoader? ScriptPluginLoader? ZipPluginLoader?)
    • file system directory order
    • plugin load order (STARTUP? POSTWORLD?)

    Any suggestions for how to improve this? I thought of something like https://github.com/pmmp/PocketMine-MP/issues/851, but it does not seem to work well with multiple plugins either since they will override each other.
     
  4. xZeroMCPE

    xZeroMCPE Witch

    Messages:
    65
    GitHub:
    xZeroMCPE

    Yeah agree, I'm planning on adding/explaining what
    Code:
    @ignoreCancelled tag
    does. Will also be updating this tutorial with a bit more explanations.

    I also noticed the same issue with event listeners.
     
  5. AshBull

    AshBull Spider Jockey

    Messages:
    31
    *mindblown*
    I always thought @ignoreCancelled meant "ignore whether it's cancelled or not", not "ignore cancelled events"
     
    SOFe likes this.
  6. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    740
    GitHub:
    dktapps
    It is very ambiguous. I wasn't sure myself when I initially did plugin development.
     
  7. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,894
    GitHub:
    sof3
    Grammatically:
    ignore cancelled = ignore cancelled events
    ignore cancel/cancellation/cancelling = ignore the cancellation of events
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.