aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin
diff options
context:
space:
mode:
authornea <romangraef@gmail.com>2022-09-10 03:48:03 +0200
committernea <romangraef@gmail.com>2022-09-10 03:48:03 +0200
commitec66c82198fe2d61d699d553c1254f08b43fcc65 (patch)
treeb5d4efaf5d6d6699357c3afb1d6920d89d51b3b8 /src/main/kotlin
parentd9353ff54c20a08e4e078e0190fc1f364b08a2d1 (diff)
downloadFirmament-ec66c82198fe2d61d699d553c1254f08b43fcc65.tar.gz
Firmament-ec66c82198fe2d61d699d553c1254f08b43fcc65.tar.bz2
Firmament-ec66c82198fe2d61d699d553c1254f08b43fcc65.zip
Move Eventhandling around.
I still want to use fabric still "array backed" events, but these here are just a bit easier to use from kotlin.
Diffstat (limited to 'src/main/kotlin')
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/NotEnoughUpdates.kt4
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/events/NEUEvent.kt7
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/events/NEUEventBus.kt26
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/events/NEUScreenEvents.kt23
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/events/ScreenOpenEvent.kt7
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/features/FeatureManager.kt36
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/features/NEUFeature.kt16
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/features/world/FairySouls.kt12
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/mixins/MixinMinecraft.kt9
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/repo/RepoDownloadManager.kt2
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/util/ConfigHolder.kt24
-rw-r--r--src/main/kotlin/moe/nea/notenoughupdates/util/MinecraftDispatcher.kt22
12 files changed, 146 insertions, 42 deletions
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/NotEnoughUpdates.kt b/src/main/kotlin/moe/nea/notenoughupdates/NotEnoughUpdates.kt
index 4868fbf..a2949a7 100644
--- a/src/main/kotlin/moe/nea/notenoughupdates/NotEnoughUpdates.kt
+++ b/src/main/kotlin/moe/nea/notenoughupdates/NotEnoughUpdates.kt
@@ -25,6 +25,7 @@ import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder
import java.nio.file.Files
import java.nio.file.Path
import kotlin.coroutines.EmptyCoroutineContext
+import moe.nea.notenoughupdates.features.FeatureManager
object NotEnoughUpdates : ModInitializer, ClientModInitializer {
const val MOD_ID = "notenoughupdates"
@@ -71,8 +72,9 @@ object NotEnoughUpdates : ModInitializer, ClientModInitializer {
override fun onInitialize() {
dbusConnection.requestBusName("moe.nea.notenoughupdates")
dbusConnection.exportObject(NEUDbusObject)
- RepoManager.initialize()
ConfigHolder.registerEvents()
+ RepoManager.initialize()
+ FeatureManager.autoload()
ClientCommandRegistrationCallback.EVENT.register(this::registerCommands)
ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
runBlocking {
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/events/NEUEvent.kt b/src/main/kotlin/moe/nea/notenoughupdates/events/NEUEvent.kt
new file mode 100644
index 0000000..278282e
--- /dev/null
+++ b/src/main/kotlin/moe/nea/notenoughupdates/events/NEUEvent.kt
@@ -0,0 +1,7 @@
+package moe.nea.notenoughupdates.events
+
+abstract class NEUEvent {
+ abstract class Cancellable : NEUEvent() {
+ var cancelled: Boolean = false
+ }
+}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/events/NEUEventBus.kt b/src/main/kotlin/moe/nea/notenoughupdates/events/NEUEventBus.kt
new file mode 100644
index 0000000..eba71bc
--- /dev/null
+++ b/src/main/kotlin/moe/nea/notenoughupdates/events/NEUEventBus.kt
@@ -0,0 +1,26 @@
+package moe.nea.notenoughupdates.events
+
+import java.util.concurrent.CopyOnWriteArrayList
+
+open class NEUEventBus<T : NEUEvent> {
+ data class Handler<T>(val invocation: (T) -> Unit, val receivesCancelled: Boolean)
+
+ private val toHandle: MutableList<Handler<T>> = CopyOnWriteArrayList()
+ fun subscribe(handle: (T) -> Unit) {
+ subscribe(handle, false)
+ }
+
+ fun subscribe(handle: (T) -> Unit, receivesCancelled: Boolean) {
+ toHandle.add(Handler(handle, receivesCancelled))
+ }
+
+ fun publish(event: T): T {
+ for (function in toHandle) {
+ if (function.receivesCancelled || event !is NEUEvent.Cancellable || !event.cancelled) {
+ function.invocation(event)
+ }
+ }
+ return event
+ }
+
+}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/events/NEUScreenEvents.kt b/src/main/kotlin/moe/nea/notenoughupdates/events/NEUScreenEvents.kt
deleted file mode 100644
index 64edda0..0000000
--- a/src/main/kotlin/moe/nea/notenoughupdates/events/NEUScreenEvents.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package moe.nea.notenoughupdates.events
-
-import moe.nea.notenoughupdates.events.NEUScreenEvents.OnScreenOpen
-import net.fabricmc.fabric.api.event.EventFactory
-import net.minecraft.client.gui.screen.Screen
-import net.minecraft.client.MinecraftClient
-
-object NEUScreenEvents {
- fun interface OnScreenOpen {
- /**
- * Called when a new Screen is opened via [MinecraftClient.setScreen]. If [new] is null, this corresponds to closing a [Screen].
- * @return true to prevent this event from happening.
- */
- fun onScreenOpen(old: Screen?, new: Screen?): Boolean
- }
-
- val SCREEN_OPEN = EventFactory.createArrayBacked(OnScreenOpen::class.java) { arr ->
- OnScreenOpen { old, new ->
- return@OnScreenOpen arr.asSequence().any { it.onScreenOpen(old, new) }
- }
- }
-
-}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/events/ScreenOpenEvent.kt b/src/main/kotlin/moe/nea/notenoughupdates/events/ScreenOpenEvent.kt
new file mode 100644
index 0000000..793f066
--- /dev/null
+++ b/src/main/kotlin/moe/nea/notenoughupdates/events/ScreenOpenEvent.kt
@@ -0,0 +1,7 @@
+package moe.nea.notenoughupdates.events
+
+import net.minecraft.client.gui.screen.Screen
+
+data class ScreenOpenEvent(val old: Screen?, val new: Screen?) : NEUEvent.Cancellable() {
+ companion object : NEUEventBus<ScreenOpenEvent>()
+}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/features/FeatureManager.kt b/src/main/kotlin/moe/nea/notenoughupdates/features/FeatureManager.kt
new file mode 100644
index 0000000..766cf1f
--- /dev/null
+++ b/src/main/kotlin/moe/nea/notenoughupdates/features/FeatureManager.kt
@@ -0,0 +1,36 @@
+package moe.nea.notenoughupdates.features
+
+import kotlinx.serialization.serializer
+import moe.nea.notenoughupdates.NotEnoughUpdates
+import moe.nea.notenoughupdates.features.world.FairySouls
+import moe.nea.notenoughupdates.util.ConfigHolder
+
+object FeatureManager : ConfigHolder<FeatureManager.Config>(serializer(), "features", ::Config) {
+ data class Config(
+ val enabledFeatures: MutableMap<String, Boolean> = mutableMapOf()
+ )
+
+ private val features = mutableMapOf<String, NEUFeature>()
+
+ fun autoload() {
+ loadFeature(FairySouls)
+ }
+
+ fun loadFeature(feature: NEUFeature) {
+ if (feature.identifier in features) {
+ NotEnoughUpdates.logger.error("Double registering feature ${feature.identifier}. Ignoring second instance $feature")
+ return
+ }
+ features[feature.identifier] = feature
+ }
+
+ fun isEnabled(identifier: String): Boolean? =
+ config.enabledFeatures[identifier]
+
+
+ fun setEnabled(identifier: String, value: Boolean) {
+ config.enabledFeatures[identifier] = value
+ markDirty()
+ }
+
+}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/features/NEUFeature.kt b/src/main/kotlin/moe/nea/notenoughupdates/features/NEUFeature.kt
new file mode 100644
index 0000000..1d3628e
--- /dev/null
+++ b/src/main/kotlin/moe/nea/notenoughupdates/features/NEUFeature.kt
@@ -0,0 +1,16 @@
+package moe.nea.notenoughupdates.features
+
+interface NEUFeature {
+ val name: String
+ val identifier: String
+ val defaultEnabled: Boolean
+ get() = true
+ var isEnabled: Boolean
+ get() = FeatureManager.isEnabled(identifier) ?: defaultEnabled
+ set(value) {
+ FeatureManager.setEnabled(identifier, value)
+ }
+
+ fun onLoad()
+
+}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/features/world/FairySouls.kt b/src/main/kotlin/moe/nea/notenoughupdates/features/world/FairySouls.kt
new file mode 100644
index 0000000..b928f3d
--- /dev/null
+++ b/src/main/kotlin/moe/nea/notenoughupdates/features/world/FairySouls.kt
@@ -0,0 +1,12 @@
+package moe.nea.notenoughupdates.features.world
+
+import moe.nea.notenoughupdates.features.NEUFeature
+
+object FairySouls : NEUFeature {
+ override val name: String get() = "Fairy Souls"
+ override val identifier: String get() = "fairy-souls"
+
+ override fun onLoad() {
+
+ }
+}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/mixins/MixinMinecraft.kt b/src/main/kotlin/moe/nea/notenoughupdates/mixins/MixinMinecraft.kt
index 21834e9..3bc1a5f 100644
--- a/src/main/kotlin/moe/nea/notenoughupdates/mixins/MixinMinecraft.kt
+++ b/src/main/kotlin/moe/nea/notenoughupdates/mixins/MixinMinecraft.kt
@@ -1,19 +1,20 @@
package moe.nea.notenoughupdates.mixins
-import moe.nea.notenoughupdates.events.NEUScreenEvents
-import net.minecraft.client.MinecraftClient
-import net.minecraft.client.gui.screen.Screen
import org.spongepowered.asm.mixin.Mixin
import org.spongepowered.asm.mixin.injection.At
import org.spongepowered.asm.mixin.injection.Inject
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo
+import net.minecraft.client.MinecraftClient
+import net.minecraft.client.gui.screen.Screen
+import moe.nea.notenoughupdates.events.ScreenOpenEvent
@Suppress("CAST_NEVER_SUCCEEDS")
@Mixin(MinecraftClient::class)
class MixinMinecraft {
@Inject(method = ["setScreen"], at = [At("HEAD")], cancellable = true)
fun onScreenChange(screen: Screen?, ci: CallbackInfo) {
- if (NEUScreenEvents.SCREEN_OPEN.invoker().onScreenOpen((this as MinecraftClient).currentScreen, screen))
+ val event = ScreenOpenEvent((this as MinecraftClient).currentScreen, screen)
+ if (ScreenOpenEvent.publish(event).cancelled)
ci.cancel()
}
}
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoDownloadManager.kt b/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoDownloadManager.kt
index c354392..2d700c1 100644
--- a/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoDownloadManager.kt
+++ b/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoDownloadManager.kt
@@ -76,7 +76,7 @@ object RepoDownloadManager {
return@withContext false
}
val currentSha = loadSavedVersionHash()
- if (latestSha != currentSha) {
+ if (latestSha != currentSha || force) {
val requestUrl = "https://github.com/${RepoManager.config.user}/${RepoManager.config.repo}/archive/$latestSha.zip"
logger.info("Planning to upgrade repository from $currentSha to $latestSha from $requestUrl")
val zipFile = downloadGithubArchive(requestUrl)
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/ConfigHolder.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/ConfigHolder.kt
index 7827708..50a3d9b 100644
--- a/src/main/kotlin/moe/nea/notenoughupdates/util/ConfigHolder.kt
+++ b/src/main/kotlin/moe/nea/notenoughupdates/util/ConfigHolder.kt
@@ -1,21 +1,20 @@
package moe.nea.notenoughupdates.util
-import kotlinx.serialization.KSerializer
-import kotlinx.serialization.SerializationException
-import moe.nea.notenoughupdates.NotEnoughUpdates
-import moe.nea.notenoughupdates.events.NEUScreenEvents
-import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
-import net.minecraft.client.MinecraftClient
-import net.minecraft.command.CommandSource
-import net.minecraft.server.command.CommandOutput
-import net.minecraft.text.Text
import java.io.IOException
import java.nio.file.Path
import java.util.concurrent.CopyOnWriteArrayList
+import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.SerializationException
import kotlin.io.path.exists
import kotlin.io.path.readText
import kotlin.io.path.writeText
import kotlin.reflect.KClass
+import net.minecraft.client.MinecraftClient
+import net.minecraft.server.command.CommandOutput
+import net.minecraft.text.Text
+import moe.nea.notenoughupdates.NotEnoughUpdates
+import moe.nea.notenoughupdates.events.ScreenOpenEvent
abstract class ConfigHolder<T>(
val serializer: KSerializer<T>,
@@ -108,7 +107,7 @@ abstract class ConfigHolder<T>(
player.sendMessage(
Text.literal(
"The following configs have been reset: ${badLoads.joinToString(", ")}. " +
- "This can be intentional, but probably isn't."
+ "This can be intentional, but probably isn't."
)
)
badLoads.clear()
@@ -116,14 +115,13 @@ abstract class ConfigHolder<T>(
}
fun registerEvents() {
- NEUScreenEvents.SCREEN_OPEN.register(NEUScreenEvents.OnScreenOpen { old, new ->
+ ScreenOpenEvent.subscribe { event ->
performSaves()
val p = MinecraftClient.getInstance().player
if (p != null) {
warnForResetConfigs(p)
}
- false
- })
+ }
ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
performSaves()
})
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/MinecraftDispatcher.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/MinecraftDispatcher.kt
new file mode 100644
index 0000000..366b81a
--- /dev/null
+++ b/src/main/kotlin/moe/nea/notenoughupdates/util/MinecraftDispatcher.kt
@@ -0,0 +1,22 @@
+package moe.nea.notenoughupdates.util
+
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Runnable
+import kotlin.coroutines.CoroutineContext
+import net.minecraft.client.MinecraftClient
+
+object MinecraftDispatcher : CoroutineDispatcher() {
+ @ExperimentalCoroutinesApi
+ override fun limitedParallelism(parallelism: Int): CoroutineDispatcher {
+ throw UnsupportedOperationException("limitedParallelism is not supported for MinecraftDispatcher")
+ }
+
+ override fun isDispatchNeeded(context: CoroutineContext): Boolean =
+ !MinecraftClient.getInstance().isOnThread
+
+
+ override fun dispatch(context: CoroutineContext, block: Runnable) {
+ MinecraftClient.getInstance().execute(block)
+ }
+}