Skip to content

Commit

Permalink
Fix annotation detection in ReactiveComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon3244 committed Mar 8, 2024
1 parent 8191bdb commit 67d8870
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 5 deletions.
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ repositories {

dependencies {

implementation("org.jetbrains.kotlin:kotlin-stdlib")
implementation("org.jetbrains.kotlin:kotlin-reflect")

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

tasks.test {
useJUnitPlatform()
}

kotlin {
jvmToolchain(17)
}
Empty file modified gradlew
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ pluginManagement {

rootProject.name = "void-ui"

include("test-mod")
//include("test-mod")
24 changes: 24 additions & 0 deletions src/main/kotlin/com/neptuneclient/voidui/VoidUI.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.neptuneclient.voidui

import com.neptuneclient.voidui.rendering.Renderer
import com.neptuneclient.voidui.ui.Component
import com.neptuneclient.voidui.ui.ReactiveComponent
import com.neptuneclient.voidui.ui.State

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

}

class TestComponent : ReactiveComponent() {
@State
public var testState = 5

override fun build(): Component {
println("Building TestComponent")
return this
}
}

fun main(args: Array<String>) {

val component = TestComponent().build()
if (component is TestComponent) {
println("TestComponent.testState: ${component.testState}")
component.testState = 1
println("TestComponent.testState: ${component.testState}")
}

}
19 changes: 15 additions & 4 deletions src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
package com.neptuneclient.voidui.ui

import kotlin.properties.Delegates
import kotlin.reflect.KMutableProperty
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.jvm.javaField

/**
* @see Component
*/
abstract class ReactiveComponent : Component() {

init {
for (field in javaClass.declaredFields) {
if (!field.isAnnotationPresent(State::class.java)) continue
val fieldObserver = Delegates.observable(field.get(this)) { _, _, new ->
for (member in this::class.declaredMemberProperties) {
println("Member $member")
println("Member annotations size: ${member.annotations.size}")
if (member.findAnnotation<State>() == null) continue
println("Member $member is a state")
val memberObserver = Delegates.observable(member.getter.call(this)) { _, _, new ->
println("Member $member changed to $new")
this.build()
// TODO do proper rebuilding in the component tree
}
field.set(this, fieldObserver)

if (member is KMutableProperty<*>) {
member.setter.call(this, memberObserver)
}
}
}

Expand Down
18 changes: 18 additions & 0 deletions src/test/kotlin/com/neptuneclient/voidui/tests/MockRenderer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.neptuneclient.voidui.tests

import com.neptuneclient.voidui.rendering.Renderer
import java.awt.Color

class MockRenderer : Renderer {
override fun beginFrame() {
println("beginFrame")
}

override fun endFrame() {
println("endFrame")
}

override fun rectangle(x: Float, y: Float, width: Float, height: Float, color: Color) {
println("rectangle: x=$x, y=$y, width=$width, height=$height, color=$color")
}
}
42 changes: 42 additions & 0 deletions src/test/kotlin/com/neptuneclient/voidui/tests/VoidScreenTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.neptuneclient.voidui.tests

import com.neptuneclient.voidui.VoidUI
import com.neptuneclient.voidui.ui.Component
import com.neptuneclient.voidui.ui.ReactiveComponent
import com.neptuneclient.voidui.ui.Screen
import com.neptuneclient.voidui.ui.State
import org.junit.jupiter.api.Test

class VoidScreenTest(void: VoidUI) : Screen(void) {
override fun build(): Component {
return TestComponent()
}
}

class TestComponent : ReactiveComponent() {
@State
public var testState = 5

override fun build(): Component {
println("Building TestComponent")
return this
}
}

object Tests {
@Test
fun testState() {
val renderer = MockRenderer()
val void = VoidUI(renderer)
val screen = VoidScreenTest(void)

val screen_component = screen.build()
val component = screen_component.build()
if (component is TestComponent) {
println("TestComponent.testState: ${component.testState}")
component.testState = 1
println("TestComponent.testState: ${component.testState}")
}

}
}

0 comments on commit 67d8870

Please sign in to comment.