personthecat.catlib.data.Lazy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of catlib-quilt Show documentation
Show all versions of catlib-quilt Show documentation
Utilities for serialization, commands, noise generation, IO, and some new data types.
The newest version!
package personthecat.catlib.data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import java.util.Optional;
import java.util.function.Supplier;
/**
* Creates a sort of lazily initialized value.
*
* Values wrapped in this class will not exist until the first time they are used.
* Note that this implementation is thread safe.
*
* @param The type of value being consumed by the wrapper.
*/
@ThreadSafe
@SuppressWarnings("unused")
public class Lazy implements Supplier {
/** The underlying value being wrapped by this object. */
protected T value = null;
/** A supplier used for producing the value when it is ready. */
protected final Supplier supplier;
/** Whether the value has been setup. */
protected volatile boolean set;
/**
* The primary constructor with instructions for producing the value.
*
* @param supplier A function generating the value when ready.
*/
public Lazy(@NotNull final Supplier supplier) {
this.supplier = supplier;
this.set = false;
}
/**
* To be used in the event that a value already exists.
*
* @param value The known value being wrapped.
*/
public Lazy(@NotNull final T value) {
this.value = value;
this.supplier = () -> value;
this.set = true;
}
/**
* Factory variant of {@link #Lazy(Supplier)}.
*
* @param The type of value being wrapped.
* @param supplier A supplier providing this value, when the time comes.
* @return The value, to be calculated on first use.s
*/
public static Lazy of(@NotNull final Supplier supplier) {
return new Lazy<>(supplier);
}
/**
* Factory variant of {@link #Lazy(Object)}.
*
* @param The type of value being wrapped.
* @param value The actual value being wrapped.
* @return The value, consumed by the wrapper.
*/
public static Lazy of(@NotNull final T value) {
return new Lazy<>(value);
}
/**
* Converts this wrapper into a resettable or non-resettable value.
*
* @param resettable Whether the wrapper should be resettable.
* @return Either this
or a {@link ResettableLazy}.
*/
public Lazy asResettable(final boolean resettable) {
if (resettable) {
return this.set ? new ResettableLazy<>(this.value) : new ResettableLazy<>(this.supplier);
}
return this;
}
/**
* The primary method for retrieving the underlying value.
*
* @return The underlying value.
*/
@NotNull
@Override
public T get() {
if (!this.set) {
synchronized(this) {
this.value = this.supplier.get();
this.set = true;
}
}
return value;
}
/**
* Returns the value only if it has already been computed.
*
* @return The actual value, if ready.
*/
public Optional getIfComputed() {
return Optional.ofNullable(this.value);
}
/**
* Returns whether the underlying operation has completed.
*
* @return whether the value has been computed.
*/
public boolean computed() {
return this.set;
}
/**
* Returns an up-to-date value without resetting this value's reference.
*
* @return A regenerated value using the given supplier.
*/
public T getUpdated() {
return this.supplier.get();
}
/**
* Returns whether the underlying data can be reloaded.
*
* @return true
if this type supports reloading its value.
*/
public boolean isResettable() {
return false;
}
/**
* Exposes the data directly without wrapping them in {@link Optional}.
*
* @return The raw value, or else null
.
*/
@Nullable
public T expose() {
return this.value;
}
@Override
public String toString() {
return this.set ? this.value.toString() : "";
}
}