Skip to content

Not executing event trigger under specific circumstances when event has already been cancelled #26

@stefvanschie

Description

@stefvanschie

I decided to create an issue out of this first to get some feedback on the idea.

When working with events, often times you want to cancel the event while not doing anything else. Examples of this may be stopping the weather from changing, stopping the time from cycling, stopping certain players from chatting, etc. When making such an event, QuickSkript (probably as well as most other interpreters) will execute the skript code inside this event every time the event is called.

When using Java, we get an interesting option when registering our event handlers. We can tell Bukkit that we do not want to receive the event when the event has already been cancelled by specifying the ignoreCancelled parameter in our annotation and setting it to true. While this is not always desirable, one place where you can always make use of this, is when your event only cancels the event, while doing nothing else. Executing this event when it has already been cancelled would be useless: the cancellation state would stay the same while wasting time by executing unnecessary code.

The way we currently register events would allow us to specify an option as stated above as well in the form of a boolean parameter. Since the elements have been parsed before we register the event, we can analyze these elements in advance. My idea is to analyze these elements and then see if we can ignore this event when it has already been cancelled. In order to determine whether this is possible we do the following things:

  • Check whether the event is cancellable or not: if the event is not cancellable, the parameter doesn't matter and we can stop analyzing elements further.
  • Check all elements and see if they do not modify any states. States imply that when the code would run, the effects of this can be seen after the code has been fully executed. We do this instead of just checking for a cancel event statement, because then we can also test for code that for example has an if statement before a cancel event statement. Note that we do not accept elements which change states which are only visible when the event isn't cancelled. Say you have an event which changes a message which only gets printed when the event is executed. You could make the assumption, since the message doesn't get shown when the event is cancelled, we can flag this event as well. However this may not be true. When a low priority event cancels the event and then our event gets ignored, it could be that a higher priority event uncancels the event. If we would ignore our event, the message would not be set even though the event will get executed after all. Underneath this post there are examples with whether they would or would not get flagged to ignore the event when cancelled.

After these checks have been executed and returned successfully, we can set this event to be ignored when the event has been cancelled. Furthermore, this system will only ignore events when cancelled when there is absolute certainty this is possible; there will be no incorrectly marked events.

By having such a system we could reduce overhead and execution times by preventing unnecessary code from being executed. This would guarantee that no code is executed when it's not needed and any heavy computations these events might be doing would only be done when absolutely needed.

It has to be noted however that when we get a feature in the future to possibly set the cancellation state of an event to false (the event will no longer be cancelled), that we have to detect this and not flag any event which has such an expression.

Examples for pieces of code. Note that not everything shown here is already implemented.

on join:
    set join message to ""
    stop

This would not get flagged: the underlying event isn't cancellable.

on weather change:
    cancel event

This will get flagged: the WeatherChangeEvent is cancellable, and there are no pieces of code that would perform modifications.

on pick up:
    if player has permission "hubcore.admin":
        stop
    else:
        cancel event

This will get flagged: the PlayerPickUpItemEvent is cancellable, and there are no pieces of code that would perform modifications (permission checks don't do modifications and neither does the stop).

If no objections are made against this idea, I'd be happy to implement it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions