Filtres d’événement

Maintenant que vous avez passé un peu de temps à travailler avec les événements, vous avez sans doute remarqué qu’il y a plusieurs préconditions que vous vérifiez très souvent quand vous écrivez un event listener. Les filtres d’événements sont un groupe d’annotations qui vous aident en vous permettant de valider automatiquement les aspects de l’événement, et si la validation échoue votre listener ne sera pas appelé. Cela permet à votre listener d’être dédié à la logique de votre gestionnaire, plutôt que les préconditions, entraînant un code plus propre.

Les filtres d’événements viennent en deux variétés, les filtres de type événement et les filtres de paramètres.

Les filtres de type événement sont des annotations de méthodes qui sont appliqués à votre méthode de listener avec l’annotation Listener et fournissent plusieurs filtres basés sur le type ou l’état de l’événement.

Les filtres de paramètres valident des objets contenus dans l’événement comme la cause. Ils viennent dans deux variétés, sources de paramètres et filtres de paramètres. Chaque paramètre supplémentaire doit avoir une annotation de source, et éventuellement peut inclure n’importe quel nombre d’annotations de filtre.

Filtres de type événement

@Include/@Exclude Ces deux paramètres sont utilisés en conjonction avec l’écoute des événements supertype comme AffectEntityEvent tout en rétrécissant les événements que vous recevez à un sous-ensemble des évéments héritant l’événement que vous écoutez.

Par exemple :

@Listener
@Exclude(InteractBlockEvent.Primary.class)
public void onInteract(InteractBlockEvent event) {
    // do something
}

Ce listener devrait normalement être appelé pour tous les événements héritant InteractBlockEvent. Toutefois, l’annotation Exclude empêchera votre listener d’être appelé pour l’événement InteractBlockEvent.Primary (Laissant juste l’événement InteractBlockEvent.Secondary).

Un exemple avec Include pourrait être :

@Listener
@Include({DamageEntityEvent.class, DestructEntityEvent.class})
public void onEvent(EntityEvent event) {
    // do something
}

Ce listener devrait normalement être appelé pour tous les EntityEvents, toutefois l’annotation Include rétrécit pour ne recevoir que les événements DamageEntityEvent et DestructEntityEvent.

@IsCancelled Cette annotation permet le filtrage des événements par leur état d’annulation au moment où votre event listener devrait être appelé. Par défaut votre event listener ne sera pas appelé si l’événement a été annulé par un event listener précédent. Toutefois, vous pouvez modifier ce comportement à l’un des trois états selon la valeur de Tristate dans l’annotation IsCancelled.

  • Tristate.FALSE est le comportement par défaut si l’annotation IsCancelled n’est pas présente, et ne va pas appeler votre listener si l’événement a été annulé.

  • Tristate.UNDEFINED entraînera votre listener à être appelé quel que soit l’état d’annulation de l’événement.

  • Tristate.TRUE entraînera votre listener à être appelé uniquement si l’événement a été annulé par un event listener précédent.

Filtres de paramètre

Les filtres de paramètre vous permettent de filtrer selon les objets à l’intérieur de l’événement. Ces annotations viennent en deux types, les sources et les filtres. Chaque paramètre supplémentaire pour votre méthode listener, au-delà du paramètre d’événement normal, nécessite exactement une annotation de source et peut éventuellement inclure n’importe quel nombre d’annotations de filtre.

Annotations de Paramètres Source

Les annotations de paramètres source disent au système d’événement où il devrait chercher la valeur du paramètre. Ceci peut être dans les causes d’événements ou dans un membre de l’objet événement lui-même.

@First Cette annotation de paramètres source dit au système d’événement de trouver le premier objet dans la cause de l’événement qui correspond au type de votre paramètre (C’est un équivalent de Cause#first(Class)). Si aucun objet n’est trouvé correspondant à ce paramètre votre listener n’est pas appelé.

Dans cet exemple votre listener sera seulement appelé si il y a un joueur dans la cause de l’événement, et le paramètre player sera défini au premier joueur présent dans la cause.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @First Player player) {
    // do something
}

@Last Ceci est similaire au @First mais il fait un appel à Cause#last(Class) à la place.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @Last Player player) {
    // do something
}

@Before Cette annotation de paramètres source dit au système d’événement de trouver l’objet avant celui du type spécifié par le paramètre d’annotation (C’est un équivalent de Cause#before(Class)). Additionnellement, l’objet trouvé doit correspondre au type du paramètre. Si aucun objet n’est trouvé correspondant à ces critères, votre listener n’est pas appelé.

Dans cet exemple votre listener sera appelé seulement si il y a un joueur situé devant un plugin dans la cause de l’événement. Le paramètre player sera défini à ce joueur.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @Before(PluginContainer.class) Player player) {
    // do something
}

@After Ceci est similaire au @Before, mais il utilise Cause#after(Class) à la place.

@Before Cette annotation de paramètres source requiert que le paramètre annoté soit un tableau. Le tableau reoutnré sera équivalent au contenu de l’appel de la méthode Cause#allOf(Class). Par défaut si le tableau retourné est vide la validation échoue, cependant ceci peut être désactivé en définissant ignoreEmpty=false.

Dans cet exemple votre listener sera toujours appelé, bien que le tableau de joueurs puisse être vide si la cause de l’événement ne contient pas de joueur.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @All(ignoreEmpty=false) Player[] players) {
    // do something
}

@Root Cette annotation de paramètres source va chercher l’objet racine de la cause, c’est l’équivalent de Cause#root(). Il effectue également une vérification supplémentaire que le type de l’objet racine correspond au type de votre paramètre.

@Named Cette annotation de paramètres source dit au système d’événement de trouver l’objet avec le nom spécifié par le paramètre d’annotation (C’est un équivalent de Cause#get(String, Class)). Additionnellement, l’objet trouvé doit correspondre au type du paramètre. Si aucun objet n’est trouvé correspondant à ces critères, votre listener n’est pas appelé.

Dans cet exemple votre listener sera appelé seulement si il y a un joueur associé au nom NamedCause.OWNER . Le paramètre player sera défini à ce joueur.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @Named(NamedCause.OWNER) Player player) {
    // do something
}

@Getter Cette annotation de paramètres source va récupérér un getter sur l’événement avec le nom spécifié. Si le getter spécifié retourne un Optional, @Getter va automatiquement déballer l”Optional.

Dans cet exemple, nous tentons de récupérer la valeur de getUseItemResult en utilisant l’annotation @Getter.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @Getter("getUseItemResult") Tristate result) {
    // do something
}

Annotations de Filtres de Paramètre

Les annotations de filtres de paramètre ajoutent des validations supplémentaires aux objets retournés par les annotations de paramètres source. Comme avec tous les événements filtres si une de ces validations échoue alors votre listener ne sera pas appelé.

@Supports Ce filtre de paramètre peut être appliqué sur n’importe quel type de paramètre qui est un DataHolder. Il prend une classe qui hérite DataManipulator en paramètre et vérifie que le DataHolder annoté prend en charge le DataManipulator donné. Cette validation est équivalent à CompositeValueStore#supports(Class<? extends H>).

Dans cet exemple le listener sera seulement appelé si il y a une entité dans la cause de l’événement, et si cette entité prend en charge le manipulateur de données FlyingData.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @First @Supports(FlyingData.class) Entity entity) {
    // do something
}

@Has Ce filtre de paramètre est similaire au filtre de paramètre Supports excepté qu’il vérifie additionnellement que le DataHolder contient une instance du DataManipulator donné.

Dans cet exemple le listener sera seulement appelé si il y a une entité dans la cause de l’événement, et si cette entité a une instance de FlyingData disponible.

@Listener
public void onInteract(InteractBlockEvent.Secondary event, @First @Has(FlyingData.class) Entity entity) {
    // do something
}

Note

@Has et @Supports ont un paramètre optionnel inverse qui peut être défini pour faire échouer la validation si elle a ou supporte la cible DataManipulator.