Class LazyOptional<T>

  • Type Parameters:
    T - The type of the optional value.

    @ParametersAreNonnullByDefault
    @MethodsReturnNonnullByDefault
    public class LazyOptional<T>
    extends java.lang.Object
    This object encapsulates a lazy value, with typical transformation operations (map/ifPresent) available, much like Optional.

    It also provides the ability to listen for invalidation, via addListener(NonNullConsumer). This method is invoked when the provider of this object calls invalidate().

    To create an instance of this class, use of(NonNullSupplier). Note that this accepts a NonNullSupplier, so the result of the supplier must never be null.

    The empty instance can be retrieved with empty().

    • Field Detail

      • lock

        private final java.lang.Object lock
      • resolved

        private org.apache.commons.lang3.mutable.Mutable<T> resolved
      • isValid

        private boolean isValid
      • EMPTY

        @Nonnull
        private static final LazyOptional<java.lang.Void> EMPTY
      • LOGGER

        private static final org.apache.logging.log4j.Logger LOGGER
    • Constructor Detail

      • LazyOptional

        private LazyOptional​(@Nullable
                             NonNullSupplier<T> instanceSupplier)
    • Method Detail

      • empty

        public static <T> LazyOptional<T> empty()
        Returns:
        The singleton empty instance
      • getValue

        @Nullable
        private T getValue()
      • getValueUnsafe

        private T getValueUnsafe()
      • isPresent

        public boolean isPresent()
        Check if this LazyOptional is non-empty.
        Returns:
        true if this LazyOptional is non-empty, i.e. holds a non-null supplier
      • ifPresent

        public void ifPresent​(NonNullConsumer<? super T> consumer)
        If non-empty, invoke the specified NonNullConsumer with the object, otherwise do nothing.
        Parameters:
        consumer - The NonNullConsumer to run if this optional is non-empty.
        Throws:
        java.lang.NullPointerException - if consumer is null and this LazyOptional is non-empty
      • lazyMap

        public <U> LazyOptional<U> lazyMap​(NonNullFunction<? super T,​? extends U> mapper)
        If a this LazyOptional is non-empty, return a new LazyOptional encapsulating the mapping function. Otherwise, returns empty().

        The supplier inside this object is NOT resolved.

        Parameters:
        mapper - A mapping function to apply to the mod object, if present
        Returns:
        A LazyOptional describing the result of applying a mapping function to the value of this LazyOptional, if a value is present, otherwise an empty LazyOptional
        Throws:
        java.lang.NullPointerException - if mapper is null.
      • map

        public <U> java.util.Optional<U> map​(NonNullFunction<? super T,​? extends U> mapper)
        If a this LazyOptional is non-empty, return a new Optional encapsulating the mapped value. Otherwise, returns Optional.empty().
        Parameters:
        mapper - A mapping function to apply to the mod object, if present
        Returns:
        An Optional describing the result of applying a mapping function to the value of this Optional, if a value is present, otherwise an empty Optional
        Throws:
        java.lang.NullPointerException - if mapper is null.
      • filter

        public java.util.Optional<T> filter​(NonNullPredicate<? super T> predicate)
        Resolve the contained supplier if non-empty, and filter it by the given NonNullPredicate, returning empty if false.

        It is important to note that this method is not lazy, as it must resolve the value of the supplier to validate it with the predicate.

        Parameters:
        predicate - A NonNullPredicate to apply to the result of the contained supplier, if non-empty
        Returns:
        An Optional containing the result of the contained supplier, if and only if the passed NonNullPredicate returns true, otherwise an empty Optional
        Throws:
        java.lang.NullPointerException - If predicate is null and this Optional is non-empty
      • resolve

        public java.util.Optional<T> resolve()
        Resolves the value of this LazyOptional, turning it into a standard non-lazy Optional
        Returns:
        The resolved optional.
      • orElse

        public T orElse​(T other)
        Resolve the contained supplier if non-empty and return the result, otherwise return other.
        Parameters:
        other - the value to be returned if this LazyOptional is empty
        Returns:
        the result of the supplier, if non-empty, otherwise other
      • orElseGet

        public T orElseGet​(NonNullSupplier<? extends T> other)
        Resolve the contained supplier if non-empty and return the result, otherwise return the result of other.
        Parameters:
        other - A NonNullSupplier whose result is returned if this LazyOptional is empty
        Returns:
        The result of the supplier, if non-empty, otherwise the result of other.get()
        Throws:
        java.lang.NullPointerException - If other is null and this LazyOptional is non-empty
      • orElseThrow

        public <X extends java.lang.Throwable> T orElseThrow​(NonNullSupplier<? extends X> exceptionSupplier)
                                                      throws X extends java.lang.Throwable
        Resolve the contained supplier if non-empty and return the result, otherwise throw the exception created by the provided NonNullSupplier.
        Type Parameters:
        X - Type of the exception to be thrown
        Parameters:
        exceptionSupplier - The NonNullSupplier which will return the exception to be thrown
        Returns:
        The result of the supplier
        Throws:
        X - If this LazyOptional is empty
        java.lang.NullPointerException - If exceptionSupplier is null and this LazyOptional is empty
        X extends java.lang.Throwable
      • invalidate

        public void invalidate()
        Invalidate this LazyOptional, making it unavailable for further use, and notifying any listeners that this has become invalid and they should update.

        This would typically be used with capability objects. For example, a TE would call this, if they are covered with a microblock panel, thus cutting off pipe connectivity to this side.

        Also should be called for all when a TE is invalidated (for example, when the TE is removed or unloaded), or a world/chunk unloads, or a entity dies, etc... This allows modders to keep a cache of capability objects instead of re-checking them every tick.