diff options
| author | Linnea Gräf <nea@nea.moe> | 2024-02-14 22:02:01 +0100 |
|---|---|---|
| committer | Linnea Gräf <nea@nea.moe> | 2024-02-14 22:02:01 +0100 |
| commit | c10724cecb0fe34b2ddefcd0405bf2e71d1815de (patch) | |
| tree | 5c0bbdba8acae12e2ae18181d80ae9a7b7c4d3dc | |
| parent | 029514e0324d8ae72ad181c06bcf081c5c2a6304 (diff) | |
| download | SkyHanni-c10724cecb0fe34b2ddefcd0405bf2e71d1815de.tar.gz SkyHanni-c10724cecb0fe34b2ddefcd0405bf2e71d1815de.tar.bz2 SkyHanni-c10724cecb0fe34b2ddefcd0405bf2e71d1815de.zip | |
Initial idea for const
| -rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/const/Const.kt | 38 | ||||
| -rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/const/ConstItemStack.kt | 48 |
2 files changed, 86 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/const/Const.kt b/src/main/java/at/hannibal2/skyhanni/utils/const/Const.kt new file mode 100644 index 000000000..8da2498e0 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/const/Const.kt @@ -0,0 +1,38 @@ +package at.hannibal2.skyhanni.utils.const + +@JvmInline +/** + * Immutable view of an object. + * This class wraps an [T] indicating that it should not be modified. This allows multiple users to share an + * object instance without having to fear that the internal mutability of the object causes unexpected behaviour. + * More specifically, as long as the invariants of the methods and constructors are followed by all users then data + * contained within will never change. + * + * For specific [T]s there are extension methods allowing to safely access the data. + * + * This is a [JvmInline] class, so at + * runtime [Const] is a 0 cost wrapper. + */ +value class Const<T> private constructor( + /** + * Unsafely access the underlying object. Callers of this method promise not to modify the returned instance, or to + * leak this instance to any other codepaths which modify the instance. Whenever possible callers should wrap + * objects they return which offer a view into this object into a [Const] of its own. + */ + @PublishedApi + internal val unsafeMutable: T, +) { + companion object { + /** + * Create a new [Const] instance. Callers of this method guarantee that the given object will not be mutated + * internally. This should ideally be done by every instance of [value] being wrapped in a [Const] (and other + * references to be discarded as quickly as possible). + */ + fun <T> fromOwned(value: T): Const<T> { + return Const(value) + } + } +} + + + diff --git a/src/main/java/at/hannibal2/skyhanni/utils/const/ConstItemStack.kt b/src/main/java/at/hannibal2/skyhanni/utils/const/ConstItemStack.kt new file mode 100644 index 000000000..5e9484ffd --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/const/ConstItemStack.kt @@ -0,0 +1,48 @@ +package at.hannibal2.skyhanni.utils.const + +import net.minecraft.item.EnumDyeColor +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound + +/** + * Access a shallow copy of the underlying item stack. Callers of this method promise not to modify the nbt data of + * the returned instance, but can modify the stack size, metadata, item or outright replace the root tag compound. + * Interior immutability of [ItemStack.stackTagCompound] needs to be guaranteed by the caller. The instance is owned + * ergo not shared with anyone else, so that there are no mutability concerns about the ItemStack instance itself. + */ +fun Const<ItemStack>.getOwnedShallowCopy(): ItemStack { + return ItemStack(unsafeMutable.item, unsafeMutable.stackSize, unsafeMutable.metadata, unsafeMutable.tagCompound) +} + +/** + * Access a copy of the underlying item stack. The returned copy is fully and deeply owned, so changes can be made + * to the item stack instance, including interior mutability concerning the [ItemStack.stackTagCompound]. + */ +fun Const<ItemStack>.getOwnedDeepCopy(): ItemStack { + return unsafeMutable.copy() +} + +/** + * Returns the [ItemStack.stackSize] + */ +inline val Const<ItemStack>.stackSize: Int get() = unsafeMutable.stackSize + +/** + * Returns the [item type](ItemStack.item) + */ +inline val Const<ItemStack>.itemType: Item get() = unsafeMutable.item + +/** + * Returns the [damage or metadata](ItemStack.metadata) + */ +inline val Const<ItemStack>.damage: Int get() = unsafeMutable.metadata + +/** + * Interprets the [damage] of this item as a [color](EnumDyeColor). This is only valid for some [item types](itemType), + * so check that one first. + */ +inline val Const<ItemStack>.color: EnumDyeColor get() = EnumDyeColor.byDyeDamage(damage) + +inline val Const<ItemStack>.nbt: Const<NBTTagCompound>? + get() = unsafeMutable.tagCompound?.let(Const.Companion::fromOwned) |
