diff options
Diffstat (limited to 'src/main/kotlin/thedarkcolour')
-rw-r--r-- | src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt | 27 | ||||
-rw-r--r-- | src/main/kotlin/thedarkcolour/kotlinforforge/forge/KDeferredRegister.kt | 84 |
2 files changed, 105 insertions, 6 deletions
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt index 37cc207..01f9e90 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt @@ -18,6 +18,7 @@ import thedarkcolour.kotlinforforge.eventbus.KotlinEventBusWrapper import java.util.* import java.util.function.Consumer import java.util.function.Predicate +import java.util.function.Supplier import kotlin.collections.HashMap import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty @@ -49,7 +50,7 @@ public val FORGE_BUS: KotlinEventBusWrapper = KotlinEventBusWrapper(MinecraftFor * * Examples: * @see net.minecraftforge.fml.event.lifecycle.InterModProcessEvent - * @see net.minecraftforge.event.AttachCapabilitiesEvent + * @see net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent * @see net.minecraftforge.event.RegistryEvent */ public val MOD_BUS: KotlinEventBus @@ -158,19 +159,26 @@ public fun <T> sidedDelegate(clientValue: () -> T, serverValue: () -> T): ReadOn /** @since 1.2.2 * Creates a new [ObjectHolderDelegate] with the specified [registryName]. * - * This delegate serves as an alternative to using the - * `@ObjectHolder` annotation, making it easier to use in Kotlin. + * Provides ObjectHolders as property delegates instead of magic annotations. */ public inline fun <reified T : IForgeRegistryEntry<in T>> objectHolder(registryName: ResourceLocation): ReadOnlyProperty<Any?, T> { return ObjectHolderDelegate(registryName, ObjectHolderDelegate.getRegistry(T::class.java)) } /** @since 1.2.2 + * Creates a new with the specified [namespace] and [registryName]. + * + * Provides ObjectHolders as property delegates instead of magic annotations. + */ +public inline fun <reified T : IForgeRegistryEntry<in T>> objectHolder(namespace: String, registryName: String): ReadOnlyProperty<Any?, T> { + return ObjectHolderDelegate(ResourceLocation(namespace, registryName), ObjectHolderDelegate.getRegistry(T::class.java)) +} + +/** @since 1.2.2 * Creates a new [ObjectHolderDelegate]. * This overload uses a string instead of a ResourceLocation. * - * This delegate serves as an alternative to using the - * `@ObjectHolder` annotation, making it easier to use in Kotlin. + * Provides ObjectHolders as property delegates instead of magic annotations. */ public inline fun <reified T : IForgeRegistryEntry<in T>> objectHolder(registryName: String): ReadOnlyProperty<Any?, T> { return ObjectHolderDelegate( @@ -222,6 +230,9 @@ private class SidedDelegate<T>(private val clientValue: () -> T, private val ser * This class has proper implementations of * [copy], [hashCode], [equals], and [toString]. * + * @since 1.4.0 + * [ObjectHolderDelegate] can now be used with the [KDeferredRegister]. + * * @param T the type of object this delegates to * @property registryName the registry name of the object this delegate references * @property registry the registry the object of this delegate is in @@ -230,7 +241,7 @@ private class SidedDelegate<T>(private val clientValue: () -> T, private val ser public data class ObjectHolderDelegate<T : IForgeRegistryEntry<in T>>( private val registryName: ResourceLocation, private val registry: IForgeRegistry<*>, -) : ReadOnlyProperty<Any?, T>, Consumer<Predicate<ResourceLocation>> { +) : ReadOnlyProperty<Any?, T>, Consumer<Predicate<ResourceLocation>>, Supplier<T> { /** * Should be initialized by [accept]. If you don't register * a value for [registryName] during the appropriate registry event @@ -242,6 +253,10 @@ public data class ObjectHolderDelegate<T : IForgeRegistryEntry<in T>>( ObjectHolderRegistry.addHandler(this) } + override fun get(): T { + return value + } + override fun getValue(thisRef: Any?, property: KProperty<*>): T { return value } diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/KDeferredRegister.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/KDeferredRegister.kt new file mode 100644 index 0000000..f556d0f --- /dev/null +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/KDeferredRegister.kt @@ -0,0 +1,84 @@ +package thedarkcolour.kotlinforforge.forge + +import net.minecraft.util.ResourceLocation +import net.minecraftforge.event.RegistryEvent +import net.minecraftforge.eventbus.api.IEventBus +import net.minecraftforge.fml.RegistryObject +import net.minecraftforge.registries.DeferredRegister +import net.minecraftforge.registries.IForgeRegistry +import net.minecraftforge.registries.IForgeRegistryEntry +import net.minecraftforge.registries.RegistryManager +import thedarkcolour.kotlinforforge.eventbus.KotlinEventBus +import kotlin.properties.ReadOnlyProperty + +/** + * Alternative version of [DeferredRegister] that creates + * [ObjectHolderDelegate] instances instead of [RegistryObject]. + */ +public class KDeferredRegister<V : IForgeRegistryEntry<V>>( + public val registry: IForgeRegistry<V>, + public val modid: String, +) { + /** + * A map of all registry objects and their value suppliers. + */ + private val entries = HashMap<ObjectHolderDelegate<out V>, () -> V>() + + /** + * Alternative constructor that uses a class instead of a registry. + */ + public constructor(registryClass: Class<V>, modid: String) : this(RegistryManager.ACTIVE.getRegistry(registryClass), modid) + + /** + * Registers this deferred register to the `KotlinEventBus`. + */ + public fun register(bus: KotlinEventBus) { + bus.addGenericListener(registry.registrySuperType, ::addEntries) + } + + /** + * Registers this deferred register to the `IEventBus`. + */ + @Deprecated("Use a KotlinEventBus. Forge's EventBus does not support function references for event listeners.") + public fun register(bus: IEventBus) { + // function references are not supported by Forge's eventbus + bus.addGenericListener(registry.registrySuperType) { event: RegistryEvent.Register<V> -> + addEntries(event) + } + } + + /** + * Adds a registry object to this deferred registry. + * + * @param name the path of the new registry object's registry name with namespace [modid] + * @param supplier the function to initialize the value of the new registry object with and + * to reset the value when forge adds reloadable registries. + * + * @return A new [ObjectHolderDelegate] with the given registry name and value + */ + public fun <T : V> register(name: String, supplier: () -> T): ReadOnlyProperty<Any?, T> { + val key = ResourceLocation(modid, name) + val a = ObjectHolderDelegate<T>(key, registry) + + entries[a] = { supplier().setRegistryName(key) } + + return a + } + + public fun getEntries(): Set<ObjectHolderDelegate<out V>> { + return entries.keys + } + + /** + * Adds all entries in this registry to the corresponding game registries. + */ + private fun addEntries(event: RegistryEvent.Register<V>) { + val registry = event.registry + + for ((objectHolder, supplier) in entries) { + registry.register(supplier()) + // pass true to always update the entry + objectHolder.accept { true } + } + } +}
\ No newline at end of file |