161 lines
5.4 KiB
Java
161 lines
5.4 KiB
Java
/*
|
|
* 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.concurrent.Callable;
|
|
|
|
import com.google.common.base.Throwables;
|
|
|
|
import net.minecraft.nbt.INBTBase;
|
|
import net.minecraft.util.EnumFacing;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
/**
|
|
* This is the core holder object Capabilities.
|
|
* Each capability will have ONE instance of this class,
|
|
* and it will the the one passed into the ICapabilityProvider functions.
|
|
*
|
|
* The CapabilityManager is in charge of creating this class.
|
|
*/
|
|
public class Capability<T>
|
|
{
|
|
public static interface IStorage<T>
|
|
{
|
|
/**
|
|
* Serialize the capability instance to a NBTTag.
|
|
* This allows for a central implementation of saving the data.
|
|
*
|
|
* It is important to note that it is up to the API defining
|
|
* the capability what requirements the 'instance' value must have.
|
|
*
|
|
* Due to the possibility of manipulating internal data, some
|
|
* implementations MAY require that the 'instance' be an instance
|
|
* of the 'default' implementation.
|
|
*
|
|
* Review the API docs for more info.
|
|
*
|
|
* @param capability The Capability being stored.
|
|
* @param instance An instance of that capabilities interface.
|
|
* @param side The side of the object the instance is associated with.
|
|
* @return a NBT holding the data. Null if no data needs to be stored.
|
|
*/
|
|
@Nullable
|
|
INBTBase writeNBT(Capability<T> capability, T instance, EnumFacing side);
|
|
|
|
/**
|
|
* Read the capability instance from a NBT tag.
|
|
*
|
|
* This allows for a central implementation of saving the data.
|
|
*
|
|
* It is important to note that it is up to the API defining
|
|
* the capability what requirements the 'instance' value must have.
|
|
*
|
|
* Due to the possibility of manipulating internal data, some
|
|
* implementations MAY require that the 'instance' be an instance
|
|
* of the 'default' implementation.
|
|
*
|
|
* Review the API docs for more info. *
|
|
*
|
|
* @param capability The Capability being stored.
|
|
* @param instance An instance of that capabilities interface.
|
|
* @param side The side of the object the instance is associated with.
|
|
* @param nbt A NBT holding the data. Must not be null, as doesn't make sense to call this function with nothing to read...
|
|
*/
|
|
void readNBT(Capability<T> capability, T instance, EnumFacing side, INBTBase nbt);
|
|
}
|
|
|
|
/**
|
|
* @return The unique name of this capability, typically this is
|
|
* the fully qualified class name for the target interface.
|
|
*/
|
|
public String getName() { return name; }
|
|
|
|
/**
|
|
* @return An instance of the default storage handler. You can safely use this store your default implementation in NBT.
|
|
*/
|
|
public IStorage<T> getStorage() { return storage; }
|
|
|
|
/**
|
|
* Quick access to the IStorage's readNBT.
|
|
* See {@link IStorage#readNBT(Capability, Object, EnumFacing, NBTBase)} for documentation.
|
|
*/
|
|
public void readNBT(T instance, EnumFacing side, INBTBase nbt)
|
|
{
|
|
storage.readNBT(this, instance, side, nbt);
|
|
}
|
|
|
|
/**
|
|
* Quick access to the IStorage's writeNBT.
|
|
* See {@link IStorage#writeNBT(Capability, Object, EnumFacing)} for documentation.
|
|
*/
|
|
@Nullable
|
|
public INBTBase writeNBT(T instance, EnumFacing side)
|
|
{
|
|
return storage.writeNBT(this, instance, side);
|
|
}
|
|
|
|
/**
|
|
* A NEW instance of the default implementation.
|
|
*
|
|
* If it important to note that if you want to use the default storage
|
|
* you may be required to use this exact implementation.
|
|
* Refer to the owning API of the Capability in question.
|
|
*
|
|
* @return A NEW instance of the default implementation.
|
|
*/
|
|
@Nullable
|
|
public T getDefaultInstance()
|
|
{
|
|
try
|
|
{
|
|
return this.factory.call();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Throwables.throwIfUnchecked(e);
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Use this inside ICapabilityProvider.getCapability to avoid unchecked cast warnings.
|
|
* Example: return SOME_CAPABILITY.cast(instance);
|
|
* Use with caution;
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public <R> R cast(T instance)
|
|
{
|
|
return (R)instance;
|
|
}
|
|
|
|
// INTERNAL
|
|
private final String name;
|
|
private final IStorage<T> storage;
|
|
private final Callable<? extends T> factory;
|
|
|
|
Capability(String name, IStorage<T> storage, Callable<? extends T> factory)
|
|
{
|
|
this.name = name;
|
|
this.storage = storage;
|
|
this.factory = factory;
|
|
}
|
|
}
|