Skip to content

Commit 89f9401

Browse files
authored
Add more javadoc for machine classes (#4783)
1 parent 04c218c commit 89f9401

66 files changed

Lines changed: 758 additions & 457 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/content/Development/External-Resources.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@ as other resources you might find helpful.
2121
- [MCJty's Modding Wiki](https://www.mcjty.eu/docs/intro)
2222

2323

24-
## LDLib
25-
26-
LDLib is the main library we're using for GTCEu-Modern.
27-
28-
!!! link "LDLib Docs"
29-
[:material-github: LDLib-Architectury :material-arrow-right: Wiki](https://github.com/Low-Drag-MC/LDLib-Architectury/wiki)
30-
31-
3224
## Mixins
3325

3426
!!! link "Overview on using Mixins"

docs/content/Development/General-Topics/Energy-Fluid-Item-Storage.md

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ title: Item/Fluid/Energy Storage
77

88
!!! note
99

10-
In general, these containers should be created as `final` fields (that's what we need for the
11-
[SyncData](../SyncData/index.md) system).
10+
In general, these containers should be created as `final` fields.
1211
Set their base arguments in the constructor (you can pass args for subclasses to modify).
1312

1413

@@ -47,7 +46,6 @@ To do so, use either of the following interfaces:
4746
- `IFluidTransfer`
4847
- `IEnergyContainer`
4948

50-
5149
## Specialized proxy implementations
5250

5351
In case you have special requirements to your containers, you may be able to use one of these implementations in
@@ -61,67 +59,9 @@ They generally act as a proxy to the underlying container(s), while also handlin
6159
- `FluidTransferList`
6260
- `EnergyContainerList`
6361

64-
6562
### IO-specific container proxies
6663

6764
For proxying multiple containers, limited to a specific IO direction.
6865

6966
- `IOItemTransferList`
7067
- `IOFluidTransferList`
71-
72-
73-
### Rate-Limited proxies
74-
75-
!!! warning inline end "Not merged yet<br>_Branch: `mi-ender-link`_"
76-
77-
If you need to proxy any item or fluid container that needs to be rate limited for insertion and extraction, you can
78-
use either of the following classes:
79-
80-
- `LimitingItemTransferProxy`
81-
- `LimitingFluidTransferProxy`
82-
83-
The transfer limit passed as a constructor parameter will not renew automatically. Your container will therefore stop
84-
transferring anything once this limit is reached.
85-
86-
If you want to make this a rate limit instead, you will have to schedule a task that regularly resets the transfer
87-
limit to the maximum value for your task's interval:
88-
89-
??? example "Example Usage"
90-
91-
```java
92-
public class MyCover extends CoverBehavior {
93-
private LimitingFluidTransferProxy transferProxy;
94-
private ConditionalSubscriptionHandler rateLimitSubscription;
95-
96-
public MyCover(IFluidTransfer myFluidTransfer) {
97-
super(/* ... */);
98-
99-
transferProxy = new LimitingFluidTransferProxy(
100-
myFluidTransfer,
101-
0L // Initial limit of 0, will be updated regularly in isRateLimitRefreshActive()
102-
);
103-
rateLimitSubscription = new ConditionalSubscriptionHandler(
104-
this,
105-
this::resetTransferRateLimit,
106-
this::isRateLimitRefreshActive
107-
);
108-
}
109-
110-
@Override
111-
public void onLoad() {
112-
super.onLoad();
113-
rateLimitSubscription.initialize(coverHolder.getLevel());
114-
}
115-
116-
private void resetTransferRateLimit() {
117-
if (transferProxy == null)
118-
return;
119-
120-
transferProxy.setRemainingTransfer(transferRate.getMilliBuckets() * 20);
121-
}
122-
123-
private boolean isRateLimitRefreshActive() {
124-
// ...
125-
}
126-
}
127-
```

docs/content/Development/General-Topics/Global-Data.md

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,3 @@ In certain cases (e.g. in a cache that holds all currently loaded instances of a
99
in a global (static and mutable) variable.
1010

1111
When doing so, you need to ensure that remote and serverside instances don't get mixed up.
12-
13-
14-
## Using `SideLocal<T>`
15-
16-
!!! warning inline end "Not yet merged<br>_Branch: `mi-ender-link`_"
17-
18-
To make working with this requirement easier, You can use `SideLocal<T>` to store your global data.
19-
It is similar to Java's `ThreadLocal`, but operates on the game's sides instead.
20-
21-
If you are currently on the remote side (`GTCEuAPI.isClientThread()` / on the client's `main` thread), it will return the
22-
remote side's instance of your data. Otherwise, you will get the server side's instance.
23-
24-
??? example "Example Usage"
25-
26-
```java
27-
public class MyCache {
28-
private static SideLocal<Map<UUID, MyData>> cache = new SideLocal<>(HashMap::new);
29-
30-
public static void cacheData(UUID id, MyData data) {
31-
cache.get().put(id, data);
32-
}
33-
34-
public static MyData getData(UUID id) {
35-
return cache.get().get(id);
36-
}
37-
}
38-
```
39-
40-
Alternatively to passing an initializer for both instances to `SideLocal`'s constructor, you can also supply
41-
separate instances for the remote and server side.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
title: Machine Trait System
3+
---
4+
5+
# Machine Trait System
6+
7+
The machine trait system allows for attaching extra capabilities and behaviours to a machine by attaching traits to machine instances. Traits can listen for specific machine events, interactions, and provide capabilities, allowing for machine functionality to be implemented via a composition-based design.
8+
9+
## Attaching and using machine traits
10+
11+
Attaching traits must be done before machine instances are fully initialised, and are typically attached in the constructor.
12+
13+
### Attaching and using traits:
14+
15+
Attaching a machine trait to a machine is done with the `MetaMachine::attachTrait` and `MetaMachine::attachPersistentTrait` methods.
16+
17+
When attaching traits, a `callbackPriority` value can be given. Traits with a higher priority will have their events and interactions called
18+
first, which may prevent traits with a lower priority from handling some events.
19+
20+
!!! warning
21+
Traits must be attached to a machine instance via either `attachTrait` or `attachPersistentTrait`.
22+
If a trait is created without either of these methods being called, the trait will not be valid.
23+
24+
```java
25+
public class CustomMachine extends MetaMachine {
26+
27+
@SaveField
28+
protected final NotifiableFluidTank tank;
29+
30+
public CustomMachine(BlockEntityCreationInfo info, int capacity) {
31+
super(info);
32+
33+
// Because the tank field is annotated with `@SaveField`, the fluid tank will be saved into the machines data.
34+
this.tank = attachTrait(new NotifiableFluidTank(1, capacity, IO.BOTH));
35+
36+
// Registers an auto output trait that provides fluid output behaviour for the given fluid tank.
37+
// Instead of using an annotated field to save traits, they can also be registered to be saved.
38+
// The trait save name should remain the same, otherwise the trait save data won't be loaded.
39+
AutoOutputTrait autoOutput = attachPersistentTrait("autoOutput", AutoOutputTrait.ofFluids(tank));
40+
41+
autoOutput.setFluidOutputDirection(Direction.DOWN);
42+
autoOutput.setFluidOutputDirectionValidator(d -> d == Direction.DOWN);
43+
}
44+
45+
public void usingTraits() {
46+
MetaMachine machine = getMachine();
47+
48+
// Most trait objects have a `TYPE` static field, it can be used to get traits with a specific type.
49+
AutoOutputTrait autoOutputTrait = machine.getTrait(AutoOutputTrait.TYPE);
50+
Optional<RecipeLogic> recipeLogicOptional = machine.getTrait(RecipeLogic.TYPE);
51+
52+
// Gets all traits with the specified type.
53+
List<NotifiableItemStackHandler> allItemStackHandlers = machine.getTraits(NotifiableItemStackHandler.TYPE);
54+
55+
List<MachineTrait> allTraits = machine.getAllTraits();
56+
}
57+
}
58+
```
59+
60+
### Creating custom traits
61+
62+
Custom machine traits are created by extending `MachineTrait` or `MultiblockMachineTrait`
63+
64+
Machine traits have access to a number of machine events and callbacks, but some extra behaviours can be added by having a trait implement a trait feature interface. For example, `IInteractionTrait` to add custom interaction behaviour. The full list of trait features is in `api/machine/trait/feature`.
65+
66+
```java
67+
public class CustomMachineTrait extends MachineTrait implements IInteractionTrait {
68+
69+
// Machine traits should have a type object defined, unless a parent class of this machine trait already defines a type
70+
public static final MachineTraitType<CustomMachineTrait> TYPE = new MachineTraitType<>(CustomMachineTrait.class);
71+
72+
public CustomMachineTrait() {
73+
74+
}
75+
76+
// Machine traits must also define a getter for the trait type
77+
@Override
78+
public MachineTraitType<CustomMachineTrait> getType() {
79+
return TYPE;
80+
}
81+
82+
// A list of classes or interfaces which a machine must be in order for this trait to be attached.
83+
// A machine trait must be at least one of these interfaces/classes.
84+
// By default, traits can be attached to any machine.
85+
@Override
86+
protected List<Class<?>> validMachineClasses() {
87+
return List.of(CustomMachine.class);
88+
}
89+
90+
// An example of a machine trait event callback.
91+
// Traits with a higher trait priority will have their events called first,
92+
// which may block lower priority traits from receiving events.
93+
// All traits default to a priority of 1.
94+
@Override
95+
public Pair<@Nullable GTToolType, InteractionResult> onToolClick(ExtendedUseOnContext context) {
96+
var toolType = context.getToolType();
97+
if (toolType.contains(GTToolType.WRENCH)) {
98+
return Pair.of(GTToolType.WRENCH, onWrenchClick(context));
99+
}
100+
return IInteractionTrait.super.onToolClick(context);
101+
}
102+
103+
private InteractionResult onWrenchClick(ExtendedUseOnContext context) {
104+
return InteractionResult.PASS;
105+
}
106+
}
107+
```

docs/content/Development/index.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ pull request with your changes.
1010

1111
The following pages describe a few important concepts that you will likely run into when working with our codebase.
1212

13-
!!! link "LDLib Docs"
14-
[:material-github: LDLib-Architectury :material-arrow-right: Wiki](https://github.com/Low-Drag-MC/LDLib-Architectury/wiki)
15-
16-
This mod is based on the LDLib library for a lot of comminly used functionalities.
17-
Please refer to its documentation as well.
18-
1913
!!! link "Architectury Gradle Plugin"
2014
[Architectury-Wiki :material-arrow-right: Gradle Plugin](https://docs.architectury.dev/plugin/introduction)
2115

docs/content/Modpacks/Changes/v8.0.0.md

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ Machine interactions have been split into two methods: `MetaMachine::onUse` and
6666

6767
A new system for attaching traits and custom behaviour to machines has been added, and many machine interfaces and traits now use this new system.
6868

69+
See [this page](../../Development/General-Topics/Machine-Trait-System.md) for an overview of the new system.
70+
6971
### Machine constructor and trait initialisation changes
7072

7173
The constructors for a large number of machines have changed in order to simply machine instance creation. Additionally, methods for trait creation have also been removed and now form part of the machine constructor.
@@ -90,8 +92,6 @@ The constructors for a large number of machines have changed in order to simply
9092
- Removed `createRecipeLogic` method
9193
- Constructor now has an optional `Supplier<RecipeLogic>` argument, defaults to the standard `RecipeLogic` class
9294

93-
### New System Example
94-
9595
#### IMPORTANT MIGRATION NOTE:
9696

9797
Traits must be attached to a machine directly by calling `attachTrait(MachineTrait trait)` on the trait being attached.
@@ -105,44 +105,6 @@ this.itemHandler = attachTrait(new NotifiableItemStackHandler(0, IO.BOTH))
105105
```
106106
When migrating, remove the `this` argument from the machine trait constructor and instead attach the trait.
107107

108-
Example of the new `AutoOutputTrait`
109-
110-
```java
111-
public class CustomDrumMachine extends MetaMachine {
112-
113-
protected final NotifiableFluidTank tank;
114-
public final AutoOutputTrait autoOutput;
115-
116-
public DrumMachine(BlockEntityCreationInfo info, int capacity) {
117-
super(info);
118-
119-
// Traits must be attached in the constructor.
120-
121-
this.tank = attachTrait(new NotifiableFluidTank(1, capacity, IO.BOTH));
122-
123-
// Registers an auto output trait that provides fluid output behaviour for the given fluid tank.
124-
this.autoOutput = attachTrait(AutoOutputTrait.ofFluids(tank));
125-
126-
autoOutput.setFluidOutputDirection(Direction.DOWN);
127-
autoOutput.setFluidOutputDirectionValidator(d -> d == Direction.DOWN);
128-
}
129-
130-
// Any code can query traits from a machine
131-
public static void queryTraits(MetaMachine machine) {
132-
133-
// Returns a trait with the given type, or null.
134-
AutoOutputTrait autoOutputTrait = machine.getTraitHolder().getTrait(AutoOutputTrait.TYPE);
135-
136-
Optional<RecipeLogic> recipeLogicOptional = machine.getTraitHolder().getTrait(RecipeLogic.TYPE);
137-
138-
// Gets all traits with the specified type.
139-
List<NotifiableItemStackHandler> allItemStackHandlers = machine.getTraitHolder().getTraits(NotifiableItemStackHandler.TYPE);
140-
141-
}
142-
}
143-
```
144-
145-
146108
### Removed interfaces
147109

148110
A large number of machine feature interfaces have been removed, and have had their functionality merged into the standard MetaMachine class, or now use the new machine trait system:

src/generated/resources/assets/gtceu/lang/en_ud.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
"behavior.portable_scanner.debug_lag_count": "˙ɹǝʌɹǝS ǝɥʇ uo )sɯ%s uɐɥʇ ɹǝbuoן buıʞɐʇ buıɥʇʎuɐ( sbuıuɹɐM ǝʞıdS bɐꞀ %s pǝsnɐƆ",
1515
"behavior.portable_scanner.debug_machine": "%s :ᗡI-ɐʇǝW",
1616
"behavior.portable_scanner.debug_machine_invalid": "¡pıןɐʌuı ",
17-
"behavior.portable_scanner.debug_machine_invalid_null=invalid! MetaTileEntity =": "¡ןןnu ",
1817
"behavior.portable_scanner.debug_machine_valid": "pıןɐʌ ",
1918
"behavior.portable_scanner.divider": "=========================",
2019
"behavior.portable_scanner.energy_container_in": "Ɐ %s ʇɐ ∩Ǝ )%s( %s :NI xɐW",

src/generated/resources/assets/gtceu/lang/en_us.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
"behavior.portable_scanner.debug_lag_count": "Caused %s Lag Spike Warnings (anything taking longer than %sms) on the Server.",
1515
"behavior.portable_scanner.debug_machine": "Meta-ID: %s",
1616
"behavior.portable_scanner.debug_machine_invalid": " invalid!",
17-
"behavior.portable_scanner.debug_machine_invalid_null=invalid! MetaTileEntity =": " null!",
1817
"behavior.portable_scanner.debug_machine_valid": " valid",
1918
"behavior.portable_scanner.divider": "=========================",
2019
"behavior.portable_scanner.energy_container_in": "Max IN: %s (%s) EU at %s A",

src/main/java/com/gregtechceu/gtceu/api/block/MaterialBlock.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player
187187
blockPos.move(Direction.UP);
188188
continue;
189189
}
190-
BlockEntity te = level.getBlockEntity(blockPos);
191-
if (te instanceof PipeBlockEntity<?, ?> pbe && !pbe.getFrameMaterial().isNull()) {
190+
BlockEntity be = level.getBlockEntity(blockPos);
191+
if (be instanceof PipeBlockEntity<?, ?> pbe && !pbe.getFrameMaterial().isNull()) {
192192
blockPos.move(Direction.UP);
193193
continue;
194194
}
@@ -197,7 +197,7 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player
197197
if (!player.isCreative())
198198
stack.shrink(1);
199199
return InteractionResult.SUCCESS;
200-
} else if (te instanceof PipeBlockEntity<?, ?> pbe && pbe.getFrameMaterial().isNull()) {
200+
} else if (be instanceof PipeBlockEntity<?, ?> pbe && pbe.getFrameMaterial().isNull()) {
201201
pbe.setFrameMaterial(frameBlock.material);
202202

203203
if (!player.isCreative())
@@ -223,8 +223,8 @@ public static MaterialBlock getFrameboxFromItem(ItemStack stack) {
223223
}
224224

225225
public boolean removeFrame(Level level, BlockPos pos, Player player, ItemStack stack) {
226-
BlockEntity te = level.getBlockEntity(pos);
227-
if (te instanceof PipeBlockEntity<?, ?> pipeTile) {
226+
BlockEntity be = level.getBlockEntity(pos);
227+
if (be instanceof PipeBlockEntity<?, ?> pipeTile) {
228228
Material mat = pipeTile.getFrameMaterial();
229229
if (!mat.isNull()) {
230230
pipeTile.setFrameMaterial(GTMaterials.NULL);

0 commit comments

Comments
 (0)