From 9c7796d51272214a786510edd261c55eaa3d5868 Mon Sep 17 00:00:00 2001
From: grng <36968271+grngxd@users.noreply.github.com>
Date: Thu, 7 Mar 2024 19:45:08 +0000
Subject: [PATCH 1/2] class based state
---
.idea/discord.xml | 7 +++
.../com/neptuneclient/voidui/event/Event.kt | 7 +++
.../voidui/event/EventManager.kt | 47 +++++++++++++++++++
.../neptuneclient/voidui/event/Subscribe.kt | 14 ++++++
.../voidui/event/impl/StateChangeEvent.kt | 8 ++++
.../com/neptuneclient/voidui/ui/Component.kt | 1 -
.../voidui/ui/ReactiveComponent.kt | 22 +++++++++
.../com/neptuneclient/voidui/ui/State.kt | 26 ++++++++++
.../testmod/mixins/TitleScreenMixin.java | 22 +++++++++
.../voidui/testmod/mixins/void/Label.kt | 23 +++++++++
10 files changed, 176 insertions(+), 1 deletion(-)
create mode 100644 .idea/discord.xml
create mode 100644 src/main/kotlin/com/neptuneclient/voidui/event/Event.kt
create mode 100644 src/main/kotlin/com/neptuneclient/voidui/event/EventManager.kt
create mode 100644 src/main/kotlin/com/neptuneclient/voidui/event/Subscribe.kt
create mode 100644 src/main/kotlin/com/neptuneclient/voidui/event/impl/StateChangeEvent.kt
create mode 100644 src/main/kotlin/com/neptuneclient/voidui/ui/State.kt
create mode 100644 test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/TitleScreenMixin.java
create mode 100644 test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt
diff --git a/.idea/discord.xml b/.idea/discord.xml
new file mode 100644
index 0000000..d8e9561
--- /dev/null
+++ b/.idea/discord.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/event/Event.kt b/src/main/kotlin/com/neptuneclient/voidui/event/Event.kt
new file mode 100644
index 0000000..fac088e
--- /dev/null
+++ b/src/main/kotlin/com/neptuneclient/voidui/event/Event.kt
@@ -0,0 +1,7 @@
+package com.neptuneclient.voidui.event
+
+/**
+ * @author refactoring
+ * @date 01-09-2023
+ */
+open class Event()
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/event/EventManager.kt b/src/main/kotlin/com/neptuneclient/voidui/event/EventManager.kt
new file mode 100644
index 0000000..ac7c6ec
--- /dev/null
+++ b/src/main/kotlin/com/neptuneclient/voidui/event/EventManager.kt
@@ -0,0 +1,47 @@
+package com.neptuneclient.voidui.event
+
+import java.lang.reflect.InvocationTargetException
+
+
+/**
+ * @author refactoring
+ * @date 01-09-2023
+ */
+class EventManager {
+ var targetClasses: MutableMap, Any> = HashMap()
+ fun register(`object`: Any) {
+ if (targetClasses.containsKey(`object`.javaClass)) return
+ targetClasses[`object`.javaClass] = `object`
+ }
+
+ fun unregister(`object`: Any) {
+ targetClasses.remove(`object`.javaClass)
+ }
+
+ fun clearTargets() {
+ targetClasses.clear()
+ }
+
+ fun fire(event: Event) {
+ targetClasses.forEach { (clazz: Class<*>, `object`: Any?) ->
+ for (method in clazz.getDeclaredMethods()) {
+ if (method.isAnnotationPresent(Subscribe::class.java) && method.getAnnotation(
+ Subscribe::class.java
+ ).target == event.javaClass
+ ) {
+ try {
+ method.invoke(`object`, event)
+ } catch (e: IllegalAccessException) {
+ throw RuntimeException(e)
+ } catch (e: InvocationTargetException) {
+ throw RuntimeException(e)
+ }
+ }
+ }
+ }
+ }
+
+ companion object {
+ val instance = EventManager()
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/event/Subscribe.kt b/src/main/kotlin/com/neptuneclient/voidui/event/Subscribe.kt
new file mode 100644
index 0000000..89f3d39
--- /dev/null
+++ b/src/main/kotlin/com/neptuneclient/voidui/event/Subscribe.kt
@@ -0,0 +1,14 @@
+package com.neptuneclient.voidui.event
+
+import kotlin.reflect.KClass
+
+
+/**
+ * @author refactoring
+ * @date 01-09-2023
+ */
+@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
+@Retention(
+ AnnotationRetention.RUNTIME
+)
+annotation class Subscribe(val target: KClass<*>)
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/event/impl/StateChangeEvent.kt b/src/main/kotlin/com/neptuneclient/voidui/event/impl/StateChangeEvent.kt
new file mode 100644
index 0000000..27f82a3
--- /dev/null
+++ b/src/main/kotlin/com/neptuneclient/voidui/event/impl/StateChangeEvent.kt
@@ -0,0 +1,8 @@
+package com.neptuneclient.voidui.event.impl
+
+import com.neptuneclient.voidui.event.Event
+import com.neptuneclient.voidui.ui.State
+
+class StateChangeEvent(state: State) : Event() {
+ var state: State = state
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt
index 5ce6bdf..1bb5a1c 100644
--- a/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt
+++ b/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt
@@ -1,7 +1,6 @@
package com.neptuneclient.voidui.ui
sealed class Component {
-
abstract fun build(): Component
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt
index ca9dc64..fee4d22 100644
--- a/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt
+++ b/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt
@@ -1,4 +1,26 @@
package com.neptuneclient.voidui.ui
+import com.neptuneclient.voidui.event.EventManager
+import com.neptuneclient.voidui.event.Subscribe
+import com.neptuneclient.voidui.event.impl.StateChangeEvent
+
abstract class ReactiveComponent : Component() {
+ // array of states
+ var state: HashMap> = hashMapOf()
+ // call function on state change
+ open fun init() {
+ EventManager.instance.register(this)
+
+ for (s in state) {
+ s.value.init()
+ }
+ }
+ override fun build(): Component {
+ return this
+ }
+
+ @Subscribe(target = StateChangeEvent::class)
+ fun onStateChange(event: StateChangeEvent<*>) {
+ println("State changed from ${event.state.prev} to ${event.state.value}")
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/State.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/State.kt
new file mode 100644
index 0000000..dd6fe59
--- /dev/null
+++ b/src/main/kotlin/com/neptuneclient/voidui/ui/State.kt
@@ -0,0 +1,26 @@
+package com.neptuneclient.voidui.ui
+
+import com.neptuneclient.voidui.event.EventManager
+import com.neptuneclient.voidui.event.impl.StateChangeEvent
+
+class State (initial: T) {
+ // make the setter like react
+ var value: T = initial
+ set(value) {
+ field = value
+ changed()
+ }
+
+ var prev: T = initial
+ fun init() {
+ EventManager.instance.register(this)
+ println("State initialized")
+ }
+
+ fun changed() {
+ EventManager.instance.fire(
+ StateChangeEvent(this)
+ )
+ prev = this.value
+ }
+}
\ No newline at end of file
diff --git a/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/TitleScreenMixin.java b/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/TitleScreenMixin.java
new file mode 100644
index 0000000..826a6a4
--- /dev/null
+++ b/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/TitleScreenMixin.java
@@ -0,0 +1,22 @@
+package com.neptuneclient.voidui.testmod.mixins;
+
+import com.neptuneclient.voidui.VoidUI;
+import com.neptuneclient.voidui.ui.Screen;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.TitleScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Overwrite;
+
+@Mixin(TitleScreen.class)
+public class TitleScreenMixin {
+ VoidUI voidUI = new VoidUI();
+ /**
+ * @author
+ * @reason
+ */
+ @Overwrite
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ voidUI.setCurrentScreen((Screen) (Object) this);
+
+ }
+}
diff --git a/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt b/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt
new file mode 100644
index 0000000..876eb4a
--- /dev/null
+++ b/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt
@@ -0,0 +1,23 @@
+package com.neptuneclient.voidui.testmod.mixins.void
+
+import com.neptuneclient.voidui.ui.Component
+import com.neptuneclient.voidui.ui.ReactiveComponent
+import com.neptuneclient.voidui.ui.State
+
+class Label: ReactiveComponent() {
+ override fun init() {
+ super.init()
+
+ state = hashMapOf(
+ "number" to State(0)
+ )
+ }
+ override fun build(): Component {
+ // wait 4 seconds
+ Thread(Runnable {
+ Thread.sleep(4000)
+ this.state["number"]?.value = 1
+ })
+ return super.build()
+ }
+}
\ No newline at end of file
From f8dfc2420f12c906c26a69315a5dd16bb37ce71a Mon Sep 17 00:00:00 2001
From: grng <36968271+grngxd@users.noreply.github.com>
Date: Thu, 7 Mar 2024 20:09:17 +0000
Subject: [PATCH 2/2] shitty state
---
.../kotlin/com/neptuneclient/voidui/VoidUI.kt | 1 -
.../voidui/ui/ReactiveComponent.kt | 28 ++++++++++++++-----
.../com/neptuneclient/voidui/ui/State.kt | 10 +++++--
.../voidui/testmod/mixins/void/Label.kt | 25 ++++++++---------
4 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/src/main/kotlin/com/neptuneclient/voidui/VoidUI.kt b/src/main/kotlin/com/neptuneclient/voidui/VoidUI.kt
index 135b637..d88eeed 100644
--- a/src/main/kotlin/com/neptuneclient/voidui/VoidUI.kt
+++ b/src/main/kotlin/com/neptuneclient/voidui/VoidUI.kt
@@ -7,5 +7,4 @@ class VoidUI {
var currentScreen: Screen? = null
fun complexFunction(x: Int, y: Int) = x + y
-
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt
index fee4d22..6e3c97c 100644
--- a/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt
+++ b/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt
@@ -5,20 +5,34 @@ import com.neptuneclient.voidui.event.Subscribe
import com.neptuneclient.voidui.event.impl.StateChangeEvent
abstract class ReactiveComponent : Component() {
- // array of states
- var state: HashMap> = hashMapOf()
- // call function on state change
- open fun init() {
- EventManager.instance.register(this)
+ val states = mutableListOf>()
- for (s in state) {
- s.value.init()
+ init {
+ EventManager.instance.register(this)
+ for (field in this.javaClass.declaredFields) {
+ if (field.type == State::class.java) {
+ field.isAccessible = true
+ val state = field.get(this) as State<*>
+ state.init()
+ states.add(state)
+ state.subscribe { newValue ->
+ // Here you can react to changes in the state.
+ // For example, you can rebuild the component.
+ rebuild()
+ }
+ }
}
}
+
override fun build(): Component {
return this
}
+ open fun rebuild() {
+ // This method is called when a state changes.
+ // You can override it to rebuild the component.
+ }
+
@Subscribe(target = StateChangeEvent::class)
fun onStateChange(event: StateChangeEvent<*>) {
println("State changed from ${event.state.prev} to ${event.state.value}")
diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/State.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/State.kt
index dd6fe59..cf87647 100644
--- a/src/main/kotlin/com/neptuneclient/voidui/ui/State.kt
+++ b/src/main/kotlin/com/neptuneclient/voidui/ui/State.kt
@@ -3,8 +3,7 @@ package com.neptuneclient.voidui.ui
import com.neptuneclient.voidui.event.EventManager
import com.neptuneclient.voidui.event.impl.StateChangeEvent
-class State (initial: T) {
- // make the setter like react
+class State(initial: T) {
var value: T = initial
set(value) {
field = value
@@ -12,6 +11,8 @@ class State (initial: T) {
}
var prev: T = initial
+ private val listeners = mutableListOf<(T) -> Unit>()
+
fun init() {
EventManager.instance.register(this)
println("State initialized")
@@ -22,5 +23,10 @@ class State (initial: T) {
StateChangeEvent(this)
)
prev = this.value
+ listeners.forEach { it(value) } // Notify all listeners about the change
+ }
+
+ fun subscribe(listener: (T) -> Unit) {
+ listeners.add(listener)
}
}
\ No newline at end of file
diff --git a/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt b/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt
index 876eb4a..ca1ba4e 100644
--- a/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt
+++ b/test-mod/src/main/kotlin/com/neptuneclient/voidui/testmod/mixins/void/Label.kt
@@ -1,23 +1,20 @@
package com.neptuneclient.voidui.testmod.mixins.void
-import com.neptuneclient.voidui.ui.Component
import com.neptuneclient.voidui.ui.ReactiveComponent
import com.neptuneclient.voidui.ui.State
-class Label: ReactiveComponent() {
- override fun init() {
- super.init()
+class Label(initialText: String) : ReactiveComponent() {
+ val text = State(initialText)
- state = hashMapOf(
- "number" to State(0)
- )
+ init {
+ text.subscribe {
+ rebuild()
+ }
}
- override fun build(): Component {
- // wait 4 seconds
- Thread(Runnable {
- Thread.sleep(4000)
- this.state["number"]?.value = 1
- })
- return super.build()
+
+ override fun rebuild() {
+ // Logic to update the UI goes here.
+ // This might involve re-rendering the component's UI, updating its data, etc.
+ println("Current text: ${text.value}")
}
}
\ No newline at end of file