Utilización de Claves

Obtención y ofrecimiento de datos utilizando una clave

Un titular de datos proporciona métodos para recuperar o modificar un solo punto de los datos identificados por una :javadoc:`Clave`. Vamos a comenzar con un ejemplo:

Ejemplo de Código: Curación de un titular de datos, si es posible

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);
    }
}

Ahora para los detalles de la función anterior.

The first line checks if our given data holder supports a current health value. Only if it does, it can be healed after all. Since a data holder cannot have current health without having a maximum health and vice versa, a check for one of the keys using the supports() method suffices.

La segunda línea utiliza la función get() para pedirle al titular de datos su máxima curación. Además de get(), el método getOrNull() y getOrElse() existen, todos acepten una Clave como su primer parámetro. Generalmente, get()``debería ser utilizado, devolverá un ``Opcional de los datos requeridos o Optional.empty() si el titular de los datos no soporta la clave suministrada. Ya que hemos verificado que la Clave es soportada, podemos solo llamar a get() en el Opcional sin comprobaciones adicionales. También podríamos utilizar getOrNull() que es básicamente un atajo para llamar a get(key).orNull(), deshaciéndose así del Opcional. La tercera posibilidad sería el getOrElse(), que acepta un valor predeterminado como un segundo parámetro que se devolverá si el valor no está presente en el titular de datos.

En la tercera línea, ofrecemos los datos al titular de datos. Proporcionamos una Clave que denota la salud actual y la salud máxima adquirida anteriormente, así que cura al titular de datos para la completa salud. Hay una variedad de métodos offer() que aceptan diferentes conjuntos de parámetros, todos los que devuelven un DataTransactionResult que contiene información si la oferta fue aceptada. Por ahora, utilizaremos el único que acepta una Clave y un valor correspondiente, pero encontraremos más en las siguientes páginas. Debido a que ya sabemos que nuestra oferta de salud actual es aceptada (ya que el titular de datos lo soporta), podemos descartar silenciosamente el resultado.

También es posible eliminar completamente datos de un DataHolder utilizando la función remove(). Simplemente proporcione una Clave que represente los datos que quiere remover. El siguiente ejemplo intentará eliminar un nombre personalizado de un titular de datos dado:

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

Transformación de Datos

Además de obtener, la modificación y oferta de un valor, hay otra manera de interactuar con datos. Utilizando un método transform() del titular de datos podemos pasar una Clave y una Función. Internamente, el valor de la clave será recuperado y la función dada se le aplicará. El resultado es entonces almacenado debajo de la clave y el método transform() devolverá un DataTransactionResult en consecuencia.

Ahora, como un ejemplo, imagine que queremos buffear un titular de datos duplicando su salud máxima.

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;
        }
    });
}

O, si utiliza Java 8, es capaz de acortar la línea con expresiones lambda:

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

Tenga en cuenta que en ambos casos necesitamos asegurar que nuestra función aprobada puede manejar nulo. También notará que no se ha realizado ninguna verificación si el objetivo actualmente soporta la clave Keys#MAX_HEALTH. Si un objetivo no lo admite, la función transform() fallará y devolverá un DataTransactionResult que lo indica.

Valores Clave

There are cases where you may care about not only the direct value for a Key, but the keyed value encapsulating it. In that case, use the getValue(key) method instead of get(key). You will receive an object inheriting from Value which contains a copy of the original value. As Keys#SPAWNABLE_ENTITIES is a WeightedCollectionValue, we can get a list of potentional entity that could spawn using the Value of the key.

Ejemplo de Código: Llevar un objetivo al borde de la muerte

public void scare(DataHolder target) {
    if (target.supports(Keys.NEXT_ENTITY_TO_SPAWN)) {
        WeightedCollectionValue value = target.getValue(Keys.NEXT_ENTITY_TO_SPAWN).get();
        List<Entity> entities = value.get(new Random());
    }
}