All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.spongepowered.api.data.value.Value Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of SpongeAPI, licensed under the MIT License (MIT).
 *
 * Copyright (c) SpongePowered 
 * Copyright (c) contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.spongepowered.api.data.value;

import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.Key;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.living.Living;
import org.spongepowered.api.util.weighted.WeightedTable;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * The abstract base interface for all of the "Value API". In short, a
 * {@link Value} is a "wrapper" around an actual value from a
 * {@link ValueContainer}. The actual value may come from various sources of
 * the {@link ValueContainer}, but usually it's a generic dynamic system for
 * being able to fetch values from object fields without having to know the
 * type of {@link Class} of the {@link ValueContainer}, the getters and
 * setters for that particular value. The driving force behind this is that
 * instead of having a traditional hierarchical structure of data that is
 * possible to be retrieved from an {@link Entity}, {@link Living}, etc.,
 * all that is required is 
{@code container.supports(Keys.HEALTH) ?
 * container.get(Keys.HEALTH).get() : 0 }
where the container is simply * a {@link ValueContainer}, nothing more, nothing less. * *

The advantage of this is that now, these various known and unknown * {@link Mutable}s can be retrieved by simple java generics: * {@link ValueContainer#getValue(Key)}. While having a {@link Mutable} for * something so primitive as the current health of a {@link Living} entity, * the power is wielded when a {@link Mutable} can be offered up to multiple * {@link ValueContainer}s without worrying about whether it's supported or not, * or getting the right cast information.

* * @param The type of element wrapped by this value */ public interface Value { /** * Constructs a mutable {@link Value} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static Value.Mutable mutableOf(Key> key, E element) { return Value.genericMutableOf(key, element).asMutable(); } /** * Constructs a mutable {@link Value} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static Value.Mutable mutableOf(Supplier>> key, E element) { return Value.mutableOf(key.get(), element); } /** * Constructs an immutable {@link Value} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static Value.Immutable immutableOf(Key> key, E element) { return Value.genericImmutableOf(key, element).asImmutable(); } /** * Constructs an immutable {@link Value} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static Value.Immutable immutableOf(Supplier>> key, E element) { return Value.immutableOf(key.get(), element); } /** * Constructs a mutable {@link ListValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static ListValue.Mutable mutableOf(Key> key, List element) { return Value.genericMutableOf(key, element).asMutable(); } /** * Constructs a mutable {@link ListValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static ListValue.Mutable mutableOf(Supplier>> key, List element) { return Value.mutableOf(key.get(), element); } /** * Constructs an immutable {@link ListValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static ListValue.Immutable immutableOf(Key> key, List element) { return Value.genericImmutableOf(key, element).asImmutable(); } /** * Constructs an immutable {@link ListValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static ListValue.Immutable immutableOf(Supplier>> key, List element) { return Value.immutableOf(key.get(), element); } /** * Constructs a mutable {@link SetValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static SetValue.Mutable mutableOf(Key> key, Set element) { return Value.genericMutableOf(key, element).asMutable(); } /** * Constructs a mutable {@link SetValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static SetValue.Mutable mutableOf(Supplier>> key, Set element) { return Value.mutableOf(key.get(), element); } /** * Constructs an immutable {@link SetValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static SetValue.Immutable immutableOf(Key> key, Set element) { return Value.genericImmutableOf(key, element).asImmutable(); } /** * Constructs an immutable {@link SetValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static SetValue.Immutable immutableOf(Supplier>> key, Set element) { return Value.immutableOf(key.get(), element); } /** * Constructs a mutable {@link MapValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The map key type * @param The map value type * @return The constructed mutable value */ static MapValue.Mutable mutableOf(Key> key, Map element) { return Value.genericMutableOf(key, element).asMutable(); } /** * Constructs a mutable {@link MapValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The map key type * @param The map value type * @return The constructed mutable value */ static MapValue.Mutable mutableOf(Supplier>> key, Map element) { return Value.mutableOf(key.get(), element); } /** * Constructs an immutable {@link MapValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The map key type * @param The map value type * @return The constructed immutable value */ static MapValue.Immutable immutableOf(Key> key, Map element) { return Value.genericImmutableOf(key, element).asImmutable(); } /** * Constructs an immutable {@link MapValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The map key type * @param The map value type * @return The constructed immutable value */ static MapValue.Immutable immutableOf(Supplier>> key, Map element) { return Value.immutableOf(key.get(), element); } /** * Constructs a mutable {@link WeightedCollectionValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static WeightedCollectionValue.Mutable mutableOf(Key> key, WeightedTable element) { return Value.genericMutableOf(key, element).asMutable(); } /** * Constructs a mutable {@link WeightedCollectionValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed mutable value */ static WeightedCollectionValue.Mutable mutableOf(Supplier>> key, WeightedTable element) { return Value.mutableOf(key.get(), element); } /** * Constructs an immutable {@link WeightedCollectionValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static WeightedCollectionValue.Immutable immutableOf(Key> key, WeightedTable element) { return Value.genericImmutableOf(key, element).asImmutable(); } /** * Constructs an immutable {@link WeightedCollectionValue} of the appropriate type based * on the given {@link Key} and the element. * * @param key The key * @param element The element * @param The element type * @return The constructed immutable value */ static WeightedCollectionValue.Immutable immutableOf(Supplier>> key, WeightedTable element) { return Value.immutableOf(key.get(), element); } /** * Constructs a {@link Value} of the appropriate type based * on the given {@link Key} and the element. The returned * {@link Value} is guaranteed {@link Mutable}, this means that * calling {@link #asMutable()} will return itself. * * @param key The key * @param element The element * @param The value type * @param The element type * @return The constructed mutable value */ static , E> V genericMutableOf(Key key, E element) { return Sponge.game().factoryProvider().provide(Factory.class).mutableOf(key, element); } /** * Constructs a {@link Value} of the appropriate type based * on the given {@link Key} and the element. The returned * {@link Value} is guaranteed {@link Immutable}, this means that * calling {@link #asImmutable()} will return itself. * * @param key The key * @param element The element * @param The value type * @param The element type * @return The constructed immutable value */ static , E> V genericImmutableOf(Key key, E element) { return Sponge.game().factoryProvider().provide(Factory.class).immutableOf(key, element); } /** * Gets the held value. * * @return The held value */ E get(); /** * Gets the key for this {@link Value}. * * @return The key for this value */ Key> key(); /** * Retrieves a mutable form of this value. Due to the vague nature of the * value itself, some cases can already provide a {@link Mutable} instance * where this would simply return itself. In other cases, where the retrieved * value is an {@link Immutable} instance, a new mutable value is created * with the same key and values. * * @return A mutable value */ Mutable asMutable(); /** * Retrieves a copy in the mutable form of this value. The new is created * with the same key and values. * * @return A mutable value */ Mutable asMutableCopy(); /** * Retrieves an immutable form of this value. Due to the vague nature of the * value itself, some cases can already provide a {@link Immutable} instance * where this would simply return itself. In other cases, where the retrieved * value is a {@link Mutable} instance, a new immutable value is created * with the same key and values. * * @return An immutable value */ Immutable asImmutable(); /** * Represents a type of {@link Value} that is mutable. Simply put, the * underlying value can always be changed without creating a new {@link Mutable}. * * @param The type of element */ interface Mutable extends Value { /** * Sets the underlying value to the provided {@code value}. * * @param value The value to set * @return The owning {@link ValueContainer} */ Mutable set(E value); /** * Attempts to transform the underlying value based on the provided * {@link Function} such that the result of {@link Function#apply(Object)} * will replace the underlying value. * * @param function The function to apply on the existing value * @return The owning {@link ValueContainer} */ Mutable transform(Function function); /** * Gets the {@link Immutable} version of this {@link Mutable} such that * all data is duplicated across to the new {@link Immutable}. Note * that once created, the {@link Immutable} is not going to change. * * @return A new {@link Immutable} instance */ @Override Immutable asImmutable(); @Override default Mutable asMutable() { return this; } @Override default Mutable asMutableCopy() { return this.copy(); } /** * Makes an independent copy of this {@link Mutable} with the same initial * data. Both this value and the new value will refer to the same object * initially. * * @return A new copy of this {@link Mutable} */ Mutable copy(); } /** * Represents an immutable representation of a {@link Value} where any * modifications of the underlying value result in a new instance of an * {@link Immutable} and/or the {@link ValueContainer} if the * {@link ValueContainer} too is immutable. * *

The basis for immutability is that once created, the value can not be * changed for any reason. Change requires a new instance to be created. As the * {@link Immutable} always has a {@link ValueContainer}, it is * recommended that the owning {@link ValueContainer} too is immutable, unless * the {@link Immutable} is being passed around for data processing. The * underlying value of an {@link Immutable} may be itself mutable, however * utilizing any provided methods by any of the {@link Immutable} classes * is recommended.

* * @param The type of value */ interface Immutable extends Value { /** * Creates a new {@link Immutable} with the given E typed * value, such that if the owning {@link ValueContainer} is immutable, the * {@link ValueContainer} too is recreated as a new instance with the new * {@link Immutable}. * * @param value The value to replace * @return The owning {@link ValueContainer}, a new instance if it too is * immutable */ Immutable with(E value); /** * Retrieves the underlying value for this {@link Immutable} and * applies the given {@link Function} onto that value, after which, the * product is sent to a new {@link Immutable} replacing this one. * *

If the {@link ValueContainer} too is immutable, a new instance of * the {@link ValueContainer} may be created. If the {@link ValueContainer} * is mutable, the same instance of the {@link ValueContainer} is retained. *

* * @param function The function to apply onto the existing value * @return The owning {@link ValueContainer}, a new instance if it too is * immutable */ Immutable transform(Function function); /** * Creates a mutable {@link Mutable} for this {@link Immutable}. * * @return A mutable value */ @Override Mutable asMutable(); @Override default Mutable asMutableCopy() { return this.asMutable(); } @Override default Immutable asImmutable() { return this; } } interface Factory { , E> V mutableOf(Key key, E element); , E> V immutableOf(Key key, E element); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy