Skip to content

Commit

Permalink
static registration
Browse files Browse the repository at this point in the history
  • Loading branch information
diacritics-owo committed Sep 3, 2024
1 parent ec53428 commit 0e5fe58
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 23 deletions.
22 changes: 12 additions & 10 deletions docs/docs/registry-initializer.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ The following is how one would generally register things into a registry:

```java title="src/main/java/com/example/item/MyModItems.java"
public class MyModItems {
public static Item ITEM = register("item", new Item(...));
public static Item ANOTHER_ITEM = register("second_item", new Item(...)); // notice that the id doesn't match the field name
public static final Item ITEM = register("item", new Item(...));
public static final Item ANOTHER_ITEM = register("second_item", new Item(...)); // notice that the id doesn't match the field name

public static Item register(String id, Item item) {
return Registry.register(Registries.ITEM, Identifier.of(MyMod.MOD_ID, id), item);
Expand All @@ -41,15 +41,15 @@ With the registry initializer API, this can be simplified to:
public class MyModItems extends ItemRegistryInitializer {
@Group("tools_and_utilities")
@Group(namespace = MyMod.MOD_ID, value = "custom_group")
public Item ITEM = new Item(...);
public static final Item ITEM = new Item(...);

@Id("second_item")
@Group("tools_and_utilities")
public Item ANOTHER_ITEM = new Item(...);
public static final Item ANOTHER_ITEM = new Item(...);
}
```

In the mod initializer, you would then call `new MyModItems().register(MOD_ID)`.
In the mod initializer, you would then call `RegistryInitializer.register(MyModItems.class, MOD_ID)`.

Note that registry initializers also support fields of type `RegistryEntry`, and that fields not of type `T` or `RegistryEntry<T>` will be ignored.

Expand All @@ -73,7 +73,7 @@ Creating a registry initializer for a registry that Circumflex doesn't provide o
public class ParticleTypeRegistryInitializer extends RegistryInitializer<ParticleType> {
@Override
public Class<ParticleType> entryClass() {
return ParticleType.class; // if it has a generic, e.g. BlockEntityType<T>, use Helpers.conform
return ParticleType.class; // if it's generic, e.g. BlockEntityType<T>, use Helpers.conform
}

@Override
Expand All @@ -87,7 +87,7 @@ And you're done! You can now create a class extending `ParticleTypeRegistryIniti

### Advanced Usage

Using custom registry initializers as above will be enough for most use cases, but you cannot, for example, do things like dynamically registering `BlockItem`s or using custom annotations. For this, you must override either `void afterRegistration(Identifier identifier, T value)` or (not recommended) `void afterRegistration(Identifier identifier, Pair<Boolean, Field> fieldData)`.
Using custom registry initializers as above will be enough for most use cases, but you cannot, for example, do things like dynamically register `BlockItem`s or use custom annotations. To do so, you must override either `void afterRegistration(Identifier identifier, T value)` or (not recommended) `void afterRegistration(Identifier identifier, Pair<Boolean, Field> fieldData)`.

```java
public class ... {
Expand All @@ -98,16 +98,18 @@ public class ... {
// do things here
}

protected void afterRegistration(Identifier identifier, Pair<Boolean, Field> fieldData) {
// only override this if you need to use custom annotations
protected void afterRegistration(
Identifier identifier,
Pair<Boolean, Field> fieldData /// the first item is a boolean indicating whether the field is a registryentry, and the second is a java.lang.reflect.Field
) {
// the default implementation is just: this.afterRegistration(identifier, this.getFieldValue(fieldData))
}

...
}
```

It is not recommended to do this, but if you need to use custom annotations, override `void afterRegistration(Identifier identifier, Pair<Boolean, Field> fieldData)` (the first item of the pair `fieldData` is a boolean indicating whether it is a `RegistryEntry` and the second is a `java.lang.reflect.Field`).

It is **strongly** recommended that you look at [`BlockRegistryInitializer`](https://github.com/diacritics-owo/circumflex/blob/main/src/main/java/diacritics/owo/registry/initalizer/BlockRegistryInitializer.java) and [`ItemRegistryInitializer`](https://github.com/diacritics-owo/circumflex/blob/main/src/main/java/diacritics/owo/registry/initalizer/ItemRegistryInitializer.java) for examples of dynamic registration and custom annotations.

## Annotations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import java.util.List;
Expand All @@ -17,7 +18,19 @@ public abstract class RegistryInitializer<T> {

abstract public Registry<T> registry();

public final void register(String namespace) {
public RegistryInitializer() {}

public static final void register(Class<? extends RegistryInitializer<?>> class_,
String namespace) {
try {
class_.getDeclaredConstructor().newInstance().register(namespace);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
throw new RuntimeException(e);
}
}

protected final void register(String namespace) {
List<Pair<Boolean, Field>> fields = Arrays.stream(this.getClass().getFields()).map(field -> {
// registryentry
if ((field.getType().equals(RegistryEntry.class)
Expand Down Expand Up @@ -50,7 +63,6 @@ protected final T getFieldValue(Pair<Boolean, Field> fieldData) {
try {
return registryEntry ? ((RegistryEntry<T>) field.get(this)).value() : (T) field.get(this);
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO: handle this...?
throw new RuntimeException(e);
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/testmod/java/diacritics/owo/TestMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import net.fabricmc.api.ModInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import diacritics.owo.registry.initalizer.RegistryInitializer;

public class TestMod implements ModInitializer {
public static final String MOD_ID = "testmod";
Expand All @@ -14,8 +15,8 @@ public void onInitialize() {

Commands.initialize();

new TestModItemGroups().register(MOD_ID);
new TestModItems().register(MOD_ID);
new TestModBlocks().register(MOD_ID);
RegistryInitializer.register(TestModItemGroups.class, MOD_ID);
RegistryInitializer.register(TestModItems.class, MOD_ID);
RegistryInitializer.register(TestModBlocks.class, MOD_ID);
}
}
6 changes: 3 additions & 3 deletions src/testmod/java/diacritics/owo/TestModBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
import net.minecraft.block.Block;

public class TestModBlocks extends BlockRegistryInitializer {
public Block BLOCK = new Block(AbstractBlock.Settings.create());
public static final Block BLOCK = new Block(AbstractBlock.Settings.create());

@Id("hewwo")
@Group(namespace = TestMod.MOD_ID, value = "group")
public Block HI = new Block(AbstractBlock.Settings.create());
public static final Block HI = new Block(AbstractBlock.Settings.create());

@NoItem
public Block UNOBTAINABLE = new Block(AbstractBlock.Settings.create());
public static final Block UNOBTAINABLE = new Block(AbstractBlock.Settings.create());
}
2 changes: 1 addition & 1 deletion src/testmod/java/diacritics/owo/TestModItemGroups.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public class TestModItemGroups extends ItemGroupRegistryInitializer {
// we won't add the items here in order to demo the group annotation in the item and block
// initializers
public ItemGroup GROUP =
public static final ItemGroup GROUP =
// best vanilla flower, fight me
FabricItemGroup.builder().icon(() -> new ItemStack(Items.LILY_OF_THE_VALLEY))
.displayName(Text.translatable("itemGroup.testmod.group")).build();
Expand Down
8 changes: 4 additions & 4 deletions src/testmod/java/diacritics/owo/TestModItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
import net.minecraft.registry.entry.RegistryEntry;

public class TestModItems extends ItemRegistryInitializer {
public Item ITEM = new Item((new Item.Settings()));
public static final Item ITEM = new Item((new Item.Settings()));

@Id(namespace = "owo", value = "uwu")
@Group(namespace = TestMod.MOD_ID, value = "group")
@Group("tools_and_utilities")
public Item OWO = new Item((new Item.Settings()));
public static final Item OWO = new Item((new Item.Settings()));

@Id(namespace = "owo")
public RegistryEntry<Item> ANOTHER = RegistryEntry.of(new Item((new Item.Settings())));
public static final RegistryEntry<Item> ANOTHER = RegistryEntry.of(new Item((new Item.Settings())));

public String ignored = "this string field will be ignored";
public static final String ignored = "this string field will be ignored";
}

0 comments on commit 0e5fe58

Please sign in to comment.