Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,6 @@ val firmamentRelocatedConfiguration: Configuration by configurations.creating {
attributes { attribute(firmamentRelocated, true) }
}

val dandelionBpRelocated = registerRelocationAttribute("relocate-dandelion-bp-moulconfig") {
relocate("io.github.notenoughupdates.moulconfig", "net.azureaaron.dandelion_bp.deps.moulconfig")
}

val dandelionBpRelocatedConfiguration: Configuration by configurations.creating {
attributes { attribute(dandelionBpRelocated, true) }
}

dependencies {
listOf("compat", "common-compat").forEach {
versionedCatalog.bundles.getOrNull(it)?.let { bundle ->
Expand All @@ -205,7 +197,7 @@ dependencies {
}
}

moulConfig(skyhanniRelocatedConfiguration, firmamentRelocatedConfiguration, dandelionBpRelocatedConfiguration)
moulConfig(skyhanniRelocatedConfiguration, firmamentRelocatedConfiguration)

"api"(versionedCatalog["jetbrains.compose.foundation"])
"api"(versionedCatalog["jetbrains.compose.material"])
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ log4j-api = "2.0-beta9" # used because this is the version that 1.8.9 supports,
# Compose
compose = "1.12.0-alpha01"
compose-navigation = "2.10.0-alpha01"
skiko = "0.999.4"
skiko = "0.999.5"

lifecycle = "2.11.0-beta01"
viewmodel = "2.11.0-beta01"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
import org.polyfrost.oneconfig.internal.ui.compose.SkiaCtx;

public class ScreenPlatformImpl implements ScreenPlatform {
@Override
public void runOnUiThread(Runnable action) {
Minecraft minecraft = Minecraft.getInstance();
if (minecraft == null || minecraft.isSameThread()) action.run();
else minecraft.execute(action);
}

@Override
public int viewportWidth() {
return Minecraft.getInstance().getWindow().getWidth();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.polyfrost.oneconfig.api.event.v1.events.InitializationEvent;
import org.polyfrost.oneconfig.api.event.v1.events.ResourceFinishedLoading;
import org.polyfrost.oneconfig.api.event.v1.events.ScreenOpenEvent;
import org.polyfrost.oneconfig.api.event.v1.events.ShutdownEvent;
import org.polyfrost.oneconfig.api.event.v1.events.WorldEvent;
import org.polyfrost.oneconfig.api.hud.v1.HudManager;
import org.polyfrost.oneconfig.api.hud.v1.events.HudEditorToggleEvent;
Expand All @@ -68,6 +69,7 @@
import org.polyfrost.oneconfig.internal.ui.hud.LegacyHudRenderer;
import org.polyfrost.oneconfig.internal.ui.keybind.KeybindProviderRegistry;
import org.polyfrost.oneconfig.internal.ui.keybind.MinecraftKeybindProvider;
import org.polyfrost.oneconfig.internal.ui.keybind.MinecraftKeybindProfiles;
import org.polyfrost.oneconfig.internal.ui.keybind.RightShiftConflicts;
import org.polyfrost.oneconfig.internal.ui.search.SearchCorpus;
import org.polyfrost.oneconfig.test.TestMod_Test;
Expand Down Expand Up @@ -217,7 +219,15 @@ private static void installNotificationRenderer() {
}

private static void registerEventHandlers() {
EventManager.register(InitializationEvent.class, e -> HudManager.INSTANCE.initialize());
EventManager.register(ShutdownEvent.class, e -> MinecraftKeybindProfiles.shutdown());
EventManager.register(InitializationEvent.class, e -> {
HudManager.INSTANCE.setProfileReloadDispatcher(r -> {
Minecraft mc = Minecraft.getInstance();
if (mc != null && !mc.isSameThread()) mc.execute(r);
else r.run();
});
HudManager.INSTANCE.initialize();
});
EventManager.register(
HudEditorToggleEvent.class, e -> {
if (e.open) {
Expand All @@ -244,10 +254,10 @@ private static void registerEventHandlers() {
RightShiftConflicts.unbindMinecraftKeybinds();
org.polyfrost.oneconfig.api.config.v1.CompatSnapshots.setDispatcher(r -> {
net.minecraft.client.Minecraft mc = net.minecraft.client.Minecraft.getInstance();
if (mc != null) mc.execute(r);
if (mc != null && !mc.isSameThread()) mc.execute(r);
else r.run();
});
org.polyfrost.oneconfig.internal.ui.keybind.MinecraftKeybindProfiles.init();
MinecraftKeybindProfiles.init();
ConfigRegistry.INSTANCE.loadFrom(ConfigManager.active(), ConfigSource.OC);
org.polyfrost.oneconfig.internal.ui.hud.BuiltinHudRegistrar.register();
org.polyfrost.oneconfig.internal.compat.FirmamentHudCompat.register();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ public List<String> getMixins() {
//? }
//? moul_compat {
mixins.add("compat.moulconfig.Mixin_MCConfigEditorIntegration_Firmament");
mixins.add("compat.moulconfig.Mixin_MoulConfigAdapter_DandelionBp");
//? }

//? dandelion_compat
Expand Down Expand Up @@ -175,6 +174,7 @@ public List<String> getMixins() {

mixins.add("keybind.Mixin_OneConfigKeybindRebind");
mixins.add("keybind.Mixin_KeyMappingResetDetect");
mixins.add("keybind.Mixin_OptionsSaveDetect");

//? cinnabar
//mixins.add("skia.Mixin_CinnabarSkiaFlush");
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.polyfrost.oneconfig.internal.mixin.keybind;

import net.minecraft.client.Options;
import org.polyfrost.oneconfig.internal.ui.keybind.MinecraftKeybindProfiles;
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;

@Mixin(Options.class)
public class Mixin_OptionsSaveDetect {
@Inject(method = "save", at = @At("RETURN"))
private void oneconfig$captureSavedControls(CallbackInfo ci) {
MinecraftKeybindProfiles.onOptionsSaved();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ package org.polyfrost.oneconfig.internal.compat

import org.polyfrost.oneconfig.api.event.v1.EventManager
import org.polyfrost.oneconfig.api.event.v1.events.Event
import org.polyfrost.oneconfig.api.event.v1.events.FramebufferRenderEvent
import org.polyfrost.oneconfig.api.event.v1.events.ResourceFinishedLoading
import org.polyfrost.oneconfig.api.platform.v1.ModInfo
import org.polyfrost.oneconfig.api.platform.v1.Platform
import org.polyfrost.oneconfig.internal.ui.compose.SkiaCtx
import org.polyfrost.oneconfig.internal.ui.compose.opengl.resyncTextureBindCache
import java.net.URI
import java.util.Optional
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedDeque
import java.util.concurrent.atomic.AtomicBoolean

object CompatLoader {
private val LOGGER = org.apache.logging.log4j.LogManager.getLogger("OneConfig/Compat")

private val forcedModId = ThreadLocal<String?>()

private var bypassDelay = false
Expand Down Expand Up @@ -121,6 +128,21 @@ object CompatLoader {
}
}

private val screenWarmups = ConcurrentLinkedDeque<() -> Unit>()
private val screenWarmupScheduled = AtomicBoolean(false)

fun queueScreenWarmup(block: () -> Unit) {
screenWarmups.add(block)
if (!screenWarmupScheduled.compareAndSet(false, true)) return
EventManager.register(FramebufferRenderEvent.End::class.java) { _ -> runNextScreenWarmup() }
}

private fun runNextScreenWarmup() {
val warmup = screenWarmups.poll() ?: return
if (!SkiaCtx.isVulkanMode) runCatching { resyncTextureBindCache() }
runCatching { warmup() }.onFailure { LOGGER.warn("Config screen warmup failed", it) }
}

private val list: MutableList<Pair<Int, () -> Unit>> = mutableListOf()

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ object DandelionCompat {
)

property.addMetadata("searchTags", option.tags())
(defaultValue as Any?)?.let { property.addMetadata("default", it) }
property.category = category
property.subcategory = subcategory
property.addDisplayCondition { if (option.modifiable()) Display.SHOWN else Display.DISABLED }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,15 @@ import org.polyfrost.oneconfig.api.config.v1.CompatSnapshots
import org.polyfrost.oneconfig.api.config.v1.ConfigManager
import org.polyfrost.oneconfig.api.config.v1.Tree
import org.polyfrost.oneconfig.api.config.v1.backend.Backend
import org.polyfrost.oneconfig.api.event.v1.EventManager
import org.polyfrost.oneconfig.api.event.v1.events.FramebufferRenderEvent
import org.polyfrost.oneconfig.api.platform.v1.ModInfo
import org.polyfrost.oneconfig.api.platform.v1.Platform
import org.polyfrost.oneconfig.internal.ui.api.ConfigRegistry
import org.polyfrost.oneconfig.internal.ui.api.ConfigSource
import org.polyfrost.oneconfig.internal.ui.compose.impls.OneConfigUIScreen
import org.polyfrost.oneconfig.internal.ui.navigation.graph.ModConfigRoute
import org.polyfrost.oneconfig.internal.ui.shell.LocalNavController
import java.util.concurrent.ConcurrentLinkedDeque
import java.util.concurrent.atomic.AtomicBoolean

object ModMenuCompat {
private val LOGGER = org.apache.logging.log4j.LogManager.getLogger("OneConfig/ModMenu-Compat")

val mods: MutableList<Mod> = mutableListOf()

private val ownModIds = setOf(
Expand Down Expand Up @@ -118,27 +112,14 @@ object ModMenuCompat {
scheduleWarmup(foundMods)
}

// Some compat layers can only load when a config UI is opened,
// this has to be done when the render thread is available.
// Do this one per frame to prevent a huge lag spike
private val warmupQueue = ConcurrentLinkedDeque<Mod>()
private val warmupScheduled = AtomicBoolean(false)

private fun scheduleWarmup(mods: List<Mod>) {
if (mods.isEmpty()) return
warmupQueue.addAll(mods)
if (!warmupScheduled.compareAndSet(false, true)) return
EventManager.register(FramebufferRenderEvent.End::class.java) { _ -> warmupNext() }
}

private fun warmupNext() {
val mod = warmupQueue.poll() ?: return
runCatching {
CompatLoader.withForcedModId(mod.id) {
// The screen is thrown away; building it is what makes the compat mixins fire.
ModMenu.getConfigScreen(mod.id, Platform.screen().current())
mods.forEach { mod ->
CompatLoader.queueScreenWarmup {
CompatLoader.withForcedModId(mod.id) {
ModMenu.getConfigScreen(mod.id, Platform.screen().current())
}
}
}.onFailure { LOGGER.warn("Failed to warm up config screen for '{}'", mod.id, it) }
}
}

// A mod can ship BOTH a native OneConfig config and a Mod Menu entrypoint. The native config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,18 @@ data object MoulConfigCompat {
}

is GuiOptionEditorColour -> {
property.getter = {
fun toArgb(value: Any?): Int? {
val colour = when (children.type) {
String::class.java -> ChromaColour.forLegacyString(children.get() as String)
ChromaColour::class.java -> children.get() as ChromaColour
String::class.java -> (value as? String)?.let { ChromaColour.forLegacyString(it) }
ChromaColour::class.java -> value as? ChromaColour
else -> null
}
colour?.let {
val rgb = Color.HSBtoRGB(it.hue, it.saturation, it.brightness)
(it.alpha shl 24) or (rgb and 0x00FFFFFF)
} ?: 0xFFFFFFFF.toInt()
} ?: return null
val rgb = Color.HSBtoRGB(colour.hue, colour.saturation, colour.brightness)
return (colour.alpha shl 24) or (rgb and 0x00FFFFFF)
}

property.getter = { toArgb(children.get()) ?: 0xFFFFFFFF.toInt() }
property.defaultMapper = ::toArgb
property.setter = setter@{
val argb = it as? Int ?: return@setter
val awtColor = Color(argb, true)
Expand All @@ -191,8 +192,8 @@ data object MoulConfigCompat {
}

is MoulConfigGuiOptionEditorDropdownAccessor -> {
fun getIndex(): Int {
val selectedObject: Any = children.get() ?: return -1
fun indexOf(selectedObject: Any?): Int {
if (selectedObject == null) return -1

return if (editor.`oneconfig$useOrdinal`()) {
selectedObject as Int
Expand All @@ -203,6 +204,8 @@ data object MoulConfigCompat {
}
}

fun getIndex(): Int = indexOf(children.get())

fun setIndex(index: Int) {
if (editor.`oneconfig$constants`() != null) {
children.set(editor.`oneconfig$constants`()[index])
Expand All @@ -214,6 +217,7 @@ data object MoulConfigCompat {
}

property.getter = ::getIndex
property.defaultMapper = { indexOf(it).takeIf { index -> index >= 0 } }
property.setter = setter@{
val index = it as? Int ?: return@setter
setIndex(index)
Expand All @@ -229,6 +233,7 @@ data object MoulConfigCompat {
property.metadata["min"] = editor.`oneconfig$minValue`
property.metadata["max"] = editor.`oneconfig$maxValue`
property.getter = { (children.get() as? Number)?.toFloat() ?: editor.`oneconfig$maxValue` }
property.defaultMapper = { (it as? Number)?.toFloat() }
property.setter = setter@{ value ->
val numberValue = value as? Number ?: return@setter
fun isAny(type: Type, numberType: KClass<out Number>): Boolean {
Expand All @@ -253,14 +258,14 @@ data object MoulConfigCompat {
// MoulConfig stores a keybind as a single int GLFW key code on an int/Integer property; a code <= 0
// (GLFW_KEY_UNKNOWN / "none") means unbound. Bridge it to OneConfig's OneConfigKeybind, which carries
// an array of key codes. The action is a no-op stub since MoulConfig owns the actual bind firing.
property.getter = {
val code = (children.get() as? Number)?.toInt() ?: KeyboardConstants.none
if (code <= 0) {
OneConfigKeybind(null, null, KeyModifiers.NONE, 0L) { true }
} else {
OneConfigKeybind(intArrayOf(code), null, KeyModifiers.NONE, 0L) { true }
}
fun keybindOf(code: Int) = if (code <= 0) {
OneConfigKeybind(null, null, KeyModifiers.NONE, 0L) { true }
} else {
OneConfigKeybind(intArrayOf(code), null, KeyModifiers.NONE, 0L) { true }
}

property.getter = { keybindOf((children.get() as? Number)?.toInt() ?: KeyboardConstants.none) }
property.defaultMapper = { value -> (value as? Number)?.toInt()?.let(::keybindOf) }
property.setter = setter@{ value ->
val keybind = value as? OneConfigKeybind ?: return@setter
val code = keybind.keyCodes?.firstOrNull()
Expand Down
Loading
Loading