Refactor OptionalCapabilityInstance to LazyOptional; clean up
- Move to util package, rename to LazyOptional - Clean up existing javadocs, add javadocs to everything missing them - Add more NonNull functional interfaces, and use them everywhere - Move orEmpty() to Capability, works better here anyways
This commit is contained in:
parent
0a11ffb827
commit
8e43dfa7a6
20 changed files with 444 additions and 294 deletions
|
@ -31,11 +31,11 @@ import net.minecraft.world.IWorldReader;
|
|||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.common.animation.Event;
|
||||
import net.minecraftforge.common.animation.IEventHandler;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.model.animation.CapabilityAnimation;
|
||||
import net.minecraftforge.common.model.animation.IAnimationStateMachine;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class TileEntityRendererAnimation<T extends TileEntity> extends TileEntit
|
|||
@Override
|
||||
public void renderTileEntityFast(T te, double x, double y, double z, float partialTick, int breakStage, BufferBuilder renderer)
|
||||
{
|
||||
OptionalCapabilityInstance<IAnimationStateMachine> cap = te.getCapability(CapabilityAnimation.ANIMATION_CAPABILITY);
|
||||
LazyOptional<IAnimationStateMachine> cap = te.getCapability(CapabilityAnimation.ANIMATION_CAPABILITY);
|
||||
if(!cap.isPresent())
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -25,7 +25,9 @@ import com.google.common.base.Throwables;
|
|||
|
||||
import net.minecraft.nbt.INBTBase;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -135,6 +137,11 @@ public class Capability<T>
|
|||
}
|
||||
}
|
||||
|
||||
public @Nonnull <R> LazyOptional<R> orEmpty(Capability<R> toCheck, LazyOptional<T> inst)
|
||||
{
|
||||
return this == toCheck ? inst.cast() : LazyOptional.empty();
|
||||
}
|
||||
|
||||
// INTERNAL
|
||||
private final String name;
|
||||
private final IStorage<T> storage;
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.util.INBTSerializable;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
/**
|
||||
* A high-speed implementation of a capability delegator.
|
||||
|
@ -92,16 +93,16 @@ public final class CapabilityDispatcher implements INBTSerializable<NBTTagCompou
|
|||
|
||||
|
||||
@Override
|
||||
public <T> OptionalCapabilityInstance<T> getCapability(Capability<T> cap, @Nullable EnumFacing side)
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, @Nullable EnumFacing side)
|
||||
{
|
||||
for (ICapabilityProvider c : caps)
|
||||
{
|
||||
OptionalCapabilityInstance<T> ret = c.getCapability(cap, side);
|
||||
LazyOptional<T> ret = c.getCapability(cap, side);
|
||||
if (ret.isPresent()) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return OptionalCapabilityInstance.empty();
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
|||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
|
@ -98,9 +99,9 @@ public abstract class CapabilityProvider<B extends CapabilityProvider<B>> implem
|
|||
|
||||
@Override
|
||||
@Nonnull
|
||||
public <T> OptionalCapabilityInstance<T> getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing side)
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing side)
|
||||
{
|
||||
final CapabilityDispatcher disp = getCapabilities();
|
||||
return disp == null ? OptionalCapabilityInstance.empty() : disp.getCapability(cap, side);
|
||||
return disp == null ? LazyOptional.empty() : disp.getCapability(cap, side);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.annotation.Nonnull;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public interface ICapabilityProvider
|
||||
{
|
||||
|
@ -37,13 +38,13 @@ public interface ICapabilityProvider
|
|||
* <strong>CAN BE NULL</strong>. Null is defined to represent 'internal' or 'self'
|
||||
* @return The requested an optional holding the requested capability.
|
||||
*/
|
||||
@Nonnull <T> OptionalCapabilityInstance<T> getCapability(@Nonnull final Capability<T> cap, final @Nullable EnumFacing side);
|
||||
@Nonnull <T> LazyOptional<T> getCapability(@Nonnull final Capability<T> cap, final @Nullable EnumFacing side);
|
||||
|
||||
/*
|
||||
* Purely added as a bouncer to sided version, to make modders stop complaining about calling with a null value.
|
||||
* This should never be OVERRIDDEN, modders should only ever implement the sided version.
|
||||
*/
|
||||
@Nonnull default <T> OptionalCapabilityInstance<T> getCapability(@Nonnull final Capability<T> cap) {
|
||||
@Nonnull default <T> LazyOptional<T> getCapability(@Nonnull final Capability<T> cap) {
|
||||
return getCapability(cap, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,241 +0,0 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2018.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.capabilities;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
public class OptionalCapabilityInstance<T>
|
||||
{
|
||||
private final NonNullSupplier<T> supplier;
|
||||
private AtomicReference<T> resolved;
|
||||
private Set<Consumer<OptionalCapabilityInstance<T>>> listeners = new HashSet<>();
|
||||
private boolean isValid = true;
|
||||
|
||||
private static final @Nonnull OptionalCapabilityInstance<Void> EMPTY = new OptionalCapabilityInstance<>(null);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> OptionalCapabilityInstance<T> empty()
|
||||
{
|
||||
return (OptionalCapabilityInstance<T>)EMPTY;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <X> OptionalCapabilityInstance<X> cast()
|
||||
{
|
||||
return (OptionalCapabilityInstance<X>)this;
|
||||
}
|
||||
|
||||
private OptionalCapabilityInstance(@Nullable NonNullSupplier<T> instanceSupplier)
|
||||
{
|
||||
this.supplier = instanceSupplier;
|
||||
}
|
||||
|
||||
public static <T> OptionalCapabilityInstance<T> of(final @Nullable NonNullSupplier<T> instanceSupplier)
|
||||
{
|
||||
return instanceSupplier == null ? EMPTY.cast() : new OptionalCapabilityInstance<>(instanceSupplier);
|
||||
}
|
||||
|
||||
public static <T, R> OptionalCapabilityInstance<R> orEmpty(Capability<R> cap, Capability<T> toCheck, OptionalCapabilityInstance<T> inst)
|
||||
{
|
||||
return cap == toCheck ? inst.cast() : EMPTY.cast();
|
||||
}
|
||||
|
||||
private @Nullable T getValue()
|
||||
{
|
||||
if (!isValid)
|
||||
return null;
|
||||
if (resolved != null)
|
||||
return resolved.get();
|
||||
|
||||
if (supplier != null)
|
||||
{
|
||||
resolved = new AtomicReference<>(null);
|
||||
try
|
||||
{
|
||||
T temp = supplier.get();
|
||||
if (temp == null)
|
||||
throw new IllegalStateException("Supplier must not return null value");
|
||||
resolved.set(temp);
|
||||
return resolved.get();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if there is a mod object present, otherwise {@code false}.
|
||||
*
|
||||
* @return {@code true} if there is a mod object present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent()
|
||||
{
|
||||
return supplier != null && isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a mod object is present, invoke the specified consumer with the object,
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* @param consumer block to be executed if a mod object is present
|
||||
* @throws NullPointerException if mod object is present and {@code consumer} is
|
||||
* null
|
||||
*/
|
||||
public void ifPresent(NonNullConsumer<? super T> consumer)
|
||||
{
|
||||
T val = getValue();
|
||||
if (isValid && val != null)
|
||||
consumer.accept(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a mod object is present, and the mod object matches the given predicate,
|
||||
* return an {@code OptionalMod} describing the value, otherwise return an
|
||||
* empty {@code OptionalMod}.
|
||||
*
|
||||
* @param predicate a predicate to apply to the mod object, if present
|
||||
* @return an {@code OptionalMod} describing the value of this {@code OptionalMod}
|
||||
* if a mod object is present and the mod object matches the given predicate,
|
||||
* otherwise an empty {@code OptionalMod}
|
||||
* @throws NullPointerException if the predicate is null
|
||||
*/
|
||||
public OptionalCapabilityInstance<T> filter(Predicate<? super T> predicate)
|
||||
{
|
||||
Objects.requireNonNull(predicate);
|
||||
final T value = getValue(); // To keep the non-null contract we have to evaluate right now. Should we allow this function at all?
|
||||
return predicate.test(value) ? OptionalCapabilityInstance.of(()->value) : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* If a mod object is present, apply the provided mapping function to it,
|
||||
* and if the result is non-null, return an {@code Optional} describing the
|
||||
* result. Otherwise return an empty {@code Optional}.
|
||||
*
|
||||
* @apiNote This method supports post-processing on optional values, without
|
||||
* the need to explicitly check for a return status.
|
||||
*
|
||||
* @param <U> The type of the result of the mapping function
|
||||
* @param mapper a mapping function to apply to the mod object, if present
|
||||
* @return an {@code Optional} describing the result of applying a mapping
|
||||
* function to the mod object of this {@code OptionalMod}, if a mod object is present,
|
||||
* otherwise an empty {@code Optional}
|
||||
* @throws NullPointerException if the mapping function is null
|
||||
*/
|
||||
public<U> OptionalCapabilityInstance<U> map(Function<? super T, ? extends U> mapper)
|
||||
{
|
||||
Objects.requireNonNull(mapper);
|
||||
return isPresent() ? OptionalCapabilityInstance.of(()->mapper.apply(getValue())) : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mod object if present, otherwise return {@code other}.
|
||||
*
|
||||
* @param other the mod object to be returned if there is no mod object present, may
|
||||
* be null
|
||||
* @return the mod object, if present, otherwise {@code other}
|
||||
*/
|
||||
public T orElse(T other)
|
||||
{
|
||||
T val = getValue();
|
||||
return val != null ? val : other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mod object if present, otherwise invoke {@code other} and return
|
||||
* the result of that invocation.
|
||||
*
|
||||
* @param other a {@code Supplier} whose result is returned if no mod object
|
||||
* is present
|
||||
* @return the mod object if present otherwise the result of {@code other.get()}
|
||||
* @throws NullPointerException if mod object is not present and {@code other} is
|
||||
* null
|
||||
*/
|
||||
public T orElseGet(NonNullSupplier<? extends T> other)
|
||||
{
|
||||
T val = getValue();
|
||||
return val != null ? val : other.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contained mod object, if present, otherwise throw an exception
|
||||
* to be created by the provided supplier.
|
||||
*
|
||||
* @apiNote A method reference to the exception constructor with an empty
|
||||
* argument list can be used as the supplier. For example,
|
||||
* {@code IllegalStateException::new}
|
||||
*
|
||||
* @param <X> Type of the exception to be thrown
|
||||
* @param exceptionSupplier The supplier which will return the exception to
|
||||
* be thrown
|
||||
* @return the present mod object
|
||||
* @throws X if there is no mod object present
|
||||
* @throws NullPointerException if no mod object is present and
|
||||
* {@code exceptionSupplier} is null
|
||||
*/
|
||||
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
|
||||
{
|
||||
T val = getValue();
|
||||
if (val != null)
|
||||
return val;
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a listener that will be called when this Optional becomes invalid.
|
||||
*/
|
||||
public void addListener(Consumer<OptionalCapabilityInstance<T>> listener)
|
||||
{
|
||||
if (!isPresent())
|
||||
listener.accept(this); // They are stupid so just directly call them.
|
||||
else
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
/*
|
||||
* Should only be called by the 'Owner' of this capability, this is to notify any listerners that this has become invalid and they should update.
|
||||
* 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 caps when a TE is invalidated, or a world/chunk unloads, or a entity dies, etc...
|
||||
* This allows modders to keep a cache of Capabilities instead of re-checking them every tick.
|
||||
*/
|
||||
public void invalidate()
|
||||
{
|
||||
this.isValid = false;
|
||||
this.listeners.forEach(e -> e.accept(this));
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ import net.minecraftforge.common.capabilities.Capability;
|
|||
import net.minecraftforge.common.capabilities.CapabilityInject;
|
||||
import net.minecraftforge.common.capabilities.CapabilityManager;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -53,18 +53,18 @@ public class CapabilityAnimation
|
|||
public static class DefaultItemAnimationCapabilityProvider implements ICapabilityProvider
|
||||
{
|
||||
@Nonnull
|
||||
private final OptionalCapabilityInstance<IAnimationStateMachine> asm;
|
||||
private final LazyOptional<IAnimationStateMachine> asm;
|
||||
|
||||
public DefaultItemAnimationCapabilityProvider(@Nonnull OptionalCapabilityInstance<IAnimationStateMachine> asm)
|
||||
public DefaultItemAnimationCapabilityProvider(@Nonnull LazyOptional<IAnimationStateMachine> asm)
|
||||
{
|
||||
this.asm = asm;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public <T> OptionalCapabilityInstance<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
{
|
||||
return OptionalCapabilityInstance.orEmpty(capability, ANIMATION_CAPABILITY, asm);
|
||||
return ANIMATION_CAPABILITY.orEmpty(capability, asm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
298
src/main/java/net/minecraftforge/common/util/LazyOptional.java
Normal file
298
src/main/java/net/minecraftforge/common/util/LazyOptional.java
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2018.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.util;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
|
||||
/**
|
||||
* This object encapsulates a lazy value, with typical transformation operations
|
||||
* (map/ifPresent) available, much like {@link Optional}.
|
||||
* <p>
|
||||
* It also provides the ability to listen for invalidation, via
|
||||
* {@link #addListener(Consumer)}. This method is invoked when the provider of
|
||||
* this object calls {@link #invalidate()}.
|
||||
* <p>
|
||||
* To create an instance of this class, use {@link #of(NonNullSupplier)}. Note
|
||||
* that this accepts a {@link NonNullSupplier}, so the result of the supplier
|
||||
* must never be null.
|
||||
* <p>
|
||||
* The empty instance can be retrieved with {@link #empty()}.
|
||||
*
|
||||
* @param <T> The type of the optional value.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
public class LazyOptional<T>
|
||||
{
|
||||
private final NonNullSupplier<T> supplier;
|
||||
private AtomicReference<T> resolved;
|
||||
private Set<NonNullConsumer<LazyOptional<T>>> listeners = new HashSet<>();
|
||||
private boolean isValid = true;
|
||||
|
||||
private static final @Nonnull LazyOptional<Void> EMPTY = new LazyOptional<>(null);
|
||||
|
||||
/**
|
||||
* Construct a new {@link LazyOptional} that wraps the given
|
||||
* {@link NonNullSupplier}.
|
||||
*
|
||||
* @param instanceSupplier The {@link NonNullSupplier} to wrap. Cannot return
|
||||
* null, but can be null itself. If null, this method
|
||||
* returns {@link #empty()}.
|
||||
*/
|
||||
public static <T> LazyOptional<T> of(final @Nullable NonNullSupplier<T> instanceSupplier)
|
||||
{
|
||||
return instanceSupplier == null ? empty() : new LazyOptional<>(instanceSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The singleton empty instance
|
||||
*/
|
||||
public static <T> LazyOptional<T> empty()
|
||||
{
|
||||
return EMPTY.cast();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method hides an unchecked cast to the inferred type. Only use this if
|
||||
* you are sure the type should match. For capabilities, generally
|
||||
* {@link Capability#orEmpty(Capability, LazyOptional)} should be used.
|
||||
*
|
||||
* @return This {@link LazyOptional}, cast to the inferred generic type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <X> LazyOptional<X> cast()
|
||||
{
|
||||
return (LazyOptional<X>)this;
|
||||
}
|
||||
|
||||
private LazyOptional(@Nullable NonNullSupplier<T> instanceSupplier)
|
||||
{
|
||||
this.supplier = instanceSupplier;
|
||||
}
|
||||
|
||||
private @Nullable T getValue()
|
||||
{
|
||||
if (!isValid)
|
||||
return null;
|
||||
if (resolved != null)
|
||||
return resolved.get();
|
||||
|
||||
if (supplier != null)
|
||||
{
|
||||
resolved = new AtomicReference<>(null);
|
||||
try
|
||||
{
|
||||
T temp = supplier.get();
|
||||
if (temp == null)
|
||||
throw new IllegalStateException("Supplier must not return null value");
|
||||
resolved.set(temp);
|
||||
return resolved.get();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private T getValueUnsafe()
|
||||
{
|
||||
T ret = getValue();
|
||||
if (ret == null)
|
||||
{
|
||||
throw new IllegalStateException("LazyOptional is empty or otherwise returned null from getValue() unexpectedly");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this {@link LazyOptional} is non-empty.
|
||||
*
|
||||
* @return {@code true} if this {@link LazyOptional} is non-empty, i.e. holds a
|
||||
* non-null supplier
|
||||
*/
|
||||
public boolean isPresent()
|
||||
{
|
||||
return supplier != null && isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* If non-empty, invoke the specified {@link NonNullConsumer} with the object,
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* @param The {@link NonNullConsumer} to run if this optional is non-empty.
|
||||
* @throws NullPointerException if {@code consumer} is null and this {@link LazyOptional} is non-empty
|
||||
*/
|
||||
public void ifPresent(NonNullConsumer<? super T> consumer)
|
||||
{
|
||||
Objects.requireNonNull(consumer);
|
||||
T val = getValue();
|
||||
if (isValid && val != null)
|
||||
consumer.accept(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a this {@link LazyOptional} is non-empty, return a new
|
||||
* {@link LazyOptional} encapsulating the mapping function. Otherwise, returns
|
||||
* {@link #empty()}.
|
||||
* <p>
|
||||
* The supplier inside this object is <strong>NOT</strong> resolved.
|
||||
*
|
||||
* @apiNote This method supports post-processing on optional values, without the
|
||||
* need to explicitly check for a return status.
|
||||
*
|
||||
* @param <U> The type of the result of the mapping function
|
||||
* @param mapper A mapping function to apply to the mod object, if present
|
||||
* @return A {@link LazyOptional} describing the result of applying a mapping
|
||||
* function to the value of this {@link LazyOptional}, if a value is
|
||||
* present, otherwise an empty {@link LazyOptional}
|
||||
* @throws NullPointerException if {@code mapper} is null and this {@link LazyOptional} is non-empty
|
||||
*/
|
||||
public <U> LazyOptional<U> map(NonNullFunction<? super T, ? extends U> mapper)
|
||||
{
|
||||
Objects.requireNonNull(mapper);
|
||||
return isPresent() ? of(() -> mapper.apply(getValueUnsafe())) : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the contained supplier if non-empty, and filter it by the given
|
||||
* {@link NonNullPredicate}, returning empty if false.
|
||||
* <p>
|
||||
* <em>It is important to note that this method is <strong>not</strong> lazy, as
|
||||
* it must resolve the value of the supplier to validate it with the
|
||||
* predicate.</em>
|
||||
*
|
||||
* @param predicate A {@link NonNullPredicate} to apply to the result of the
|
||||
* contained supplier, if non-empty
|
||||
* @return A {@link LazyOptional} containing the result of the contained
|
||||
* supplier, if and only if the passed {@link NonNullPredicate} returns
|
||||
* true, otherwise an empty {@link LazyOptional}
|
||||
* @throws NullPointerException If {@code predicate} is null and this
|
||||
* {@link LazyOptional} is non-empty
|
||||
*/
|
||||
public LazyOptional<T> filter(NonNullPredicate<? super T> predicate)
|
||||
{
|
||||
Objects.requireNonNull(predicate);
|
||||
final T value = getValue(); // To keep the non-null contract we have to evaluate right now. Should we allow this function at all?
|
||||
return value != null && predicate.test(value) ? of(() -> value) : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the contained supplier if non-empty and return the result, otherwise return
|
||||
* {@code other}.
|
||||
*
|
||||
* @param other the value to be returned if this {@link LazyOptional} is empty
|
||||
* @return the result of the supplier, if non-empty, otherwise {@code other}
|
||||
*/
|
||||
public T orElse(T other)
|
||||
{
|
||||
T val = getValue();
|
||||
return val != null ? val : other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the contained supplier if non-empty and return the result, otherwise return the
|
||||
* result of {@code other}.
|
||||
*
|
||||
* @param other A {@link NonNullSupplier} whose result is returned if this
|
||||
* {@link LazyOptional} is empty
|
||||
* @return The result of the supplier, if non-empty, otherwise the result of
|
||||
* {@code other.get()}
|
||||
* @throws NullPointerException If {@code other} is null and this
|
||||
* {@link LazyOptional} is non-empty
|
||||
*/
|
||||
public T orElseGet(NonNullSupplier<? extends T> other)
|
||||
{
|
||||
T val = getValue();
|
||||
return val != null ? val : other.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the contained supplier if non-empty and return the result, otherwise throw the
|
||||
* exception created by the provided {@link NonNullSupplier}.
|
||||
*
|
||||
* @apiNote A method reference to the exception constructor with an empty
|
||||
* argument list can be used as the supplier. For example,
|
||||
* {@code IllegalStateException::new}
|
||||
*
|
||||
* @param <X> Type of the exception to be thrown
|
||||
* @param exceptionSupplier The {@link NonNullSupplier} which will return the
|
||||
* exception to be thrown
|
||||
* @return The result of the supplier
|
||||
* @throws X If this {@link LazyOptional} is empty
|
||||
* @throws NullPointerException If {@code exceptionSupplier} is null and this
|
||||
* {@link LazyOptional} is empty
|
||||
*/
|
||||
public <X extends Throwable> T orElseThrow(NonNullSupplier<? extends X> exceptionSupplier) throws X
|
||||
{
|
||||
T val = getValue();
|
||||
if (val != null)
|
||||
return val;
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link NonNullConsumer listener} that will be called when this {@link LazyOptional} becomes invalid (via {@link #invalidate()}).
|
||||
* <p>
|
||||
* If this {@link LazyOptional} is empty, the listener will be called immediately.
|
||||
*/
|
||||
public void addListener(NonNullConsumer<LazyOptional<T>> listener)
|
||||
{
|
||||
if (isPresent())
|
||||
{
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
listener.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate this {@link LazyOptional}, making it unavailable for further use,
|
||||
* and notifying any {@link #addListener(NonNullConsumer) listeners} that this
|
||||
* has become invalid and they should update.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* Also should be called for all when a TE is invalidated, 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.
|
||||
*/
|
||||
public void invalidate()
|
||||
{
|
||||
this.isValid = false;
|
||||
this.listeners.forEach(e -> e.accept(this));
|
||||
}
|
||||
}
|
|
@ -17,11 +17,17 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.capabilities;
|
||||
package net.minecraftforge.common.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
//Exactly like Consumer, except there IS a contract that the parameter must not be null.
|
||||
/**
|
||||
* Equivalent to {@link Consumer}, except with nonnull contract.
|
||||
*
|
||||
* @see Consumer
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface NonNullConsumer<T>
|
||||
{
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2018.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.util;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Equivalent to {@link Function}, except with nonnull contract.
|
||||
*
|
||||
* @see Function
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface NonNullFunction<T, R>
|
||||
{
|
||||
@Nonnull
|
||||
R apply(@Nonnull T t);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2018.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.util;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Equivalent to {@link Predicate}, except with nonnull contract.
|
||||
*
|
||||
* @see Predicate
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface NonNullPredicate<T>
|
||||
{
|
||||
boolean test(@Nonnull T t);
|
||||
}
|
|
@ -17,11 +17,17 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.common.capabilities;
|
||||
package net.minecraftforge.common.util;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
//Exactly like Supplier, except there IS a contract that each invocation should return a new unique instance and it must not be null.
|
||||
/**
|
||||
* Equivalent to {@link Supplier}, except with nonnull contract.
|
||||
*
|
||||
* @see Supplier
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface NonNullSupplier<T>
|
||||
{
|
|
@ -41,7 +41,7 @@ import net.minecraft.util.SoundEvent;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
||||
|
@ -434,7 +434,7 @@ public class FluidUtil
|
|||
*
|
||||
* Vanilla buckets will be converted to universal buckets if they are enabled.
|
||||
*/
|
||||
public static OptionalCapabilityInstance<IFluidHandlerItem> getFluidHandler(@Nonnull ItemStack itemStack)
|
||||
public static LazyOptional<IFluidHandlerItem> getFluidHandler(@Nonnull ItemStack itemStack)
|
||||
{
|
||||
return itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ public class FluidUtil
|
|||
/**
|
||||
* Helper method to get the fluid contained in an itemStack
|
||||
*/
|
||||
public static OptionalCapabilityInstance<FluidStack> getFluidContained(@Nonnull ItemStack container)
|
||||
public static LazyOptional<FluidStack> getFluidContained(@Nonnull ItemStack container)
|
||||
{
|
||||
if (!container.isEmpty())
|
||||
{
|
||||
|
@ -450,13 +450,13 @@ public class FluidUtil
|
|||
return getFluidHandler(container)
|
||||
.map(handler -> handler.drain(Integer.MAX_VALUE, false));
|
||||
}
|
||||
return OptionalCapabilityInstance.empty();
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get an IFluidHandler for at a block position.
|
||||
*/
|
||||
public static OptionalCapabilityInstance<IFluidHandler> getFluidHandler(World world, BlockPos blockPos, @Nullable EnumFacing side)
|
||||
public static LazyOptional<IFluidHandler> getFluidHandler(World world, BlockPos blockPos, @Nullable EnumFacing side)
|
||||
{
|
||||
IBlockState state = world.getBlockState(blockPos);
|
||||
Block block = state.getBlock();
|
||||
|
@ -478,7 +478,7 @@ public class FluidUtil
|
|||
return OptionalCapabilityInstance.of(() -> new BlockLiquidWrapper((BlockLiquid) block, world, blockPos));
|
||||
}
|
||||
*/
|
||||
return OptionalCapabilityInstance.empty();
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,7 +24,7 @@ import net.minecraft.tileentity.TileEntity;
|
|||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidTank;
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class TileFluidHandler extends TileEntity
|
|||
{
|
||||
protected FluidTank tank = new FluidTank(Fluid.BUCKET_VOLUME);
|
||||
|
||||
private final OptionalCapabilityInstance<IFluidHandler> holder = OptionalCapabilityInstance.of(() -> tank);
|
||||
private final LazyOptional<IFluidHandler> holder = LazyOptional.of(() -> tank);
|
||||
|
||||
public TileFluidHandler(@Nonnull TileEntityType<?> tileEntityTypeIn)
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ public class TileFluidHandler extends TileEntity
|
|||
|
||||
@Override
|
||||
@Nonnull
|
||||
public <T> OptionalCapabilityInstance<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
{
|
||||
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
|
||||
return holder.cast();
|
||||
|
|
|
@ -27,7 +27,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.*;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.FluidTankProperties;
|
||||
|
@ -47,7 +47,7 @@ public class FluidHandlerItemStack implements IFluidHandlerItem, ICapabilityProv
|
|||
{
|
||||
public static final String FLUID_NBT_KEY = "Fluid";
|
||||
|
||||
private final OptionalCapabilityInstance<IFluidHandlerItem> holder = OptionalCapabilityInstance.of(() -> this);
|
||||
private final LazyOptional<IFluidHandlerItem> holder = LazyOptional.of(() -> this);
|
||||
|
||||
@Nonnull
|
||||
protected ItemStack container;
|
||||
|
@ -205,9 +205,9 @@ public class FluidHandlerItemStack implements IFluidHandlerItem, ICapabilityProv
|
|||
|
||||
@Override
|
||||
@Nonnull
|
||||
public <T> OptionalCapabilityInstance<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
{
|
||||
return OptionalCapabilityInstance.orEmpty(capability, CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, holder);
|
||||
return CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY.orEmpty(capability, holder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,7 +27,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.FluidTankProperties;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
||||
|
@ -44,7 +44,7 @@ public class FluidHandlerItemStackSimple implements IFluidHandlerItem, ICapabili
|
|||
{
|
||||
public static final String FLUID_NBT_KEY = "Fluid";
|
||||
|
||||
private final OptionalCapabilityInstance<IFluidHandlerItem> holder = OptionalCapabilityInstance.of(() -> this);
|
||||
private final LazyOptional<IFluidHandlerItem> holder = LazyOptional.of(() -> this);
|
||||
|
||||
@Nonnull
|
||||
protected ItemStack container;
|
||||
|
@ -182,9 +182,9 @@ public class FluidHandlerItemStackSimple implements IFluidHandlerItem, ICapabili
|
|||
|
||||
@Override
|
||||
@Nonnull
|
||||
public <T> OptionalCapabilityInstance<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
{
|
||||
return OptionalCapabilityInstance.orEmpty(capability, CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, holder);
|
||||
return CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY.orEmpty(capability, holder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,7 +30,7 @@ import net.minecraft.util.EnumFacing;
|
|||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
@ -46,7 +46,7 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
|||
*/
|
||||
public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvider
|
||||
{
|
||||
private final OptionalCapabilityInstance<IFluidHandlerItem> holder = OptionalCapabilityInstance.of(() -> this);
|
||||
private final LazyOptional<IFluidHandlerItem> holder = LazyOptional.of(() -> this);
|
||||
|
||||
@Nonnull
|
||||
protected ItemStack container;
|
||||
|
@ -175,8 +175,8 @@ public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvide
|
|||
|
||||
@Override
|
||||
@Nonnull
|
||||
public <T> OptionalCapabilityInstance<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
|
||||
{
|
||||
return OptionalCapabilityInstance.orEmpty(capability, CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, holder);
|
||||
return CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY.orEmpty(capability, holder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import net.minecraft.util.EnumFacing;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
@ -212,7 +212,7 @@ public class VanillaInventoryCodeHooks
|
|||
return stack;
|
||||
}
|
||||
|
||||
private static OptionalCapabilityInstance<Pair<IItemHandler, Object>> getItemHandler(IHopper hopper, EnumFacing hopperFacing)
|
||||
private static LazyOptional<Pair<IItemHandler, Object>> getItemHandler(IHopper hopper, EnumFacing hopperFacing)
|
||||
{
|
||||
double x = hopper.getXPos() + (double) hopperFacing.getXOffset();
|
||||
double y = hopper.getYPos() + (double) hopperFacing.getYOffset();
|
||||
|
@ -246,7 +246,7 @@ public class VanillaInventoryCodeHooks
|
|||
return true;
|
||||
}
|
||||
|
||||
public static OptionalCapabilityInstance<Pair<IItemHandler, Object>> getItemHandler(World worldIn, double x, double y, double z, final EnumFacing side)
|
||||
public static LazyOptional<Pair<IItemHandler, Object>> getItemHandler(World worldIn, double x, double y, double z, final EnumFacing side)
|
||||
{
|
||||
int i = MathHelper.floor(x);
|
||||
int j = MathHelper.floor(y);
|
||||
|
@ -264,6 +264,6 @@ public class VanillaInventoryCodeHooks
|
|||
}
|
||||
}
|
||||
|
||||
return OptionalCapabilityInstance.empty();
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
@ -194,13 +194,13 @@ public abstract class EntityEquipmentInvWrapper implements IItemHandlerModifiabl
|
|||
return slots.get(slot);
|
||||
}
|
||||
|
||||
public static OptionalCapabilityInstance<IItemHandlerModifiable>[] create(EntityLivingBase entity)
|
||||
public static LazyOptional<IItemHandlerModifiable>[] create(EntityLivingBase entity)
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
OptionalCapabilityInstance<IItemHandlerModifiable>[] ret = new OptionalCapabilityInstance[3];
|
||||
ret[0] = OptionalCapabilityInstance.of(() -> new EntityHandsInvWrapper(entity));
|
||||
ret[1] = OptionalCapabilityInstance.of(() -> new EntityArmorInvWrapper(entity));
|
||||
ret[2] = OptionalCapabilityInstance.of(() -> new CombinedInvWrapper(ret[0].orElse(null), ret[1].orElse(null)));
|
||||
LazyOptional<IItemHandlerModifiable>[] ret = new LazyOptional[3];
|
||||
ret[0] = LazyOptional.of(() -> new EntityHandsInvWrapper(entity));
|
||||
ret[1] = LazyOptional.of(() -> new EntityArmorInvWrapper(entity));
|
||||
ret[2] = LazyOptional.of(() -> new CombinedInvWrapper(ret[0].orElse(null), ret[1].orElse(null)));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ package net.minecraftforge.items.wrapper;
|
|||
import net.minecraft.inventory.ISidedInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.OptionalCapabilityInstance;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
|
@ -34,11 +34,11 @@ public class SidedInvWrapper implements IItemHandlerModifiable
|
|||
protected final EnumFacing side;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static OptionalCapabilityInstance<IItemHandlerModifiable>[] create(ISidedInventory inv, EnumFacing... sides) {
|
||||
OptionalCapabilityInstance<IItemHandlerModifiable>[] ret = new OptionalCapabilityInstance[sides.length];
|
||||
public static LazyOptional<IItemHandlerModifiable>[] create(ISidedInventory inv, EnumFacing... sides) {
|
||||
LazyOptional<IItemHandlerModifiable>[] ret = new LazyOptional[sides.length];
|
||||
for (int x = 0; x < sides.length; x++) {
|
||||
final EnumFacing side = sides[x];
|
||||
ret[x] = OptionalCapabilityInstance.of(() -> new SidedInvWrapper(inv, side));
|
||||
ret[x] = LazyOptional.of(() -> new SidedInvWrapper(inv, side));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue