From 0e5fe583920ce129639cdd58b580fd16d556a788 Mon Sep 17 00:00:00 2001 From: diacritics-owo <176600453+diacritics-owo@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:05:01 +0530 Subject: [PATCH] static registration --- docs/docs/registry-initializer.md | 22 ++++++++++--------- .../initalizer/RegistryInitializer.java | 16 ++++++++++++-- src/testmod/java/diacritics/owo/TestMod.java | 7 +++--- .../java/diacritics/owo/TestModBlocks.java | 6 ++--- .../diacritics/owo/TestModItemGroups.java | 2 +- .../java/diacritics/owo/TestModItems.java | 8 +++---- 6 files changed, 38 insertions(+), 23 deletions(-) diff --git a/docs/docs/registry-initializer.md b/docs/docs/registry-initializer.md index 39e88f4..b87d523 100644 --- a/docs/docs/registry-initializer.md +++ b/docs/docs/registry-initializer.md @@ -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); @@ -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` will be ignored. @@ -73,7 +73,7 @@ Creating a registry initializer for a registry that Circumflex doesn't provide o public class ParticleTypeRegistryInitializer extends RegistryInitializer { @Override public Class entryClass() { - return ParticleType.class; // if it has a generic, e.g. BlockEntityType, use Helpers.conform + return ParticleType.class; // if it's generic, e.g. BlockEntityType, use Helpers.conform } @Override @@ -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 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 fieldData)`. ```java public class ... { @@ -98,7 +98,11 @@ public class ... { // do things here } - protected void afterRegistration(Identifier identifier, Pair fieldData) { + // only override this if you need to use custom annotations + protected void afterRegistration( + Identifier identifier, + Pair 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)) } @@ -106,8 +110,6 @@ public class ... { } ``` -It is not recommended to do this, but if you need to use custom annotations, override `void afterRegistration(Identifier identifier, Pair 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 diff --git a/src/main/java/diacritics/owo/registry/initalizer/RegistryInitializer.java b/src/main/java/diacritics/owo/registry/initalizer/RegistryInitializer.java index 30e1f9b..357de1e 100644 --- a/src/main/java/diacritics/owo/registry/initalizer/RegistryInitializer.java +++ b/src/main/java/diacritics/owo/registry/initalizer/RegistryInitializer.java @@ -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; @@ -17,7 +18,19 @@ public abstract class RegistryInitializer { abstract public Registry registry(); - public final void register(String namespace) { + public RegistryInitializer() {} + + public static final void register(Class> 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> fields = Arrays.stream(this.getClass().getFields()).map(field -> { // registryentry if ((field.getType().equals(RegistryEntry.class) @@ -50,7 +63,6 @@ protected final T getFieldValue(Pair fieldData) { try { return registryEntry ? ((RegistryEntry) field.get(this)).value() : (T) field.get(this); } catch (IllegalArgumentException | IllegalAccessException e) { - // TODO: handle this...? throw new RuntimeException(e); } } diff --git a/src/testmod/java/diacritics/owo/TestMod.java b/src/testmod/java/diacritics/owo/TestMod.java index 8cca3aa..7a2a293 100644 --- a/src/testmod/java/diacritics/owo/TestMod.java +++ b/src/testmod/java/diacritics/owo/TestMod.java @@ -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"; @@ -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); } } diff --git a/src/testmod/java/diacritics/owo/TestModBlocks.java b/src/testmod/java/diacritics/owo/TestModBlocks.java index bdbf5c5..1a7c6c4 100644 --- a/src/testmod/java/diacritics/owo/TestModBlocks.java +++ b/src/testmod/java/diacritics/owo/TestModBlocks.java @@ -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()); } diff --git a/src/testmod/java/diacritics/owo/TestModItemGroups.java b/src/testmod/java/diacritics/owo/TestModItemGroups.java index 0e0a70b..99937a8 100644 --- a/src/testmod/java/diacritics/owo/TestModItemGroups.java +++ b/src/testmod/java/diacritics/owo/TestModItemGroups.java @@ -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(); diff --git a/src/testmod/java/diacritics/owo/TestModItems.java b/src/testmod/java/diacritics/owo/TestModItems.java index 6e3ba8d..deb77e4 100644 --- a/src/testmod/java/diacritics/owo/TestModItems.java +++ b/src/testmod/java/diacritics/owo/TestModItems.java @@ -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 ANOTHER = RegistryEntry.of(new Item((new Item.Settings()))); + public static final RegistryEntry 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"; }