Skip to content

Commit 67d8870

Browse files
committedMar 8, 2024·
Fix annotation detection in ReactiveComponent
1 parent 8191bdb commit 67d8870

File tree

7 files changed

+103
-5
lines changed

7 files changed

+103
-5
lines changed
 

‎build.gradle.kts

+3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ repositories {
1111

1212
dependencies {
1313

14+
implementation("org.jetbrains.kotlin:kotlin-stdlib")
15+
implementation("org.jetbrains.kotlin:kotlin-reflect")
1416

1517
testImplementation("org.jetbrains.kotlin:kotlin-test")
1618
}
1719

1820
tasks.test {
1921
useJUnitPlatform()
2022
}
23+
2124
kotlin {
2225
jvmToolchain(17)
2326
}

‎gradlew

100644100755
File mode changed.

‎settings.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ pluginManagement {
77

88
rootProject.name = "void-ui"
99

10-
include("test-mod")
10+
//include("test-mod")

‎src/main/kotlin/com/neptuneclient/voidui/VoidUI.kt

+24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.neptuneclient.voidui
22

33
import com.neptuneclient.voidui.rendering.Renderer
4+
import com.neptuneclient.voidui.ui.Component
5+
import com.neptuneclient.voidui.ui.ReactiveComponent
6+
import com.neptuneclient.voidui.ui.State
47

58
/**
69
* The main class of VoidUI. It is mostly used to contain settings and singleton instances of other classes
@@ -14,4 +17,25 @@ class VoidUI
1417
*/
1518
constructor(val renderer: Renderer) {
1619

20+
}
21+
22+
class TestComponent : ReactiveComponent() {
23+
@State
24+
public var testState = 5
25+
26+
override fun build(): Component {
27+
println("Building TestComponent")
28+
return this
29+
}
30+
}
31+
32+
fun main(args: Array<String>) {
33+
34+
val component = TestComponent().build()
35+
if (component is TestComponent) {
36+
println("TestComponent.testState: ${component.testState}")
37+
component.testState = 1
38+
println("TestComponent.testState: ${component.testState}")
39+
}
40+
1741
}

‎src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
package com.neptuneclient.voidui.ui
22

33
import kotlin.properties.Delegates
4+
import kotlin.reflect.KMutableProperty
5+
import kotlin.reflect.full.declaredMemberProperties
6+
import kotlin.reflect.full.findAnnotation
7+
import kotlin.reflect.jvm.javaField
48

59
/**
610
* @see Component
711
*/
812
abstract class ReactiveComponent : Component() {
913

1014
init {
11-
for (field in javaClass.declaredFields) {
12-
if (!field.isAnnotationPresent(State::class.java)) continue
13-
val fieldObserver = Delegates.observable(field.get(this)) { _, _, new ->
15+
for (member in this::class.declaredMemberProperties) {
16+
println("Member $member")
17+
println("Member annotations size: ${member.annotations.size}")
18+
if (member.findAnnotation<State>() == null) continue
19+
println("Member $member is a state")
20+
val memberObserver = Delegates.observable(member.getter.call(this)) { _, _, new ->
21+
println("Member $member changed to $new")
1422
this.build()
1523
// TODO do proper rebuilding in the component tree
1624
}
17-
field.set(this, fieldObserver)
25+
26+
if (member is KMutableProperty<*>) {
27+
member.setter.call(this, memberObserver)
28+
}
1829
}
1930
}
2031

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.neptuneclient.voidui.tests
2+
3+
import com.neptuneclient.voidui.rendering.Renderer
4+
import java.awt.Color
5+
6+
class MockRenderer : Renderer {
7+
override fun beginFrame() {
8+
println("beginFrame")
9+
}
10+
11+
override fun endFrame() {
12+
println("endFrame")
13+
}
14+
15+
override fun rectangle(x: Float, y: Float, width: Float, height: Float, color: Color) {
16+
println("rectangle: x=$x, y=$y, width=$width, height=$height, color=$color")
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.neptuneclient.voidui.tests
2+
3+
import com.neptuneclient.voidui.VoidUI
4+
import com.neptuneclient.voidui.ui.Component
5+
import com.neptuneclient.voidui.ui.ReactiveComponent
6+
import com.neptuneclient.voidui.ui.Screen
7+
import com.neptuneclient.voidui.ui.State
8+
import org.junit.jupiter.api.Test
9+
10+
class VoidScreenTest(void: VoidUI) : Screen(void) {
11+
override fun build(): Component {
12+
return TestComponent()
13+
}
14+
}
15+
16+
class TestComponent : ReactiveComponent() {
17+
@State
18+
public var testState = 5
19+
20+
override fun build(): Component {
21+
println("Building TestComponent")
22+
return this
23+
}
24+
}
25+
26+
object Tests {
27+
@Test
28+
fun testState() {
29+
val renderer = MockRenderer()
30+
val void = VoidUI(renderer)
31+
val screen = VoidScreenTest(void)
32+
33+
val screen_component = screen.build()
34+
val component = screen_component.build()
35+
if (component is TestComponent) {
36+
println("TestComponent.testState: ${component.testState}")
37+
component.testState = 1
38+
println("TestComponent.testState: ${component.testState}")
39+
}
40+
41+
}
42+
}

0 commit comments

Comments
 (0)
Please sign in to comment.