Les Event Listeners

Dans le but d’écouter un événement, un event listener doit être inscrit. Cela se fait en créant une méthode, peu importe son nom, ayant pour premier (et seul) paramètre le type de l’événement désiré, et en apposant l’annotation Listener à la méthode, comme illustré ci-dessous.

import org.spongepowered.api.event.Listener;

@Listener
public void onSomeEvent(SomeEvent event) {
    // Do something with the event
}

En plus, la classe contenant ces méthodes doit être inscrite auprès du gestionnaire d’événements:

Astuce

Pour les event listeners présents dans la classe principale de votre plugin (annotée par Plugin), vous n’avez pas besoin d’inscrire son instance car Sponge le fera déjà automatiquement.

Note

Le bus d’événements supporte les supertypes. Par exemple, la classe ChangeBlockEvent.Break hérite de la classe ChangeBlockEvent. Donc un plugin pourrait écouter l’événement ChangeBlockEvent et toujours recevoir des événements ChangeBlockEvent.Break. Toutefois, un plugin n’écoutant que l’événement ChangeBlockEvent.Break ne sera pas averti des autres types de l’événement ChangeBlockEvent.

Inscription et Désinscription des Event Listeners

Pour enregistrer les event listeners annotés de @Listener qui ne sont pas dans la classe principale de votre plugin, vous pouvez utiliser la méthode EventManager#registerListeners(Object, Object), qui pend en paramètres une instance du plugin et une instance de la classe contenant les events listeners.

Exemple: Inscription des Event Listeners dans d’autres classes

import org.spongepowered.api.Sponge;

public class ExampleListener {

    @Listener
    public void onSomeEvent(SomeEvent event) {
        // Do something with the event
    }
}

Sponge.getEventManager().registerListeners(this, new ExampleListener());

Inscription dynamique des Event Listeners

Certains plugins (comme les plugins de scripting) peuvent avoir besoin d’inscrire un event listener dynamiquement. Dans ce cas, l’event listener n’est pas une méthode annotée de @Listener, mais une classe implémentant l’interface EventListener. Cet event listener peut ensuite être inscrit avec la méthode EventManager#registerListener, qui prend en paramètres, dans l’ordre: une référence au plugin, sa Class, et le listener lui-même. Optionnellement, vous pouvez spécifier un ordre Order d’exécution en troisième paramètre (avant l’instance du listener), ou un booléen en quatrième argument qui déterminera s’il faut appeler le listener avant ou bien après toute modification effectuée par le serveur.

Exemple: Implémenter l’interface EventListerner

import org.spongepowered.api.event.EventListener;
import org.spongepowered.api.event.block.ChangeBlockEvent;

public class ExampleListener implements EventListener<ChangeBlockEvent.Break> {

    @Override
    public void handle(ChangeBlockEvent.Break event) throws Exception {
        [...]
    }
}

Exemple: Inscription dynamique de l’Event Listener

EventListener<ChangeBlockEvent.Break> listener = new ExampleListener();
Sponge.getEventManager().registerListener(this, ChangeBlockEvent.Break.class, listener);

Astuce

Pour les event listeners créés via l’annotation @Listener, l’ordre d’exécution peut être configuré (voir aussi About @Listener). Pour les listeners inscrits dynamiquement cela est possible en passant à la méthode EventManager#registerListener un Order en troisième paramètre.

Désinscription des Event Listeners

Pour désinscrire un seul event listener, vous pouvez utiliser la méthode EventManager#unregisterListeners(Object), qui prend en paramètre une instance de la classe contenant les event listeners.

EventListener listener = ...;
Sponge.getEventManager().unregisterListeners(listener);

Alternativement, vous pouvez utiliser la méthode EventManager#unregisterPluginListeners(Object), en passant en paramètre une instance du plugin, pour désinscrire tous les events listeners qui lui sont associés. Notez que cela inclue ceux inscrits via les annotations @Listener.

PluginContainer plugin = ...;
Sponge.getEventManager().unregisterPluginListeners(plugin);

A propos de @Listener

L’annotation @Listener a quelques champs configurables:

  • order est l’ordre dans lequel l’event listener doit être exécuté. Voir l’énumération Order de SpongeAPI pour voir les options disponibles.

  • beforeModifications spécifie si l’event listener doit être appelé avant les autres mods serveur, tels que les mods Forge. Par défaut, il est défini sur false.

Par défaut, l’annotation @Listener est configurée de manière à ce que l’event listener ne soit pas appelé si l’événement en question est annulable et a été annulé (par un autre plugin, par exemple).

GameReloadEvent

Pour éviter que tous les plugins fournissent leur propre commande de reload, Sponge fournit une une fonction de rappel (Callback) pour que les plugins puissent l’écouter, et quand elle est exécutée, effectuer une action de rechargement. C’est au plugin de décider ce qui constitue l” “action de rechargement”. Le GameReloadEvent est appelé quand un joueur exécute la commande /sponge plugins reload. L’événement n’est pas nécessairement restreint à recharger la configuration.

import org.spongepowered.api.event.game.GameReloadEvent;

@Listener
public void reload(GameReloadEvent event) {
    // Do reload stuff
}

Notez que c’est différent de ce qui est généralement considéré “reload”, puisque l’événement est purement une fonction de rappel (Callback) pour les plugins et ne fait lui-même aucun rechargement.

Déclenchement d’Événements

Pour envoyer un événement, vous avez besoin d’un objet qui implémente l’interface Event.

Vous pouvez déclencher des événements en utilisant le bus d’événements (EventManager):

boolean cancelled = Sponge.getEventManager().post(theEventObject);

La méthode retourne true si l’événement a été annulé, false sinon.

Déclenchement d’Événements Sponge

Il est possible de générer des instances d’événements intégrés avec la SpongeEventFactory statique. Cette classe est générée automatiquement, donc il n’y a pas de Javadocs. Utilisez l’autocomplétion de votre IDE pour lister les méthodes existantes. Les événements créés par la SpongeEventFactory sont alors passés au EventManager#post(Event).

Example: Le LightningEvent

import org.spongepowered.api.event.action.LightningEvent;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.cause.EventContext;
import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.SpongeEventFactory;

PluginContainer plugin = ...;
EventContext eventContext = EventContext.builder().add(EventContextKeys.PLUGIN, plugin).build();

LightningEvent lightningEvent = SpongeEventFactory.createLightningEventPre(Cause.of(eventContext, plugin));
Sponge.getEventManager().post(lightningEvent);

Avertissement

Une Cause ne peut jamais être vide. Au minimum, elle devrait contenir votre plugin.