1
0
mirror of https://github.com/chylex/Hardcore-Ender-Expansion-2.git synced 2025-04-11 03:15:44 +02:00

Add a component system

This commit is contained in:
chylex 2021-02-28 13:29:18 +01:00
parent a9df51e315
commit 3279dde625
4 changed files with 103 additions and 0 deletions
src/system/src/main/java/chylex/hee/system/component

View File

@ -0,0 +1,8 @@
package chylex.hee.system.component
abstract class AbstractAwareComponent {
var entityComponents: EntityComponents? = null
open fun onComponentAttached() {}
open fun onComponentDetached() {}
}

View File

@ -0,0 +1,56 @@
package chylex.hee.system.component
class EntityComponents {
private val mutableComponents = mutableListOf<Any>()
val components: List<Any>
get() = mutableComponents
fun attach(component: Any) {
require(!mutableComponents.contains(component)) { "[EntityComponents] component must not be registered twice" }
mutableComponents.add(component)
if (component is AbstractAwareComponent) {
require(component.entityComponents === null) { "[EntityComponents] component must not be registered in two entities" }
component.entityComponents = this
component.onComponentAttached()
}
}
fun detach(component: Any) {
if (!mutableComponents.remove(component)) {
return
}
if (component is AbstractAwareComponent) {
require(component.entityComponents === this) { "[EntityComponents] component was not registered correctly" }
component.onComponentDetached()
component.entityComponents = null
}
}
inline fun <reified T> on(f: T.() -> Unit) {
for(component in components) {
if (component is T) {
f(component)
}
}
}
inline fun <reified T, U> handle(f: T.() -> U?): U? {
for(component in components) {
if (component is T) {
val result = f(component)
if (result != null) {
return result
}
}
}
return null
}
inline fun <reified T> list(): List<T> {
return components.filterIsInstance<T>()
}
}

View File

@ -0,0 +1,20 @@
package chylex.hee.system.component.general
import chylex.hee.system.component.EntityComponents
import chylex.hee.system.serialization.TagCompound
import net.minecraftforge.common.util.INBTSerializable
interface SerializableComponent : INBTSerializable<TagCompound> {
val serializationKey: String
}
fun EntityComponents.serializeTo(tag: TagCompound) {
this.on<SerializableComponent> {
require(!tag.contains(serializationKey)) { "[SerializableComponent] cannot serialize duplicate key: $serializationKey" }
tag.put(serializationKey, serializeNBT())
}
}
fun EntityComponents.deserializeFrom(tag: TagCompound) {
this.on<SerializableComponent> { deserializeNBT(tag.getCompound(serializationKey)) }
}

View File

@ -0,0 +1,19 @@
package chylex.hee.system.component.general
import chylex.hee.system.component.EntityComponents
import net.minecraft.entity.Entity
interface TickableComponent {
@JvmDefault fun tickClient() {}
@JvmDefault fun tickServer() {}
}
@JvmName("tickEntity")
fun <T : Entity> EntityComponents.tick(entity: T) {
if (entity.world.isRemote) {
this.on(TickableComponent::tickClient)
}
else {
this.on(TickableComponent::tickServer)
}
}