aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-02-14 22:02:01 +0100
committerLinnea Gräf <nea@nea.moe>2024-02-14 22:02:01 +0100
commitc10724cecb0fe34b2ddefcd0405bf2e71d1815de (patch)
tree5c0bbdba8acae12e2ae18181d80ae9a7b7c4d3dc
parent029514e0324d8ae72ad181c06bcf081c5c2a6304 (diff)
downloadSkyHanni-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.kt38
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/const/ConstItemStack.kt48
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)