aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/thedarkcolour
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/thedarkcolour')
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt27
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/forge/KDeferredRegister.kt84
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