diff --git a/orx-parameters/src/main/kotlin/Annotations.kt b/orx-parameters/src/main/kotlin/Annotations.kt
index 00b8d94c..8763040f 100644
--- a/orx-parameters/src/main/kotlin/Annotations.kt
+++ b/orx-parameters/src/main/kotlin/Annotations.kt
@@ -17,6 +17,7 @@ import kotlin.reflect.full.memberProperties
5. Add a test in TestAnnotations.kt
*/
+//
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Description(val title: String, val description: String = "")
@@ -33,6 +34,29 @@ annotation class Description(val title: String, val description: String = "")
@Retention(AnnotationRetention.RUNTIME)
annotation class DoubleParameter(val label: String, val low: Double, val high: Double, val precision: Int = 3, val order: Int = Integer.MAX_VALUE)
+
+/**
+ * DoubleListParameter annotation for a double precision parameter
+ * @property label a short description of the parameter
+ * @property low the lowest value this parameter should be assigned
+ * @property high the highest value this parameter should be assigned
+ * @property minimumListLength the minimum amount of entries the annotated list should contain
+ * @property maximumListLength the maximum amount of entries the annotated list should contain
+ * @property precision a hint for precision in user interfaces
+ * @property order hint for where to place the parameter in user interfaces
+ */
+@Target(AnnotationTarget.PROPERTY)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class DoubleListParameter(
+ val label: String,
+ val low: Double = -1.0,
+ val high: Double = 1.0,
+ val minimumListLength: Int = 1,
+ val maximumListLength: Int = 16,
+ val precision: Int = 3,
+ val order: Int = Integer.MAX_VALUE
+)
+
/**
* IntParameter annotation for an integer parameter
* @property label a short description of the parameter
@@ -100,6 +124,8 @@ annotation class XYParameter(
@Retention(AnnotationRetention.RUNTIME)
annotation class ActionParameter(val label: String, val order: Int = Integer.MAX_VALUE)
+//
+//
enum class ParameterType(val annotationClass: KClass) {
Double(DoubleParameter::class),
Int(IntParameter::class),
@@ -107,7 +133,8 @@ enum class ParameterType(val annotationClass: KClass) {
Action(ActionParameter::class),
Text(TextParameter::class),
Color(ColorParameter::class),
- XY(XYParameter::class)
+ XY(XYParameter::class),
+ DoubleList(DoubleListParameter::class)
;
companion object {
@@ -117,7 +144,8 @@ enum class ParameterType(val annotationClass: KClass) {
val parameterAnnotationClasses get() = values().map { it.annotationClass }
}
}
-
+//
+//
/**
* Parameter summary class. This is used by [listParameters] as a way to report parameters in
* a unified form.
@@ -138,25 +166,28 @@ class Parameter(
val label: String,
val doubleRange: ClosedRange?,
val vectorRange: Pair?,
+ val sizeRange: ClosedRange?,
val intRange: IntRange?,
val precision: Int?,
val invertY: Boolean?,
val showVector: Boolean?,
val order: Int)
-
+//
+//
/**
* List all parameters, (public var properties with a parameter annotation)
*/
fun Any.listParameters(): List {
- return (this::class.memberProperties.filter {
- !it.isConst &&
- it is KMutableProperty1<*, *> &&
- it.visibility == KVisibility.PUBLIC &&
- it.annotations.map { it.annotationClass }.intersect(ParameterType.parameterAnnotationClasses).isNotEmpty()
- }.map {
- val annotations = it.annotations.filter { it.annotationClass in ParameterType.parameterAnnotationClasses }
+ return (this::class.memberProperties.filter { property ->
+ !property.isConst &&
+ property is KMutableProperty1<*, *> &&
+ property.visibility == KVisibility.PUBLIC &&
+ property.annotations.map { it.annotationClass }.intersect(ParameterType.parameterAnnotationClasses).isNotEmpty()
+ }.map { property ->
+ val annotations = property.annotations.filter { it.annotationClass in ParameterType.parameterAnnotationClasses }
var intRange: IntRange? = null
var doubleRange: ClosedRange? = null
+ var sizeRange: ClosedRange? = null
var order: Int = Integer.MAX_VALUE
var label = ""
var precision: Int? = null
@@ -199,15 +230,24 @@ fun Any.listParameters(): List {
invertY = it.invertY
showVector = it.showVector
}
+ is DoubleListParameter -> {
+ label = it.label
+ order = it.order
+ doubleRange = it.low..it.high
+ precision = it.precision
+ sizeRange = it.minimumListLength..it.maximumListLength
+
+ }
}
}
Parameter(
parameterType = type ?: error("no type"),
- property = it as KMutableProperty1,
+ property = property as KMutableProperty1,
function = null,
label = label,
doubleRange = doubleRange,
vectorRange = vectorRange,
+ sizeRange = sizeRange,
intRange = intRange,
precision = precision,
showVector = showVector,
@@ -228,6 +268,7 @@ fun Any.listParameters(): List {
label = label,
doubleRange = null,
intRange = null,
+ sizeRange = null,
vectorRange = null,
precision = null,
showVector = null,
@@ -236,6 +277,7 @@ fun Any.listParameters(): List {
)
}).sortedBy { it.order }
}
+//
fun Any.title() = this::class.findAnnotation()?.title
diff --git a/orx-parameters/src/test/kotlin/TestAnnotations.kt b/orx-parameters/src/test/kotlin/TestAnnotations.kt
index 21f7bd67..6e2cff93 100644
--- a/orx-parameters/src/test/kotlin/TestAnnotations.kt
+++ b/orx-parameters/src/test/kotlin/TestAnnotations.kt
@@ -28,20 +28,23 @@ val a = object {
@XYParameter("an XY parameter", order = 6)
var xy = Vector2.ZERO
+
+ @DoubleListParameter("a double list parameter", order = 7)
+ var dl = mutableListOf()
}
object TestAnnotations : Spek({
describe("an annotated object") {
it("has listable parameters") {
val list = a.listParameters()
- list.size `should be equal to` 7
+ list.size `should be equal to` 8
list[0].property?.name `should be equal to` "d"
list[0].parameterType `should be equal to` ParameterType.Double
list[0].label `should be equal to` "a double scalar"
list[0].doubleRange?.let {
- it.start shouldBeInRange 0.0 .. 0.0001
- it.endInclusive shouldBeInRange 0.999 .. 1.001
+ it.start shouldBeInRange 0.0..0.0001
+ it.endInclusive shouldBeInRange 0.999..1.001
}
list[0].precision `should be equal to` 3
@@ -68,7 +71,7 @@ object TestAnnotations : Spek({
invoking {
try {
list[3].function?.call(a)
- } catch(e: java.lang.reflect.InvocationTargetException) {
+ } catch (e: java.lang.reflect.InvocationTargetException) {
/* this unpacks the exception that is wrapped in the ITExc */
throw(e.targetException)
}
@@ -85,6 +88,10 @@ object TestAnnotations : Spek({
list[6].parameterType `should be equal to` ParameterType.XY
list[6].property?.name `should be equal to` "xy"
list[6].label `should be equal to` "an XY parameter"
+
+ list[7].parameterType `should be equal to` ParameterType.DoubleList
+ list[7].property?.name `should be equal to` "dl"
+ list[7].label `should be equal to` "a double list parameter"
}
}
})