diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt index 029885d0f..b75861628 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt @@ -57,6 +57,7 @@ object LegacyHudRenderer { for (hud in frame) { try { HudManager.updateIfDue(hud) + if (!HudManager.isEditing && !hud.shouldShow()) continue val hudScale = hud.effectiveScale val (mw, mh) = hud.frameMinimumSize() val w = mw * hudScale diff --git a/modules/hud/api/hud.api b/modules/hud/api/hud.api index 23db92aac..78ece35c9 100644 --- a/modules/hud/api/hud.api +++ b/modules/hud/api/hud.api @@ -195,6 +195,7 @@ public abstract class org/polyfrost/oneconfig/api/hud/v1/Hud : org/polyfrost/one public fun setX (F)V public fun setY (F)V public fun setup ()V + public fun shouldShow ()Z public fun showByDefault ()Z public abstract fun update ()Z public final fun updateAndRecalculate ()V diff --git a/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/Hud.kt b/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/Hud.kt index 2f1f21287..d9c50048a 100644 --- a/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/Hud.kt +++ b/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/Hud.kt @@ -1137,6 +1137,14 @@ abstract class Hud(id: String, title: String, val category: Category) : Cloneabl open fun updateFrequency(): Long = -1L open fun defaultPosition(): Pair = 10f to 10f + /** + * Return `false` to skip drawing this HUD while it has nothing to show. Unlike [hidden], this + * doesn't change the user's visibility setting + * + * Called every frame after [update], so return state computed there + */ + open fun shouldShow(): Boolean = true + open fun showByDefault(): Boolean = false open fun hasBackground(): Boolean = true diff --git a/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/HudManager.kt b/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/HudManager.kt index dfd77f784..8f84e3759 100644 --- a/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/HudManager.kt +++ b/modules/hud/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/HudManager.kt @@ -478,20 +478,7 @@ object HudManager { return list.indices.sortedBy { depth[it] }.map { list[it] } } - private fun updateAndAdvance(huds: List) { - // opening or closing the editor swaps between preview and live content, so every HUD gets - // one immediate update on the edge instead of waiting out its remaining interval - if (wasEditing != isEditing) { - wasEditing = isEditing - for (hud in activeInstances) hud.lastUpdate = Long.MIN_VALUE - } - for (hud in huds) { - try { - updateIfDue(hud) - } catch (e: Throwable) { - LOGGER.error("Failed to update HUD ${hud.title}", e) - } - } + private fun updateAndAdvance() { if (showingPreviews) for (hud in hudProviders.values) updateIfDue(hud) if (PolyComposeHost.frameWithReport()) { invalidate() @@ -522,15 +509,17 @@ object HudManager { @ApiStatus.Internal fun updateIfDue(hud: Hud) { val frequency = hud.updateFrequency() - if (frequency < 0L) { + if (frequency >= 0L) { + val now = System.nanoTime() + val last = hud.lastUpdate + if (last != Long.MIN_VALUE && now - last < frequency) return + hud.lastUpdate = now + } + try { hud.update() - return + } catch (e: Throwable) { + LOGGER.error("Failed to update HUD ${hud.title}", e) } - val now = System.nanoTime() - val last = hud.lastUpdate - if (last != Long.MIN_VALUE && now - last < frequency) return - hud.lastUpdate = now - hud.update() } private fun layoutOnce(hud: Hud, screenWidth: Float, screenHeight: Float, scale: Float): RootNode { @@ -569,6 +558,19 @@ object HudManager { var volatileContent = false for (hud in orderedForRender()) { val visible = shouldDraw(hud) + if (visible || keepsBackgroundOnly(hud)) { + updateIfDue(hud) + val show = isEditing || try { + hud.shouldShow() + } catch (e: Throwable) { + LOGGER.error("Failed to check whether HUD ${hud.title} should show", e) + true + } + if (!show) { + hud.isVisible.value = false + continue + } + } hud.isVisible.value = visible if (visible) { frameOrder.add(hud) @@ -595,8 +597,15 @@ object HudManager { frameId++ Snapshot.sendApplyNotifications() + // opening or closing the editor swaps between preview and live content, so every HUD gets + // one immediate update on the edge instead of waiting out its remaining interval + if (wasEditing != isEditing) { + wasEditing = isEditing + for (hud in activeInstances) hud.lastUpdate = Long.MIN_VALUE + } + val huds = selectHuds() - updateAndAdvance(huds) + updateAndAdvance() layoutAll(huds, screenWidth, screenHeight, scale) updateBackgroundGroups(huds, screenWidth, screenHeight, scale) @@ -824,6 +833,7 @@ object HudManager { hud.isVisible.value = visible if (visible) prepareOrder.add(hud) } + for (hud in prepareOrder) updateIfDue(hud) prepareOrder }) }