Scheduler
Planifie des taches differees, repetitives, asynchrones ou enchainees — sans bloquer le jeu.
Introduction
Le Scheduler d'EriAPI permet de planifier des taches de plusieurs facons :
- Execution differee — lance une action apres N ticks (20 ticks = 1 seconde)
- Repetition — execute une action toutes les N ticks, un nombre fini ou infini de fois
- Async — execute du code lourd hors du main thread, puis revient sur le main thread pour toucher aux objets Minecraft
- Chaine sequentielle — enchaîne plusieurs actions avec des delais precis entre elles
Toutes les classes du Scheduler sont dans le package fr.eri.eriapi.scheduler.
Minecraft tourne a 20 ticks par seconde. Un delai de 20 ticks = 1 seconde,
100 ticks = 5 secondes, 1200 ticks = 1 minute.
EriScheduler — API statique
EriScheduler est le point d'entree principal du module. Toutes ses methodes sont
statiques : pas besoin d'instancier quoi que ce soit.
Execution differee — delay()
Execute une action une seule fois, apres un delai en ticks.
// Delai de 20 ticks = 1 seconde
ScheduledTask task = EriScheduler.delay(20, () -> {
player.sendMessage(new TextComponentString("1 seconde plus tard !"));
});
Repetition limitee — repeat(ticks, maxCount, Runnable)
Execute une action toutes les N ticks, au maximum maxCount fois.
// Toutes les 20 ticks, 5 fois au maximum
ScheduledTask task = EriScheduler.repeat(20, 5, () -> {
System.out.println("Tick!");
});
Repetition infinie — repeat(ticks, Runnable)
Execute une action toutes les N ticks indefiniment, jusqu'a ce que tu l'annules manuellement.
// Toutes les 100 ticks = toutes les 5 secondes, sans limite
ScheduledTask task = EriScheduler.repeat(100, () -> {
System.out.println("Toutes les 5 secondes");
});
Tache asynchrone — async()
Lance un Callable hors du main thread. Voir la section
AsyncExecutor pour les details.
EriScheduler.async(() -> fetchDataFromWeb())
.thenSync(result -> player.sendMessage(new TextComponentString("Data: " + result)));
Chaine sequentielle — chain()
Cree une TaskChain pour enchaîner des actions avec des delais. Voir la section
TaskChain.
Gestion globale
// Annuler toutes les taches actives
EriScheduler.cancelAll();
// Obtenir le nombre de taches actives
int count = EriScheduler.activeCount();
Reference des methodes
| Methode | Parametres | Description |
|---|---|---|
delay() |
int ticks, Runnable |
Execute une action une fois apres N ticks |
repeat() |
int ticks, int maxCount, Runnable |
Repete une action N fois toutes les X ticks |
repeat() |
int ticks, Runnable |
Repete indefiniment toutes les X ticks |
async() |
Callable<T> |
Lance une tache hors du main thread, retourne un AsyncExecutor |
chain() |
— | Cree une nouvelle TaskChain vide |
cancelAll() |
— | Annule toutes les taches en cours |
activeCount() |
— | Retourne le nombre de taches actives |
ScheduledTask — Reference de tache
Chaque appel a EriScheduler.delay() ou EriScheduler.repeat() retourne
un objet ScheduledTask. Garde cette reference pour controler la tache apres sa creation.
ScheduledTask task = EriScheduler.repeat(20, () -> doStuff());
task.pause(); // Gele le compteur de ticks (la tache ne s'execute plus)
task.resume(); // Reprend le decompte la ou il s'etait arrete
task.cancel(); // Arrete definitivement la tache
boolean running = task.isRunning(); // true si active et non pausee
boolean cancelled = task.isCancelled(); // true si annulee
boolean paused = task.isPaused(); // true si gelee
int executions = task.getExecutionCount(); // Nombre de fois que la tache s'est executee
Reference des methodes
| Methode | Retour | Description |
|---|---|---|
pause() |
void |
Gele le compteur, la tache ne s'execute plus |
resume() |
void |
Reprend le decompte apres un pause() |
cancel() |
void |
Annule definitivement la tache |
isRunning() |
boolean |
true si la tache est active et non pausee |
isCancelled() |
boolean |
true si la tache a ete annulee |
isPaused() |
boolean |
true si la tache est gelee |
getExecutionCount() |
int |
Nombre total d'executions effectuees |
Stocke toujours la reference de ta tache dans un champ de ta classe si tu as besoin de
l'annuler plus tard (par exemple dans la methode onGuiClosed() de ton ecran).
TaskChain — Chaine sequentielle
Une TaskChain permet d'enchaîner plusieurs actions avec des delais precis entre chacune.
C'est ideal pour des sequences d'evenements en jeu : animations de texte, tutoriels, cinematiques, etc.
EriScheduler.chain()
.then(0, () -> System.out.println("Maintenant"))
.then(20, () -> System.out.println("1s plus tard"))
.then(40, () -> System.out.println("2s plus tard"))
.run();
Le parametre de then(ticks, action) est le delai depuis le debut de la chaine,
pas depuis l'etape precedente. Un delai de 0 execute l'action immediatement au lancement de
run(). Pense-y comme des "timestamps" dans une timeline.
Reference des methodes
| Methode | Parametres | Description |
|---|---|---|
then() |
int ticks, Runnable |
Ajoute une etape a la chaine avec un delai en ticks |
run() |
— | Lance la chaine. Toutes les etapes sont planifiees immediatement. |
AsyncExecutor — Taches asynchrones
L'AsyncExecutor permet d'executer du code lourd (appels reseau, lecture de fichiers,
calculs intensifs) dans un thread separe, sans bloquer le jeu. Quand le resultat est pret, tu peux
revenir sur le main thread pour interagir avec les objets Minecraft.
Dans le callback de async(), tu ne dois pas appeler de methodes Minecraft
(player, world, etc.). Utilise thenSync() pour revenir sur le main thread
avant de manipuler des objets du jeu.
EriScheduler.async(() -> {
// Hors du main thread — ideal pour les operations lentes
return fetchDataFromWeb();
})
.onError(e -> {
// Appelee si une exception est lancee dans le bloc async
System.err.println("Erreur: " + e.getMessage());
})
.thenSync(result -> {
// Retour sur le main thread — safe pour toucher aux objets Minecraft
player.sendMessage(new TextComponentString("Data: " + result));
});
Reference des methodes
| Methode | Parametres | Description |
|---|---|---|
onError() |
Consumer<Exception> |
Callback appele si une exception est lancee dans le bloc async |
thenSync() |
Consumer<T> |
Callback execute sur le main thread avec le resultat de la tache async |
Exemple complet — Countdown
Voici un exemple concret qui combine repeat() et ScheduledTask pour
faire un compte a rebours affiché dans le chat du joueur.
// Compte a rebours : 5...4...3...2...1...Go!
// La tache se repete 6 fois (5 chiffres + le message "Go!")
final int[] count = {5};
ScheduledTask countdown = EriScheduler.repeat(20, 6, () -> {
if (count[0] > 0) {
player.sendMessage(new TextComponentString(count[0] + "..."));
count[0]--;
} else {
player.sendMessage(new TextComponentString("Go!"));
}
});
final int[] ?En Java 8, les lambdas ne peuvent capturer que des variables effectives finales. Un tableau
d'un seul element est une astuce courante pour avoir un compteur mutable dans un lambda :
la reference au tableau est finale, mais son contenu (count[0]) peut changer.
Exemple avec TaskChain — Sequence de messages
Pour une sequence de messages avec des timings precis, la TaskChain est plus lisible :
EriScheduler.chain()
.then(0, () -> player.sendMessage(new TextComponentString("Bienvenue sur le serveur !")))
.then(40, () -> player.sendMessage(new TextComponentString("Rejoins le Discord : discord.gg/...")))
.then(80, () -> player.sendMessage(new TextComponentString("Tape /help pour la liste des commandes.")))
.then(120, () -> player.sendMessage(new TextComponentString("Bonne partie !")))
.run();
Exemple avec AsyncExecutor — Chargement de donnees
Un cas d'usage typique : charger des donnees depuis une API externe sans freezer le jeu.
player.sendMessage(new TextComponentString("Chargement en cours..."));
EriScheduler.async(() -> {
// Simule un appel reseau lent (hors main thread)
URL url = new URL("https://api.example.com/player/" + player.getName());
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
return reader.readLine();
})
.onError(e -> {
player.sendMessage(new TextComponentString("Impossible de charger les donnees."));
})
.thenSync(data -> {
// On est de retour sur le main thread, safe pour Minecraft
player.sendMessage(new TextComponentString("Ton score : " + data));
});
Si tu crées des taches repetitives dans une GUI ou un ecran, pense a les annuler quand
l'ecran se ferme. Surcharge la methode onGuiClosed() de EriGuiScreen
et appelle task.cancel() ou EriScheduler.cancelAll().