Passing this reference when using implementation by delegation in Kotlin

154 Views Asked by At

I'm using Implementation by Delegation to create a kind of entity-component system.

A simplified example:

// attribute 1: can take damage
interface Damageable {
  val broken: Boolean
  fun takeDamage(dmg: Int)
}

// simple implementation
class HpComponent(private var hp: Int): Damageable {
  override val broken: Boolean
    get() = hp <= 0
  override fun takeDamage(dmg: Int) {
    hp -= dmg
  }
}

// attribute 2: something with electricity
interface Electric {
  fun overcharge()
}

// implementation where overcharge damages the component
class PlainElectricComponent(private val component: Damageable): Electric {
  override fun overcharge() {
    component.takeDamage(10)
  }
}


// oven entity
class Oven: Damageable by HpComponent(hp=20), Electric by PlainElectricComponent(this)

The compiler gives me an error for using this in the constructor of PlainElectricComponent: 'this' is not defined in this context. The answers to this question say that due to JVM related constraints, using the this pointer is not possible during this phase of object construction.

I know that I can initialize component later, e.g. by

class PlainElectricComponent: Electric {
  lateinit var component: Damageable
  ...
}

class Oven(private val ec: PlainElectricComponent = PlainElectricComponent()):
  Damageable by HpComponent(hp=20),
  Electric by ec
{
  init {
    ec.component = this
  }
}

but this forces an ugly constructor property and requires the additional "wiring" which can be forgotten easily.

Are you aware of another way to keep the declaration of components for an entity that straight-forward?

PS: Having Oven implementing the interfaces, I can fully use the compilers type-checking, smart casting, etc.

0

There are 0 best solutions below