Skip to content

Instantly share code, notes, and snippets.

@falseresync
Created February 3, 2023 20:23
Show Gist options
  • Save falseresync/f1bc75ca9a29f7b7f7dd590915e89497 to your computer and use it in GitHub Desktop.
Save falseresync/f1bc75ca9a29f7b7f7dd590915e89497 to your computer and use it in GitHub Desktop.
Dirty AutoRegistry
/**
* <h2>USAGE EXAMPLE</h2>
*
* <p>In your ModInitializer:
* <pre>{@code
* AutoRegistry.create(MODID)
* .run(Registries.BLOCK, MyBlocks.class)
* .run(Registries.ITEM, MyItems.class);
* }</pre>
*
* <p>In your MyBlocks/Items/etc classes:
* <pre>{@code
* public class MyBlocks {
* public static final @RegistryObject MagicCauldronBlock MAGIC_CAULDRON = new MagicCauldronBlock();
* }
* }</pre>
*/
public class AutoRegistry {
private final String modid;
private final Logger logger;
protected AutoRegistry(String modid, Logger logger) {
this.modid = modid;
this.logger = logger;
}
public static AutoRegistry create(String modid, Logger logger) {
return new AutoRegistry(modid, logger);
}
/**
* Registers all the objects in the provided class into the provided registry by the following rules:
* <ul>
* <li>Only the public static fields marked with @RegistryObject are scanned</li>
* <li>The ID is formed by lower-casing the field name</li>
* <li>Null fields are discarded with a warning message</li>
* </ul>
* @param <T> type parameter must match the type of the fields
* @implNote help
*/
public <T> AutoRegistry run(Registry<T> registry, Class<?> holderClass) {
for (var field : holderClass.getDeclaredFields()) {
var modifiers = field.getModifiers();
var annotations = field.getAnnotationsByType(RegistryObject.class);
if (!Modifier.isStatic(modifiers)
|| !Modifier.isPublic(modifiers)
|| annotations.length == 0) {
continue;
}
try {
var registryObject = field.get(holderClass);
if (registryObject == null) {
logger.warn("Found a null @RegistryObject field, discarding: %s at %s".formatted(field.getName(), holderClass.getCanonicalName()));
continue;
}
Registry.register(registry, new Identifier(modid, field.getName().toLowerCase()), (T) registryObject);
} catch (IllegalAccessException e) {
throw new InaccessibleObjectException("Couldn't read a @RegistryObject field: %s at %s".formatted(field.getName(), holderClass.getCanonicalName()));
} catch (ClassCastException e) {
throw new IllegalArgumentException("A @RegistryObject field's type doesn't match the provided registry: %s at %s".formatted(field.getName(), holderClass.getCanonicalName()));
}
}
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment