Skip to content

Commit

Permalink
event system
Browse files Browse the repository at this point in the history
  • Loading branch information
Hobbyshop committed Apr 1, 2024
1 parent e5847fa commit 74274db
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/main/kotlin/com/neptuneclient/voidui/VoidUI.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.neptuneclient.voidui

import com.neptuneclient.voidui.event.EventHandler
import com.neptuneclient.voidui.rendering.Renderer
import com.neptuneclient.voidui.themes.Theme
import org.slf4j.Logger
Expand All @@ -19,6 +20,11 @@ class VoidUI
*/
constructor(val renderer: Renderer, var theme: Theme) {

/**
* The event handler which handles all events in the instance.
*/
val eventHandler = EventHandler()

companion object {
val LOGGER: Logger = LoggerFactory.getLogger("VoidUI")
}
Expand Down
17 changes: 17 additions & 0 deletions src/main/kotlin/com/neptuneclient/voidui/event/Event.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.neptuneclient.voidui.event

import com.neptuneclient.voidui.VoidUI

/**
* The base class for events in VoidUI.
*/
abstract class Event {

/**
* Calls the event.
*
* @param void The instance of VoidUI in which the event will be called.
*/
fun call(void: VoidUI) = void.eventHandler.eventCalled(this)

}
72 changes: 72 additions & 0 deletions src/main/kotlin/com/neptuneclient/voidui/event/EventHandler.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.neptuneclient.voidui.event

import kotlin.reflect.KClass

/**
* Handles all event calls of the library.
*/
class EventHandler {

/**
* A table of all actions which are registered.
*
* See [ActionRegistry] for more info.
*/
private val actions = mutableListOf<ActionRegistry>()

/**
* Register a new action.
*
* @param action The action which will be invoked at the event call.
* @param event The class of the event which will trigger the action.
* @param key An optional key which will identify an action when it gets unregistered, keys don't need to be unique but
* in case of a duplicate key all actions with this key will get unregistered.
*/
fun <T : Event> register(event: KClass<T>, key: Any? = null, action: (T) -> Unit) {
actions.add(ActionRegistry(action as (Event) -> Unit, event as KClass<Event>, key))
}

/**
* Invokes all actions which are registered with the provided event.
*/
fun eventCalled(event: Event) {
for ((action, eventClass, _) in actions) {
if (event::class != eventClass) continue
action(event)
}
}

/**
* Unregisters all actions with the provided key.
*/
fun unregister(key: Any) {
val indexCache = mutableListOf<Int>()

// fuck you ConcurrentModificationException
for ((index, data) in actions.withIndex()) {
if (key != data.key) continue
indexCache.add(index)
}

for (index in indexCache)
actions.removeAt(index)
}

/**
* Unregisters all actions.
*/
fun unregisterAll() {
actions.clear()
}

}

/**
* Stores information about an event action.
*
* @param action The action which will be invoked at the event call.
* @param event The class of the event which will trigger the action.
* @param key An optional key which will identify an action when it gets unregistered, keys don't need to be unique but
* in case of a duplicate key all actions with this key will get unregistered.
*/
private data class ActionRegistry(val action: (Event) -> Unit, val event: KClass<Event>, val key: Any?)
3 changes: 3 additions & 0 deletions src/main/kotlin/com/neptuneclient/voidui/event/events.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.neptuneclient.voidui.event

class TestEvent(val test: String) : Event()
5 changes: 5 additions & 0 deletions src/main/kotlin/com/neptuneclient/voidui/widgets/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ abstract class Screen
*/
constructor(val void: VoidUI) {

/**
* A shortcut to [VoidUI.eventHandler].
*/
protected val eventHandler = void.eventHandler

/**
* The size of the screen.
*/
Expand Down
1 change: 0 additions & 1 deletion src/main/kotlin/com/neptuneclient/voidui/widgets/Widget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.neptuneclient.voidui.widgets
import com.neptuneclient.voidui.widgets.objects.BoxConstraints
import com.neptuneclient.voidui.widgets.objects.Offset
import com.neptuneclient.voidui.widgets.objects.Size
import java.awt.Rectangle
import kotlin.math.round
import kotlin.properties.Delegates

Expand Down
10 changes: 10 additions & 0 deletions src/test/kotlin/com/neptuneclient/voidui/tests/ScreenTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package com.neptuneclient.voidui.tests

import com.neptuneclient.voidui.VoidUI
import com.neptuneclient.voidui.event.EventHandler
import com.neptuneclient.voidui.event.TestEvent
import com.neptuneclient.voidui.widgets.*
import com.neptuneclient.voidui.widgets.objects.EdgeInsets
import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable
Expand Down Expand Up @@ -54,13 +56,21 @@ class TestScreen(void: VoidUI) : Screen(void) {
val voidUI = VoidUI(TestRenderer(), TestTheme())

fun main() {
val handler = EventHandler()
handler.register(TestEvent::class, "ok") { // normally you would use `this` as a proper key
println(it.test)
}

val screen = TestScreen(voidUI)
screen.init()

val renderer = voidUI.renderer as TestRenderer
while (!GLFW.glfwWindowShouldClose(renderer.window)) {
screen.render()
TestEvent("lululu").call(voidUI)
}

handler.unregister("ok")

renderer.destroy()
}

0 comments on commit 74274db

Please sign in to comment.