Skip to content

Commit

Permalink
create first event
Browse files Browse the repository at this point in the history
  • Loading branch information
PssbleTrngle committed Jul 5, 2023
1 parent 6368d79 commit c841177
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.possible_triangle.skygrid.api.events

import com.possible_triangle.skygrid.platform.Services
import kotlinx.serialization.KSerializer
import kotlinx.serialization.serializer
import kotlin.reflect.KClass

interface RegisterElementEvent {

companion object {
val EVENT = Services.EVENTS.createEvent(RegisterElementEvent::class)
}

fun <TParent : Any, TSub : TParent> register(
parent: KClass<TParent>,
subclass: KClass<TSub>,
serializer: KSerializer<TSub>,
)

}

interface RegisterElementBuilder<TParent : Any> {
fun <TSub : TParent> subclass(clazz: KClass<TSub>, serializer: KSerializer<TSub>)
}

inline fun <TParent : Any, reified TSub : TParent> RegisterElementEvent.register(
parent: KClass<TParent>,
subclass: KClass<TSub>,
) = register(parent, subclass, serializer())

inline fun <TParent : Any, reified TSub : TParent> RegisterElementBuilder<TParent>.subclass(clazz: KClass<TSub>) =
subclass(clazz, serializer())


inline fun <TParent : Any> RegisterElementEvent.register(
parent: KClass<TParent>,
builder: RegisterElementBuilder<TParent>.() -> Unit,
) = object : RegisterElementBuilder<TParent> {
override fun <TSub : TParent> subclass(clazz: KClass<TSub>, serializer: KSerializer<TSub>) {
register(parent, clazz, serializer)
}
}.apply(builder)
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package com.possible_triangle.skygrid.platform

import com.possible_triangle.skygrid.SkygridMod
import com.possible_triangle.skygrid.platform.services.IConfig
import com.possible_triangle.skygrid.platform.services.IEvents
import com.possible_triangle.skygrid.platform.services.IPlatformHelper
import java.util.*

object Services {

val PLATFORM = load(IPlatformHelper::class.java)
val CONFIG = load(IConfig::class.java)
val EVENTS = load(IEvents::class.java)

private fun <T> load(clazz: Class<T>): T {
val loadedService: T = ServiceLoader.load(clazz)
return ServiceLoader.load(clazz)
.findFirst()
.orElseThrow { NullPointerException("Failed to load service for ${clazz.name}") }
SkygridMod.LOGGER.debug("Loaded $loadedService for service $clazz")
return loadedService
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.possible_triangle.skygrid.platform.services

import kotlin.reflect.KClass

interface EventInvoker<TEvent> {
fun invoke(event: TEvent)
fun addListener(callback: EventCallback<TEvent>)
}

fun interface EventCallback<T> {
fun accept(event: T)
}

interface IEvents {

fun <TEvent : Any> createEvent(clazz: KClass<TEvent>): EventInvoker<TEvent>

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.possible_triangle.skygrid.platform.services

import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.TagKey
import net.minecraft.world.level.block.Block
import kotlin.properties.ReadOnlyProperty

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.possible_triangle.skygrid

import com.possible_triangle.skygrid.api.SkygridConstants.MOD_ID
import com.possible_triangle.skygrid.api.SkygridConstants.MOD_NAME
import com.possible_triangle.skygrid.api.events.RegisterElementEvent
import com.possible_triangle.skygrid.block.StiffAir
import com.possible_triangle.skygrid.platform.Services
import com.possible_triangle.skygrid.world.SkygridChunkGenerator
import com.possible_triangle.skygrid.xml.registerDefaultElements
import com.possible_triangle.skygrid.xml.resources.DimensionConfigs
import com.possible_triangle.skygrid.xml.resources.Presets
import net.minecraft.ChatFormatting
Expand All @@ -23,12 +25,18 @@ object SkygridMod {
val STIFF_AIR by Services.PLATFORM.createBlock("stiff_air") { StiffAir() }

fun init() {
registerEvents()
Presets.register()
DimensionConfigs.register()
}

private fun registerEvents() {
RegisterElementEvent.EVENT.addListener {
it.registerDefaultElements()
}
}

fun setup() {
LOGGER.info("Skygrid booting")
Registry.register(Registry.CHUNK_GENERATOR, ResourceLocation(MOD_ID, MOD_ID), SkygridChunkGenerator.CODEC)
}

Expand Down
108 changes: 108 additions & 0 deletions common/src/main/kotlin/com/possible_triangle/skygrid/xml/XMLModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.possible_triangle.skygrid.xml

import com.possible_triangle.skygrid.api.events.RegisterElementEvent
import com.possible_triangle.skygrid.api.events.register
import com.possible_triangle.skygrid.api.events.subclass
import com.possible_triangle.skygrid.api.xml.DeserializationException
import com.possible_triangle.skygrid.api.xml.elements.*
import com.possible_triangle.skygrid.api.xml.elements.extras.Cardinal
import com.possible_triangle.skygrid.api.xml.elements.extras.Offset
import com.possible_triangle.skygrid.api.xml.elements.extras.Side
import com.possible_triangle.skygrid.api.xml.elements.filters.ExceptFilter
import com.possible_triangle.skygrid.api.xml.elements.filters.ModFilter
import com.possible_triangle.skygrid.api.xml.elements.filters.NameFilter
import com.possible_triangle.skygrid.api.xml.elements.filters.TagFilter
import com.possible_triangle.skygrid.api.xml.elements.providers.*
import com.possible_triangle.skygrid.api.xml.elements.transformers.CyclePropertyTransformer
import com.possible_triangle.skygrid.api.xml.elements.transformers.SetPropertyTransformer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.modules.PolymorphicModuleBuilder
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.SerializersModuleBuilder
import kotlinx.serialization.modules.polymorphic
import nl.adaptivity.xmlutil.ExperimentalXmlUtilApi
import nl.adaptivity.xmlutil.serialization.UnknownChildHandler
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlSerializationPolicy
import kotlin.reflect.KClass

private typealias Sub<T> = Pair<KClass<T>, KSerializer<T>>

private fun SerializersModuleBuilder.collectRegisteredElements() {
val collected = hashMapOf<KClass<*>, MutableCollection<Sub<*>>>()

RegisterElementEvent.EVENT.invoke(object : RegisterElementEvent {
override fun <TParent : Any, TSub : TParent> register(
parent: KClass<TParent>,
subclass: KClass<TSub>,
serializer: KSerializer<TSub>,
) {
collected.getOrPut(parent, ::hashSetOf).add(subclass to serializer)
}
})

fun <TParent : Any, TSub : TParent> PolymorphicModuleBuilder<TParent>.subclass(it: Sub<*>) {
subclass(it.first as KClass<TSub>, it.second as KSerializer<TSub>)
}

fun <TParent : Any> registerPolymorphic(parent: KClass<TParent>, subclasses: Collection<Sub<*>>) {
polymorphic(parent) {
subclasses.forEach {
subclass(it)
}
}
}

collected.forEach { (parent, subclasses) ->
registerPolymorphic(parent, subclasses)
}
}

fun RegisterElementEvent.registerDefaultElements() {
register(BlockProvider::class) {
subclass(BlockList::class)
subclass(Fallback::class)
subclass(Tag::class)
subclass(SingleBlock::class)
subclass(Reference::class)
}

register(Transformer::class) {
subclass(SetPropertyTransformer::class)
subclass(CyclePropertyTransformer::class)
}

register(FilterOperator::class) {
subclass(ExceptFilter::class)
}

register(Extra::class) {
subclass(Side::class)
subclass(Cardinal::class)
subclass(Offset::class)
}

register(Filter::class) {
subclass(NameFilter::class)
subclass(ModFilter::class)
subclass(TagFilter::class)
}
}

@ExperimentalXmlUtilApi
fun createXMLModule() = XML(SerializersModule {
collectRegisteredElements()
}) {
defaultPolicy {
indentString = " ".repeat(3)
autoPolymorphic = true
encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER
unknownChildHandler = UnknownChildHandler { input, _, descriptor, name, candidates ->
throw DeserializationException(
input.locationInfo,
"${descriptor.tagName}/${name ?: "<CDATA>"}",
candidates
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
package com.possible_triangle.skygrid.xml

import com.google.common.base.Suppliers
import com.possible_triangle.skygrid.SkygridMod.LOGGER
import com.possible_triangle.skygrid.api.SkygridConstants
import com.possible_triangle.skygrid.api.xml.DeserializationException
import com.possible_triangle.skygrid.api.xml.elements.*
import com.possible_triangle.skygrid.api.xml.elements.extras.Cardinal
import com.possible_triangle.skygrid.api.xml.elements.extras.Offset
import com.possible_triangle.skygrid.api.xml.elements.extras.Side
import com.possible_triangle.skygrid.api.xml.elements.filters.ExceptFilter
import com.possible_triangle.skygrid.api.xml.elements.filters.ModFilter
import com.possible_triangle.skygrid.api.xml.elements.filters.NameFilter
import com.possible_triangle.skygrid.api.xml.elements.filters.TagFilter
import com.possible_triangle.skygrid.api.xml.elements.providers.*
import com.possible_triangle.skygrid.api.xml.elements.transformers.CyclePropertyTransformer
import com.possible_triangle.skygrid.api.xml.elements.transformers.SetPropertyTransformer
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
import kotlinx.serialization.StringFormat
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.MinecraftServer
import net.minecraft.server.packs.resources.Resource
import net.minecraft.server.packs.resources.ResourceManager
import net.minecraft.server.packs.resources.SimplePreparableReloadListener
import net.minecraft.util.profiling.ProfilerFiller
import nl.adaptivity.xmlutil.ExperimentalXmlUtilApi
import nl.adaptivity.xmlutil.serialization.UnknownChildHandler
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlSerializationPolicy
import java.io.File

abstract class XMLResource<T>(val path: String, private val serializer: () -> KSerializer<T>) :
Expand All @@ -37,49 +22,7 @@ abstract class XMLResource<T>(val path: String, private val serializer: () -> KS
@ExperimentalXmlUtilApi
@ExperimentalSerializationApi
companion object {
val LOADER = XML(SerializersModule {
polymorphic(BlockProvider::class) {
subclass(BlockList::class)
subclass(Fallback::class)
subclass(Tag::class)
subclass(SingleBlock::class)
subclass(Reference::class)
}

polymorphic(Transformer::class) {
subclass(SetPropertyTransformer::class)
subclass(CyclePropertyTransformer::class)
}

polymorphic(FilterOperator::class) {
subclass(ExceptFilter::class)
}

polymorphic(Extra::class) {
subclass(Side::class)
subclass(Cardinal::class)
subclass(Offset::class)
}

polymorphic(Filter::class) {
subclass(NameFilter::class)
subclass(ModFilter::class)
subclass(TagFilter::class)
}
}) {
defaultPolicy {
indentString = " ".repeat(3)
autoPolymorphic = true
encodeDefault = XmlSerializationPolicy.XmlEncodeDefault.NEVER
unknownChildHandler = UnknownChildHandler { input, _, descriptor, name, candidates ->
throw DeserializationException(
input.locationInfo,
"${descriptor.tagName}/${name ?: "<CDATA>"}",
candidates
)
}
}
}
val LOADER: StringFormat get() = Suppliers.memoize(::createXMLModule).get()

private val RESOURCES = arrayListOf<XMLResource<*>>()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.possible_triangle.skygrid.test

import com.possible_triangle.skygrid.SkygridMod
import com.possible_triangle.skygrid.test.mocks.WorldMock
import net.minecraft.SharedConstants
import net.minecraft.server.Bootstrap
Expand All @@ -20,6 +21,7 @@ class TestExtension : BeforeAllCallback, BeforeEachCallback {
SharedConstants.tryDetectVersion()
Bootstrap.bootStrap()
Bootstrap.validate()
SkygridMod.init()
}

override fun beforeEach(context: ExtensionContext?) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.possible_triangle.skygrid.test.mocks

import com.possible_triangle.skygrid.platform.services.EventCallback
import com.possible_triangle.skygrid.platform.services.EventInvoker
import com.possible_triangle.skygrid.platform.services.IEvents
import kotlin.reflect.KClass

class EventsMock : IEvents {

class SimpleEventBus<TEvent> : EventInvoker<TEvent> {
private val listeners = hashSetOf<EventCallback<TEvent>>()

override fun invoke(event: TEvent) {
listeners.forEach {
it.accept(event)
}
}

override fun addListener(callback: EventCallback<TEvent>) {
listeners.add(callback)
}
}

override fun <TEvent : Any> createEvent(clazz: KClass<TEvent>) = SimpleEventBus<TEvent>()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.possible_triangle.skygrid.test.mocks.EventsMock
9 changes: 5 additions & 4 deletions common/src/test/resources/snapshot.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
serializer=au.com.origin.snapshots.serializers.ToStringSnapshotSerializer
comparator=au.com.origin.snapshots.comparators.PlainTextEqualsComparator
reporters=au.com.origin.snapshots.reporters.PlainTextSnapshotReporter
serializer=au.com.origin.snapshots.serializers.v1.ToStringSnapshotSerializer
comparator=au.com.origin.snapshots.comparators.v1.PlainTextEqualsComparator
reporters=au.com.origin.snapshots.reporters.v1.PlainTextSnapshotReporter
snapshot-dir=__snapshots__
output-dir=../src/test/kotlin
ci-env-var=CI
ci-env-var=CI
update-snapshot=none
Loading

0 comments on commit c841177

Please sign in to comment.