Utilisation des Clés

Obtenir et offrir une donnée en utilisant une clé

Un data holder fournit des méthodes pour récupérer ou altérer une donnée précise identifiée par une Key. Commençons avec un exemple:

Exemple de Code : Soigner un data holder, si possible

import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.key.Keys;

public void heal(DataHolder target) {
    if (target.supports(Keys.HEALTH)) {
        double maxHealth = target.get(Keys.MAX_HEALTH).get();
        target.offer(Keys.HEALTH, maxHealth);
    }
}

Maintenant, pour les détails de la fonction ci-dessus.

La première ligne vérifie si notre data holder donné supporte une valeur actuelle de la santé. Et seulement si c’est le cas, il peut être guéri après tout. Puisque qu’un data holder ne peut pas avoir de santé actuelle sans avoir de santé maximum et vice versa, une vérification pour une seule des clés à l’aide de la méthode supports() suffit.

La seconde ligne utilise la fonction get() pour demander la santé maximum du data holder. Outre get(), les méthodes getOrNull() et getOrElse() existent, elles acceptent toute une Key en premier paramètre. Généralement, get() devrait être utilisé, qui retournera un Optional des les données demandées ou Optional.empty() si le data holder ne supporte pas la clé fournie. Puisque nous avons déjà vérifié si la Key est supportée, nous pouvons appeler get() sur l’Optional sans plus de vérifications. Nous pourrions également utiliser ` getOrNull()`` qui est basiquement un raccourci pour get(key).orNull(), pour ainsi se débarrasser de l”Optional. La troisième possibilité serait le getOrElse(), qui accepte une valeur par défaut comme second paramètre à retourner si la valeur n’est pas présente sur le data holder.

À la troisième ligne, nous fournissons des données au data holder. Nous fournissons une Key indiquant la santé actuelle et la santé maximale acquise auparavant, guérissant ainsi le data holder avec toute sa santé. Il y a une multitude de méthodes offer() acceptant différents paramètres d’ensembles, qui retournent tous un DataTransactionResult contenant les informations si l’offre a accepté acceptée. Pour l’instant, nous utiliserons celui acceptant une Key et une valeur correspondante, mais nous en rencontrerons plus dans les pages suivantes. Puisque nous savons déjà que notre offre de santé actuelle est acceptée (comme le data holder le supporte), nous pouvons discrètement se débarrasser du résultat.

Il est également possible de supprimer complètement les données d’un DataHolder en utilisant la fonction remove(). Fournissez simplement une Key représentant les données que vous souhaitez supprimer. L’exemple suivant tente de supprimer un custom name depuis un data holder donné :

public void removeName(DataHolder target) {
    target.remove(Keys.DISPLAY_NAME);
}

Transformer les Données

Autre que l’obtention, la modification et l’offre d’une valeur, il y a une autre façon d’interagir avec les données. À l’aide de la méthode transform() d’un data holder, nous pouvons passer une Key et une Function. En interne, la valeur de la clé sera récupérée et la fonction donnée lui sera appliquée. Le résultat est ensuite stocké sous la clé et la méthode transform() retournera par conséquent un DataTransactionResult.

Maintenant, à titre d’exemple, imaginez que nous voulons buff un dat aholder en doublant sa santé maximale.

import java.util.function.Function;

public void buff(DataHolder target) {
    target.transform(Keys.MAX_HEALTH, new Function<Double,Double>() {
        @Override
        public Double apply(Double input) {
            return (input == null) ? 0 : input * 2;
        }
    });
}

Ou, si vous utilisez Java 8, vous serez capable de raccourcir la ligne avec les expressions lambda :

public void buff(DataHolder target) {
    target.transform(Keys.MAX_HEALTH, d -> (d == null) ? 0 : 2*d);
}

Remarquez que dans les deux cas, il faut s’assurer que notre fonction passée peut gérer null. Vous remarquerez également qu’aucune vérification n’a été réalisée pour savoir si la cible supporte la clé Keys#MAX_HEALTH. Si une cible ne le supporte pas, la fonction transform() va échouer et retourner un DataTransactionResult l’indiquant.

Valeurs Clés

Il y a des cas où vous pouvez vous soucier non seulement à propos de la valeur directe d’une Key, mais aussi la valeur clé l’encapsulant. Dans ce cas, utilisez la méthode getValue(key) au lieu de get(key). Vous recevrez un objet héritant de BaseValue qui contient une copie de la valeur originale. Puisque nous savons que la vie actuelle est un MutableBoundedValue, nous pouvez trouver la valeur minimum possible et définir la vie de notre cible juste un tout petit peu au-dessus.

Exemple de Code : Amener une cible au bord de la mort

import org.spongepowered.api.data.value.mutable.MutableBoundedValue;

public void scare(DataHolder target) {
    if (target.supports(Keys.HEALTH)) {
        MutableBoundedValue<Double> health = target.getValue(Keys.HEALTH).get();
        double nearDeath = health.getMinValue() + 1;
        health.set(nearDeath);
        target.offer(health);
    }
}

Encore une fois, nous vérifions si notre cible supporte la clé de la santé et ensuite obtenir la valeur clé. Un MutableBoundedValue contient une méthode getMinValue(), donc nous récupérons la valeur minimale, on ajoute 1 et on la définit à notre conteneur de données. En interne, la méthode set() effectue une vérification de si notre valeur fournie est valide et échoue silencieusement si elle ne l’est pas. Appeler health.set(-2) ne changera pas la valeur à l’intérieur de health puisqu’il échouereait les contrôles de validité. Pour finalement appliquer nos modifications à la cible, nous devons lui offrir la valeur clé. Puisqu’une valeur clé contient aussi la Key utilisée pour l’identifier, appeler target.offer(health) est équivalent à appeler target.offer(health.getKey(), health.get()).