Skip to content

Commit a051c57

Browse files
Version 1.3.9.3
1 parent 55b2788 commit a051c57

File tree

201 files changed

+5613
-2099
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

201 files changed

+5613
-2099
lines changed

changelog/release-1.3.9.3.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Title: Bug Patch
2+
Summary: Minor bug fixes
3+
4+
## New Versions
5+
- Added support for 1.21.10 Fabric
6+
7+
## Bug Fixes
8+
- Fixed buttons in Multiplayer menu not moving when the game window is resized on 1.21.9+
9+
- Fixed incorrect scrolling when cosmetic is clicked on preview player in Wardrobe
10+
- Fixed incorrect sub-category being highlighted in Wardrobe
11+
- Fixed Numpad Enter key not being recognized as Enter key
12+
- Fixed equipped cape disappearing when Essential is disabled

elementa/layoutdsl/src/main/kotlin/gg/essential/gui/common/stateExtensions.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ package gg.essential.gui.common
1414
import gg.essential.elementa.state.State
1515
import gg.essential.elementa.state.v2.ReferenceHolder
1616

17+
@Deprecated("Use StateV2 instead")
1718
fun <T> State<T>.onSetValueAndNow(listener: (T) -> Unit) = onSetValue(listener).also { listener(get()) }
1819

1920
@Deprecated("See `State.onSetValue`. Use `stateBy`/`effect` instead.")
2021
fun <T> gg.essential.gui.elementa.state.v2.State<T>.onSetValueAndNow(owner: ReferenceHolder, listener: (T) -> Unit) =
2122
onSetValue(owner, listener).also { listener(get()) }
2223

24+
@Deprecated("Use StateV2 instead")
2325
operator fun State<Boolean>.not() = map { !it }

elementa/layoutdsl/src/main/kotlin/gg/essential/gui/util/elementaExtensions.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,20 @@ inline fun <reified T : Effect> UIComponent.get() =
3535
inline fun <reified T : Effect> UIComponent.getOrPut(init: () -> T) =
3636
get<T>() ?: init().also { enableEffect(it) }
3737

38+
@Deprecated("Use StateV2 instead", ReplaceWith("pollingStateV2(initialValue, getter)"))
3839
fun <T> UIComponent.pollingState(initialValue: T? = null, getter: () -> T): State<T> {
3940
val state = BasicState(initialValue ?: getter())
4041
addUpdateFunc { _, _ -> state.set(getter()) }
4142
return state
4243
}
4344

45+
/**
46+
* Turns some impure computation into a pure [StateV2] by evaluating it before every frame.
47+
*
48+
* This should be avoided in favor of pure State-based computations where possible, but may be necessary when
49+
* interfacing with third-party code.
50+
* If the impure part of your computation is the current time, [Observer.systemTime] can likely replace this method.
51+
*/
4452
fun <T> UIComponent.pollingStateV2(initialValue: T? = null, getter: () -> T): StateV2<T> {
4553
val state = mutableStateOf(initialValue ?: getter())
4654
addUpdateFunc { _, _ -> state.set(getter()) }
@@ -224,6 +232,7 @@ fun UIComponent.hoverScopeV2(parentOnly: Boolean = false): StateV2<Boolean> {
224232
return consumer.state
225233
}
226234

235+
@Deprecated("Use StateV2 instead", ReplaceWith("hoverScopeV2(parentOnly)"))
227236
fun UIComponent.hoverScope(parentOnly: Boolean = false): State<Boolean> =
228237
hoverScopeV2(parentOnly).toV1(this)
229238

@@ -360,6 +369,7 @@ fun UIComponent.isComponentInParentChain(target: UIComponent): Boolean {
360369
fun UIComponent.isInComponentTree(): Boolean =
361370
this is Window || hasParent && this in parent.children && parent.isInComponentTree()
362371

372+
@Deprecated("ObservableList should be replaced with StateV2's `ListState`")
363373
fun <E> ObservableList<E>.onItemRemoved(callback: (E) -> Unit) {
364374
addObserver { _, arg ->
365375
if (arg is ObservableRemoveEvent<*>) {
@@ -368,6 +378,7 @@ fun <E> ObservableList<E>.onItemRemoved(callback: (E) -> Unit) {
368378
}
369379
}
370380

381+
@Deprecated("ObservableList should be replaced with StateV2's `ListState`")
371382
fun <E> ObservableList<E>.onItemAdded(callback: (E) -> Unit) {
372383
addObserver { _, arg ->
373384
if (arg is ObservableAddEvent<*>) {
@@ -376,6 +387,7 @@ fun <E> ObservableList<E>.onItemAdded(callback: (E) -> Unit) {
376387
}
377388
}
378389

390+
@Deprecated("ObservableList should be replaced with StateV2's `ListState`")
379391
@Suppress("UNCHECKED_CAST")
380392
fun <E> ObservableList<E>.toStateV2List(): ListStateV2<E> {
381393
val stateList = mutableStateOf(MutableTrackedList(this.toMutableList()))

elementa/layoutdsl/src/main/kotlin/gg/essential/gui/util/focusable.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ private fun UIComponent.setupKeyboardNavigation(): UIComponent.(Char, Int) -> Un
6767
}
6868

6969
when (keyCode) {
70-
UKeyboard.KEY_ENTER -> simulateLeftClick()
70+
UKeyboard.KEY_ENTER, UKeyboard.KEY_NUMPADENTER -> simulateLeftClick()
7171
UKeyboard.KEY_TAB -> passFocusToNextComponent(backwards = UKeyboard.isShiftKeyDown())
7272
}
7373
}

elementa/statev2/src/main/kotlin/gg/essential/gui/elementa/state/v2/combinators/booleans.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,26 @@ package gg.essential.gui.elementa.state.v2.combinators
1414
import gg.essential.gui.elementa.state.v2.MutableState
1515
import gg.essential.gui.elementa.state.v2.State
1616

17+
@Deprecated("Exists primarily for easier migration from State v1. Prefer using [State] lambda (with `memo` where necessary) instead.",
18+
replaceWith = ReplaceWith("State { this() && other() }"))
19+
@Suppress("DEPRECATION")
1720
infix fun State<Boolean>.and(other: State<Boolean>) =
1821
zip(other) { a, b -> a && b }
1922

23+
@Deprecated("Exists primarily for easier migration from State v1. Prefer using [State] lambda (with `memo` where necessary) instead.",
24+
replaceWith = ReplaceWith("State { this() || other() }"))
25+
@Suppress("DEPRECATION")
2026
infix fun State<Boolean>.or(other: State<Boolean>) =
2127
zip(other) { a, b -> a || b }
2228

23-
operator fun State<Boolean>.not() = map { !it }
29+
/**
30+
* Creates a new [State] which has the inverse value of this [State].
31+
*
32+
* This is mostly a convenience method so one can write `if_(!myState) {` instead of the more verbose
33+
* `if_({ !myState() }) {`. Both are equivalent.
34+
* This method shouldn't be overused though. If the expression is more complex, the verbose version is usually
35+
* preferred because it generalizes much better.
36+
*/
37+
operator fun State<Boolean>.not() = letState { !it }
2438

25-
operator fun MutableState<Boolean>.not() = bimap({ !it }, { !it })
39+
operator fun MutableState<Boolean>.not() = bimapState({ !it }, { !it })

elementa/statev2/src/main/kotlin/gg/essential/gui/elementa/state/v2/combinators/state.kt

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,72 @@
1212
package gg.essential.gui.elementa.state.v2.combinators
1313

1414
import gg.essential.gui.elementa.state.v2.MutableState
15+
import gg.essential.gui.elementa.state.v2.Observer
1516
import gg.essential.gui.elementa.state.v2.State
1617
import gg.essential.gui.elementa.state.v2.memo
1718

1819
/** Maps this state into a new state */
20+
@Deprecated("This method always applies `memo` even though it is often unnecessary. " +
21+
"Use `letState` instead, and explicitly call `.memo()` on the result only where required.")
1922
fun <T, U> State<T>.map(mapper: (T) -> U): State<U> {
2023
return memo { mapper(get()) }
2124
}
2225

26+
/**
27+
* Derives a new [State] from this [State].
28+
*
29+
* This method is equivalent to `.let { state -> State { block(state()) } }`.
30+
*
31+
* Note: For repeated or more complex derivations, an explicit [State] or [memo] lambda is likely easier to use.
32+
*/
33+
inline fun <T, U> State<T>.letState(crossinline block: Observer.(T) -> U): State<U> {
34+
val sourceState = this
35+
return State { block(sourceState()) }
36+
}
37+
2338
/** Maps this mutable state into a new mutable state. */
39+
@Deprecated("This method always applies `memo` even though it is often unnecessary. " +
40+
"Use `bimapState` or `bimapMemo` instead.")
2441
fun <T, U> MutableState<T>.bimap(map: (T) -> U, unmap: (U) -> T): MutableState<U> {
25-
return object : MutableState<U>, State<U> by this.map(map) {
42+
return bimapMemo(map, unmap)
43+
}
44+
45+
/**
46+
* Derives a new [MutableState] from this [MutableState].
47+
*
48+
* This variant uses [memo] internally. If this is not required, use [bimapState] instead.
49+
*/
50+
fun <T, U> MutableState<T>.bimapMemo(map: (T) -> U, unmap: (U) -> T): MutableState<U> {
51+
val sourceState = this
52+
return object : MutableState<U>, State<U> by (memo { map(sourceState()) }) {
2653
override fun set(mapper: (U) -> U) {
27-
this@bimap.set { unmap(mapper(map(it))) }
54+
sourceState.set { unmap(mapper(map(it))) }
2855
}
2956
}
3057
}
3158

59+
/**
60+
* Derives a new [MutableState] from this [MutableState].
61+
*
62+
* @see [bimapMemo]
63+
*/
64+
fun <T, U> MutableState<T>.bimapState(map: (T) -> U, unmap: (U) -> T): MutableState<U> {
65+
val sourceState = this
66+
return object : MutableState<U> {
67+
override fun Observer.get(): U = map(sourceState())
68+
override fun set(mapper: (U) -> U) = sourceState.set { unmap(mapper(map(it))) }
69+
}
70+
}
71+
3272
/** Zips this state with another state */
73+
@Deprecated("Exists primarily for easier migration from State v1. Prefer using [State] lambda (with `memo` where necessary) instead.",
74+
replaceWith = ReplaceWith("State { Pair(this(), other()) }"))
75+
@Suppress("DEPRECATION")
3376
fun <T, U> State<T>.zip(other: State<U>): State<Pair<T, U>> = zip(other, ::Pair)
3477

3578
/** Zips this state with another state using [mapper] */
79+
@Deprecated("Exists primarily for easier migration from State v1. Prefer using [State] lambda (with `memo` where necessary) instead.",
80+
replaceWith = ReplaceWith("State { mapper(this(), other()) }"))
3681
fun <T, U, V> State<T>.zip(other: State<U>, mapper: (T, U) -> V): State<V> {
3782
return memo { mapper(this@zip(), other()) }
3883
}

elementa/statev2/src/main/kotlin/gg/essential/gui/elementa/state/v2/combinators/strings.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,18 @@ package gg.essential.gui.elementa.state.v2.combinators
1313

1414
import gg.essential.gui.elementa.state.v2.State
1515

16+
@Deprecated("Exists primarily for easier migration from State v1. Prefer using [State] lambda (with `memo` where necessary) instead.",
17+
replaceWith = ReplaceWith("State { this().contains(other(), ignoreCase = ignoreCase) }"))
18+
@Suppress("DEPRECATION")
1619
fun State<String>.contains(other: State<String>, ignoreCase: Boolean = false) =
1720
zip(other) { a, b -> a.contains(b, ignoreCase) }
1821

22+
@Deprecated("Exists primarily for easier migration from State v1. Prefer using [State] lambda (with `memo` where necessary) instead.",
23+
replaceWith = ReplaceWith("State { this().isEmpty() }"))
24+
@Suppress("DEPRECATION")
1925
fun State<String>.isEmpty() = map { it.isEmpty() }
2026

27+
@Deprecated("Exists primarily for easier migration from State v1. Prefer using [State] lambda (with `memo` where necessary) instead.",
28+
replaceWith = ReplaceWith("State { this().isNotEmpty() }"))
29+
@Suppress("DEPRECATION")
2130
fun State<String>.isNotEmpty() = map { it.isNotEmpty() }

elementa/statev2/src/main/kotlin/gg/essential/gui/elementa/state/v2/combinators/utils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ package gg.essential.gui.elementa.state.v2.combinators
1414
import gg.essential.gui.elementa.state.v2.MutableState
1515

1616
fun MutableState<Int>.reorder(vararg mapping: Int) =
17-
bimap({ mapping[it] }, { mapping.indexOf(it) })
17+
bimapState({ mapping[it] }, { mapping.indexOf(it) })

elementa/statev2/src/main/kotlin/gg/essential/gui/elementa/state/v2/impl/Impl.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ internal interface Impl {
2525
fun <T> memo(func: Observer.() -> T): State<T>
2626
fun effect(referenceHolder: ReferenceHolder, func: Observer.() -> Unit): () -> Unit
2727

28+
@Suppress("DEPRECATION")
2829
fun <T> stateDelegatingTo(state: State<T>): DelegatingState<T> =
2930
object : DelegatingState<T> {
3031
private val target = mutableStateOf(state)
3132
override fun rebind(newState: State<T>) = target.set(newState)
3233
override fun Observer.get(): T = target()()
3334
}
3435

36+
@Suppress("DEPRECATION")
3537
fun <T> mutableStateDelegatingTo(state: MutableState<T>): DelegatingMutableState<T> =
3638
object : DelegatingMutableState<T> {
3739
private val target = mutableStateOf(state)

0 commit comments

Comments
 (0)