Skip to content

Commit

Permalink
Merge pull request #158 from Jkly/unable-to-create-component-error
Browse files Browse the repository at this point in the history
Throw an appropriate exception if createComponent fails
  • Loading branch information
czyzby authored Sep 20, 2018
2 parents cc6051a + 53f9321 commit 14c86ab
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
16 changes: 14 additions & 2 deletions ashley/src/main/kotlin/ktx/ashley/engines.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ktx.ashley
import com.badlogic.ashley.core.Component
import com.badlogic.ashley.core.Engine
import com.badlogic.ashley.core.Entity
import kotlin.reflect.KClass

/**
* An [Entity] created by the provided [Engine].
Expand All @@ -23,6 +24,7 @@ class EngineEntity(
* @param T the [Component] type to get or create.
* @param configure inlined function with [T] as the receiver to allow additional configuration of the [Component].
* @return the created ƒ[Component].
* @throws [CreateComponentException] if the engine was unable to create the component
* @see [create]
*/
inline fun <reified T : Component> with(configure: (@AshleyDsl T).() -> Unit = {}): T {
Expand All @@ -36,12 +38,20 @@ class EngineEntity(
/**
* Get or create a [Component] by calling [Engine.createComponent].
*
* The [Component] must have a visible no-arg constructor.
*
* @param T the type of [Component] to get or create.
* @param configure inlined function with [T] as the receiver to allow further configuration.
* @return an [Component] instance of the selected type.
* @throws [CreateComponentException] if the engine was unable to create the component
*/
inline fun <reified T : Component> Engine.create(configure: T.() -> Unit = {}): T
= createComponent(T::class.java).apply(configure)
inline fun <reified T : Component> Engine.create(configure: T.() -> Unit = {}): T {
return try {
createComponent(T::class.java)
} catch (e: Exception) {
throw CreateComponentException(T::class, e)
}?.apply(configure)?:throw CreateComponentException(T::class)
}

/**
* Builder function for [Engine].
Expand All @@ -63,3 +73,5 @@ inline fun Engine.entity(configure: EngineEntity.() -> Unit = {}): Entity {
addEntity(entity)
return entity
}

class CreateComponentException(type: KClass<*>, cause: Throwable? = null): RuntimeException("Could not instantiate component ${type::java.name} - the component must have a visible no-arg constructor", cause)
20 changes: 20 additions & 0 deletions ashley/src/test/kotlin/ktx/ashley/EnginesSpec.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package ktx.ashley

import com.badlogic.ashley.core.Component
import com.badlogic.ashley.core.Engine
import com.badlogic.ashley.core.PooledEngine
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.describe
import org.jetbrains.spek.api.dsl.it
Expand All @@ -18,6 +21,23 @@ object EnginesSpec : Spek({
assertThat(component.y).isEqualTo(0f)
}
}
describe("creating a component that has no no-arg constructor") {
@Suppress("UNUSED_PARAMETER")
class NoNoArgConstructorComponent(body: String): Component

it("should throw an exception if the non-pooled engine was unable to create the component") {
val nonPooledEngine = Engine()
assertThatExceptionOfType(CreateComponentException::class.java).isThrownBy {
nonPooledEngine.create<NoNoArgConstructorComponent>()
}
}

it("should throw an exception if the pooled engine was unable to create the component") {
assertThatExceptionOfType(CreateComponentException::class.java).isThrownBy {
engine.create<NoNoArgConstructorComponent>()
}
}
}
describe("creating a component with configuration") {
val component = engine.create<Transform> {
x = 1f
Expand Down

0 comments on commit 14c86ab

Please sign in to comment.