mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-09 00:40:29 +00:00
Clarify docs around registering peripherals
This commit is contained in:
parent
87ce41f251
commit
bdffabc08e
@ -8,6 +8,8 @@ plugins {
|
||||
id("cc-tweaked.vanilla")
|
||||
}
|
||||
|
||||
val mcVersion: String by extra
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
@ -17,8 +19,36 @@ dependencies {
|
||||
}
|
||||
|
||||
tasks.javadoc {
|
||||
title = "CC: Tweaked $version Minecraft $mcVersion"
|
||||
include("dan200/computercraft/api/**/*.java")
|
||||
|
||||
options {
|
||||
(this as StandardJavadocDocletOptions)
|
||||
|
||||
groups = mapOf(
|
||||
"Common" to listOf(
|
||||
"dan200.computercraft.api",
|
||||
"dan200.computercraft.api.lua",
|
||||
"dan200.computercraft.api.peripheral",
|
||||
),
|
||||
"Upgrades" to listOf(
|
||||
"dan200.computercraft.api.client.turtle",
|
||||
"dan200.computercraft.api.pocket",
|
||||
"dan200.computercraft.api.turtle",
|
||||
"dan200.computercraft.api.upgrades",
|
||||
),
|
||||
)
|
||||
|
||||
addBooleanOption("-allow-script-in-comments", true)
|
||||
bottom(
|
||||
"""
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@v1.29.0/components/prism-core.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@v1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
||||
<link href=" https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css " rel="stylesheet">
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
|
||||
// Include the core-api in our javadoc export. This is wrong, but it means we can export a single javadoc dump.
|
||||
source(project(":core-api").sourceSets.main.map { it.allJava })
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import dan200.computercraft.api.ComputerCraftAPI;
|
||||
* as a proxy for all network objects. Whilst the node may change networks, an element's node should remain constant
|
||||
* for its lifespan.
|
||||
* <p>
|
||||
* Elements are generally tied to a block or tile entity in world. In such as case, one should provide the
|
||||
* Elements are generally tied to a block or block entity in world. In such as case, one should provide the
|
||||
* {@link WiredElement} capability for the appropriate sides.
|
||||
*/
|
||||
public interface WiredElement extends WiredSender {
|
||||
|
@ -248,7 +248,7 @@ public class CommandAPI implements ILuaAPI {
|
||||
* Get some basic information about a block.
|
||||
* <p>
|
||||
* The returned table contains the current name, metadata and block state (as
|
||||
* with [`turtle.inspect`]). If there is a tile entity for that block, its NBT
|
||||
* with [`turtle.inspect`]). If there is a block entity for that block, its NBT
|
||||
* will also be returned.
|
||||
*
|
||||
* @param x The x position of the block to query.
|
||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A loot condition which checks if the tile entity has a non-0 ID.
|
||||
* A loot condition which checks if the block entity has a computer ID.
|
||||
*/
|
||||
public final class HasComputerIdLootCondition implements LootItemCondition {
|
||||
public static final HasComputerIdLootCondition INSTANCE = new HasComputerIdLootCondition();
|
||||
|
@ -23,7 +23,7 @@ import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
*
|
||||
* <pre>{@code
|
||||
* public class InventoryMethods implements GenericSource {
|
||||
* \@LuaFunction( mainThread = true )
|
||||
* \@LuaFunction(mainThread = true)
|
||||
* public int size(IItemHandler inventory) {
|
||||
* return inventory.getSlots();
|
||||
* }
|
||||
|
@ -7,11 +7,13 @@
|
||||
* <p>
|
||||
* You probably want to start in the following places:
|
||||
* <ul>
|
||||
* <li>{@link dan200.computercraft.api.peripheral.IPeripheral} for registering new peripherals.</li>
|
||||
* <li>{@link dan200.computercraft.api.peripheral} for registering new peripherals.</li>
|
||||
* <li>
|
||||
* {@link dan200.computercraft.api.lua.LuaFunction} and {@link dan200.computercraft.api.lua.IArguments} for
|
||||
* adding methods to your peripheral or Lua objects.
|
||||
* </li>
|
||||
* <li>{@link dan200.computercraft.api.turtle.ITurtleUpgrade} for turtle upgrades.</li>
|
||||
* <li>{@link dan200.computercraft.api.pocket.IPocketUpgrade} for pocket upgrades.</li>
|
||||
* </ul>
|
||||
*/
|
||||
@DefaultQualifier(value = NonNull.class, locations = {
|
||||
|
@ -19,17 +19,17 @@ public interface GenericPeripheral extends GenericSource {
|
||||
* Unlike normal {@link IPeripheral}s, {@link GenericPeripheral} do not have to have a type. By default, the
|
||||
* resulting peripheral uses the resource name of the wrapped block entity (for instance {@code minecraft:chest}).
|
||||
* <p>
|
||||
* However, in some cases it may be more appropriate to specify a more readable name. Overriding this method allows
|
||||
* you to do so.
|
||||
* However, in some cases it may be more appropriate to specify a more readable name, or provide
|
||||
* {@linkplain PeripheralType#getAdditionalTypes() additional types}. Overriding this method allows you to do so.
|
||||
* <p>
|
||||
* When multiple {@link GenericPeripheral}s return a non-empty peripheral type for a single tile entity, the
|
||||
* lexicographically smallest will be chosen. In order to avoid this conflict, this method should only be
|
||||
* implemented when your peripheral targets a single tile entity <strong>AND</strong> it's likely that you're the
|
||||
* only mod to do so. Similarly this should <strong>NOT</strong> be implemented when your methods target a
|
||||
* capability or other interface (such as Forge's {@code IItemHandler}).
|
||||
* When multiple {@link GenericPeripheral}s provide a {@linkplain PeripheralType#getPrimaryType() primary peripheral
|
||||
* type} for a single block entity, the lexicographically smallest will be chosen. In order to avoid this conflict,
|
||||
* primary types should only be used when your peripheral targets a single block entity <strong>AND</strong> it's
|
||||
* likely that you're the only mod to do so.
|
||||
*
|
||||
* @return The type of this peripheral or {@link PeripheralType#untyped()}.
|
||||
* @see IPeripheral#getType()
|
||||
* @see IPeripheral#getAdditionalTypes()
|
||||
*/
|
||||
default PeripheralType getType() {
|
||||
return PeripheralType.untyped();
|
||||
|
@ -10,7 +10,6 @@ import dan200.computercraft.api.lua.*;
|
||||
* A peripheral whose methods are not known at runtime.
|
||||
* <p>
|
||||
* This behaves similarly to {@link IDynamicLuaObject}, though also accepting the current {@link IComputerAccess}.
|
||||
* Generally one may use {@link LuaFunction} instead of implementing this interface.
|
||||
*/
|
||||
public interface IDynamicPeripheral extends IPeripheral {
|
||||
/**
|
||||
|
@ -4,19 +4,28 @@
|
||||
|
||||
package dan200.computercraft.api.peripheral;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.api.lua.LuaTask;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The interface that defines a peripheral.
|
||||
* A peripheral is an external device that a computer can interact with.
|
||||
* <p>
|
||||
* In order to expose a peripheral for your block or block entity, you should either attach a capability (Forge) or
|
||||
* use the block lookup API (Fabric). This interface <em>cannot</em> be implemented directly on the block entity.
|
||||
* Peripherals can be supplied by both a block (or block entity), or from
|
||||
* {@linkplain dan200.computercraft.api.turtle.ITurtleUpgrade#createPeripheral(dan200.computercraft.api.turtle.ITurtleAccess, dan200.computercraft.api.turtle.TurtleSide) turtle}
|
||||
* or {@linkplain dan200.computercraft.api.pocket.IPocketUpgrade#createPeripheral(dan200.computercraft.api.pocket.IPocketAccess) pocket}
|
||||
* upgrades.
|
||||
* <p>
|
||||
* Peripherals should provide a series of methods to the user, either using {@link LuaFunction} or by implementing
|
||||
* {@link IDynamicPeripheral}.
|
||||
* See the {@linkplain dan200.computercraft.api.peripheral package documentation} for more information on registering peripherals.
|
||||
* <p>
|
||||
* Peripherals should provide a series of methods to the user, typically by annotating Java methods with
|
||||
* {@link LuaFunction}. Alternatively, {@link IDynamicPeripheral} may be used to provide a dynamic set of methods.
|
||||
* Remember that peripheral methods are called on the <em>computer</em> thread, and so it is not safe to interact with
|
||||
* the Minecraft world by default. One should use {@link LuaFunction#mainThread()} or
|
||||
* {@link ILuaContext#executeMainThreadTask(LuaTask)} to run code on the main server thread.
|
||||
*/
|
||||
public interface IPeripheral {
|
||||
/**
|
||||
@ -24,6 +33,7 @@ public interface IPeripheral {
|
||||
* This can be queried from lua by calling {@code peripheral.getType()}
|
||||
*
|
||||
* @return A string identifying the type of peripheral.
|
||||
* @see PeripheralType#getPrimaryType()
|
||||
*/
|
||||
String getType();
|
||||
|
||||
@ -81,7 +91,7 @@ public interface IPeripheral {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object that this peripheral provides methods for. This will generally be the tile entity
|
||||
* Get the object that this peripheral provides methods for. This will generally be the block entity
|
||||
* or block, but may be an inventory, entity, etc...
|
||||
*
|
||||
* @return The object this peripheral targets
|
||||
@ -95,7 +105,7 @@ public interface IPeripheral {
|
||||
* Determine whether this peripheral is equivalent to another one.
|
||||
* <p>
|
||||
* The minimal example should at least check whether they are the same object. However, you may wish to check if
|
||||
* they point to the same block or tile entity.
|
||||
* they point to the same block or block entity.
|
||||
*
|
||||
* @param other The peripheral to compare against. This may be {@code null}.
|
||||
* @return Whether these peripherals are equivalent.
|
||||
|
@ -96,6 +96,7 @@ public final class PeripheralType {
|
||||
* Get the name of this peripheral type. This may be {@code null}.
|
||||
*
|
||||
* @return The type of this peripheral.
|
||||
* @see IPeripheral#getType()
|
||||
*/
|
||||
@Nullable
|
||||
public String getPrimaryType() {
|
||||
@ -107,6 +108,7 @@ public final class PeripheralType {
|
||||
* a peripheral might have.
|
||||
*
|
||||
* @return All additional types.
|
||||
* @see IPeripheral#getAdditionalTypes()
|
||||
*/
|
||||
public Set<String> getAdditionalTypes() {
|
||||
return additionalTypes;
|
||||
|
@ -11,7 +11,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* Monitors "work" associated with a computer, keeping track of how much a computer has done, and ensuring every
|
||||
* computer receives a fair share of any processing time.
|
||||
* <p>
|
||||
* This is primarily intended for work done by peripherals on the main thread (such as on a tile entity's tick), but
|
||||
* This is primarily intended for work done by peripherals on the main thread (such as on a block entity's tick), but
|
||||
* could be used for other purposes (such as complex computations done on another thread).
|
||||
* <p>
|
||||
* Before running a task, one should call {@link #canWork()} to determine if the computer is currently allowed to
|
||||
|
@ -0,0 +1,205 @@
|
||||
// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
/**
|
||||
* Peripherals for blocks and upgrades.
|
||||
* <p>
|
||||
* A peripheral is an external device that a computer can interact with. Peripherals can be supplied by both a block (or
|
||||
* block entity), or from {@linkplain dan200.computercraft.api.turtle.ITurtleUpgrade#createPeripheral(dan200.computercraft.api.turtle.ITurtleAccess, dan200.computercraft.api.turtle.TurtleSide) turtle}
|
||||
* or {@linkplain dan200.computercraft.api.pocket.IPocketUpgrade#createPeripheral(dan200.computercraft.api.pocket.IPocketAccess) pocket}
|
||||
* upgrades.
|
||||
*
|
||||
* <h2>Creating peripherals for blocks</h2>
|
||||
* One of the most common things you'll want to do with ComputerCraft's API is register new peripherals. This is
|
||||
* relatively simple once you know how to do it, but may be a bit confusing the first time round.
|
||||
* <p>
|
||||
* There are currently two possible ways to define a peripheral in ComputerCraft:
|
||||
* <ul>
|
||||
* <li>
|
||||
* <p>
|
||||
* <strong>With a {@linkplain dan200.computercraft.api.peripheral.GenericPeripheral generic peripheral}:</strong>
|
||||
* Generic peripherals are a way to add peripheral methods to any block entity, in a trait-based manner. This
|
||||
* allows multiple mods to add methods to the same block entity.
|
||||
* <p>
|
||||
* This is the recommended approach if you just want to add a couple of methods, and do not need any advanced
|
||||
* functionality.
|
||||
* </li>
|
||||
* <li>
|
||||
* <p>
|
||||
* <strong>With an {@link dan200.computercraft.api.peripheral.IPeripheral}:</strong> If your peripheral needs
|
||||
* more advanced behaviour, such as knowing which computers it is attached to, then you can use an
|
||||
* {@link dan200.computercraft.api.peripheral.IPeripheral}.
|
||||
* <p>
|
||||
* These peripherals are currently <strong>NOT</strong> compatible with the generic peripheral system, so
|
||||
* methods added by other mods (including CC's built-in inventory methods) will not be available.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* In the following examples, we'll write a peripheral method that returns the remaining burn time of a furnace, and
|
||||
* demonstrate how to register this peripheral.
|
||||
*
|
||||
* <h3>Creating a generic peripheral</h3>
|
||||
* First, we'll need to create a new {@code final} class, that implements {@link dan200.computercraft.api.peripheral.GenericPeripheral}.
|
||||
* You'll need to implement {@link dan200.computercraft.api.peripheral.GenericPeripheral#id()}, which should just return
|
||||
* some namespaced-string with your mod id.
|
||||
* <p>
|
||||
* Then, we can start adding methods to your block entity. Each method should take its target type as the first
|
||||
* argument, which in this case is a {@code AbstractFurnaceBlockEntity}. We then annotate this method with
|
||||
* {@link dan200.computercraft.api.lua.LuaFunction} to expose it to computers.
|
||||
*
|
||||
* <pre class="language language-java">{@code
|
||||
* import dan200.computercraft.api.lua.LuaFunction;
|
||||
* import dan200.computercraft.api.peripheral.GenericPeripheral;
|
||||
* import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||
*
|
||||
* public final class FurnacePeripheral implements GenericPeripheral {
|
||||
* @Override
|
||||
* public String id() {
|
||||
* return "mymod:furnace";
|
||||
* }
|
||||
*
|
||||
* @LuaFunction(mainThread = true)
|
||||
* public int getBurnTime(AbstractFurnaceBlockEntity furnace) {
|
||||
* return furnace.litTime;
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Finally, we need to register our peripheral, so that ComputerCraft is aware of it:
|
||||
*
|
||||
* <pre class="language language-java">{@code
|
||||
* import dan200.computercraft.api.ComputerCraftAPI;
|
||||
*
|
||||
* public class ComputerCraftCompat {
|
||||
* public static void register() {
|
||||
* ComputerCraftAPI.registerGenericSource(new FurnacePeripheral());
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Creating a {@code IPeripheral}</h3>
|
||||
* First, we'll need to create a new class that implements {@link dan200.computercraft.api.peripheral.IPeripheral}. This
|
||||
* requires a couple of boilerplate methods: one to get the type of the peripheral, and an equality function.
|
||||
* <p>
|
||||
* We can then start adding peripheral methods to our class. Each method should be {@code final}, and annotated with
|
||||
* {@link dan200.computercraft.api.lua.LuaFunction}.
|
||||
*
|
||||
* <pre class="language language-java">{@code
|
||||
* import dan200.computercraft.api.lua.LuaFunction;
|
||||
* import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
* import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||
* import org.jetbrains.annotations.Nullable;
|
||||
*
|
||||
* public class FurnacePeripheral implements IPeripheral {
|
||||
* private final AbstractFurnaceBlockEntity furnace;
|
||||
*
|
||||
* public FurnacePeripheral(AbstractFurnaceBlockEntity furnace) {
|
||||
* this.furnace = furnace;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public String getType() {
|
||||
* return "furnace";
|
||||
* }
|
||||
*
|
||||
* @LuaFunction(mainThread = true)
|
||||
* public final int getBurnTime() {
|
||||
* return furnace.litTime;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public boolean equals(@Nullable IPeripheral other) {
|
||||
* return this == other || other instanceof FurnacePeripheral p && furnace == p.furnace;
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Finally, we'll need to register our peripheral. This is done with capabilities on Forge, or the block lookup API on
|
||||
* Fabric.
|
||||
*
|
||||
* <h4>Registering {@code IPeripheral} on Forge</h4>
|
||||
* Registering a peripheral on Forge can be done by attaching the {@link dan200.computercraft.api.peripheral.IPeripheral}
|
||||
* to a block entity. Unfortunately, this requires quite a lot of boilerplate, due to the awkward nature of
|
||||
* {@code ICapabilityProvider}. If you've got an existing system for dealing with this, we recommend you use that,
|
||||
* otherwise you can use something similar to the code below:
|
||||
*
|
||||
* <pre class="language language-java">{@code
|
||||
* import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
* import net.minecraft.core.Direction;
|
||||
* import net.minecraft.resources.ResourceLocation;
|
||||
* import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||
* import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
* import net.minecraftforge.common.capabilities.Capability;
|
||||
* import net.minecraftforge.common.capabilities.CapabilityManager;
|
||||
* import net.minecraftforge.common.capabilities.CapabilityToken;
|
||||
* import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
* import net.minecraftforge.common.util.LazyOptional;
|
||||
* import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||
* import org.jetbrains.annotations.Nullable;
|
||||
*
|
||||
* import java.util.function.Function;
|
||||
*
|
||||
* public class ComputerCraftCompat {
|
||||
* public static final Capability<IPeripheral> CAPABILITY_PERIPHERAL = CapabilityManager.get(new CapabilityToken<>() {
|
||||
* });
|
||||
* private static final ResourceLocation PERIPHERAL = new ResourceLocation("mymod", "peripheral");
|
||||
*
|
||||
* public static void register(AttachCapabilitiesEvent<BlockEntity> event) {
|
||||
* if (event.getObject() instanceof AbstractFurnaceBlockEntity furnace) {
|
||||
* PeripheralProvider.attach(event, furnace, FurnacePeripheral::new);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // A {@link ICapabilityProvider} that lazily creates an {@link IPeripheral} when required.
|
||||
* private static class PeripheralProvider<O extends BlockEntity> implements ICapabilityProvider {
|
||||
* private final O blockEntity;
|
||||
* private final Function<O, IPeripheral> factory;
|
||||
* private @Nullable LazyOptional<IPeripheral> peripheral;
|
||||
*
|
||||
* private PeripheralProvider(O blockEntity, Function<O, IPeripheral> factory) {
|
||||
* this.blockEntity = blockEntity;
|
||||
* this.factory = factory;
|
||||
* }
|
||||
*
|
||||
* private static <O extends BlockEntity> void attach(AttachCapabilitiesEvent<BlockEntity> event, O blockEntity, Function<O, IPeripheral> factory) {
|
||||
* var provider = new PeripheralProvider<>(blockEntity, factory);
|
||||
* event.addCapability(PERIPHERAL, provider);
|
||||
* event.addListener(provider::invalidate);
|
||||
* }
|
||||
*
|
||||
* private void invalidate() {
|
||||
* if (peripheral != null) peripheral.invalidate();
|
||||
* peripheral = null;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public <T> LazyOptional<T> getCapability(Capability<T> capability, @Nullable Direction direction) {
|
||||
* if (capability != CAPABILITY_PERIPHERAL) return LazyOptional.empty();
|
||||
* if (blockEntity.isRemoved()) return LazyOptional.empty();
|
||||
*
|
||||
* var peripheral = this.peripheral;
|
||||
* return (peripheral == null ? (this.peripheral = LazyOptional.of(() -> factory.apply(blockEntity))) : peripheral).cast();
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <h4>Registering {@code IPeripheral} on Fabric</h4>
|
||||
* Registering a peripheral on Fabric can be done using the block lookup API, via {@code PeripheralLookup}.
|
||||
*
|
||||
* <pre class="language language-java">{@code
|
||||
* import dan200.computercraft.api.peripheral.PeripheralLookup;
|
||||
* import dan200.computercraft.example.FurnacePeripheral;
|
||||
* import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
*
|
||||
* public class ComputerCraftCompat {
|
||||
* public static void register() {
|
||||
* PeripheralLookup.get().registerForBlockEntity((f, s) -> new FurnacePeripheral(f), BlockEntityType.FURNACE);
|
||||
* PeripheralLookup.get().registerForBlockEntity((f, s) -> new FurnacePeripheral(f), BlockEntityType.BLAST_FURNACE);
|
||||
* PeripheralLookup.get().registerForBlockEntity((f, s) -> new FurnacePeripheral(f), BlockEntityType.SMOKER);
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
package dan200.computercraft.api.peripheral;
|
@ -30,7 +30,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* <p>
|
||||
* Now, if anywhere during this period, we use more than our allocated time slice, the executor is marked as
|
||||
* {@link State#HOT}. This means it will no longer be able to execute {@link MainThread} tasks (though will still
|
||||
* execute tile entity tasks, in order to prevent the main thread from exhausting work every tick).
|
||||
* execute block entity tasks, in order to prevent the main thread from exhausting work every tick).
|
||||
* <p>
|
||||
* At the beginning of the next tick, we increment the budget e by {@link MainThreadConfig#maxComputerTime()} and any
|
||||
* {@link State#HOT} executors are marked as {@link State#COOLING}. They will remain cooling until their budget is fully
|
||||
|
Loading…
Reference in New Issue
Block a user