diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt index 6663c1747..427dc6b5c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterPanelBlockEntity.kt @@ -179,7 +179,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : } override fun getTask(id: UUID): ReplicationTask? { - return _tasks[id]?.asImmutable() + return _tasks[id] } fun removeTask(id: UUID) { @@ -192,7 +192,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : setChanged() } - fun addTask(state: PatternState, count: Int): IReplicationTask<*> { + fun addTask(state: PatternState, count: Int): ReplicationTask { val task = ReplicationTask(UUID.randomUUID(), Optional.of(state.id), state.item, 0, 0, count) _tasks[task.id] = task diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt index 1e42b8a95..ba76baaba 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt @@ -83,11 +83,11 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : return matter } - override fun onMatterTaskCreated(task: IReplicationTask<*>) { + override fun onMatterTaskCreated(task: ReplicationTask) { jobEventLoops[0].notify(MachineJobEventLoop.IdleReason.OBSERVING) } - override fun > onMatterTaskUpdated(newState: T, oldState: T) { + override fun onMatterTaskUpdated(newState: ReplicationTask, oldState: ReplicationTask) { jobEventLoops[0].notify(MachineJobEventLoop.IdleReason.OBSERVING) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/Data.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/Data.kt index 64b6d75cf..8a52f25e0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/Data.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/Data.kt @@ -21,4 +21,4 @@ class PatternInsertUpdated(new: PatternState, old: PatternState) : PatternInsert class PatternInsertInserted(new: PatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null) @JvmRecord -data class ReplicationTaskAllocation(val task: IReplicationTask<*>, val pattern: PatternState?) +data class ReplicationTaskAllocation(val task: ReplicationTask, val pattern: PatternState?) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IReplicationTaskProvider.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IReplicationTaskProvider.kt index 2fc50bb25..500a9a5e2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IReplicationTaskProvider.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IReplicationTaskProvider.kt @@ -7,19 +7,19 @@ interface IReplicationTaskProvider { /** * It must return new stream each time */ - val replicationTasks: Stream> + val replicationTasks: Stream /** * It must return new stream each time */ - val allReplicationTasks: Stream> + val allReplicationTasks: Stream /** * Allocates (marks as work-in-progress) a task - * by incrementing it's [IReplicationTask.inProgress] by 1 - * and shrinking [IReplicationTask.required] by 1 + * by incrementing it's [ReplicationTask.inProgress] by 1 + * and shrinking [ReplicationTask.required] by 1 * - * If [IReplicationTask.required] == 0, it should not be returned by this method + * If [ReplicationTask.required] == 0, it should not be returned by this method * @param simulate whenever to change internal state * @return MatterTaskAllocation(task, pattern) that should be performed, or null if no work is available */ @@ -38,7 +38,7 @@ interface IReplicationTaskProvider { * @param id uuid of task * @return MatterTask that this capability holds with this id, or null */ - fun getTask(id: UUID): IReplicationTask<*>? { + fun getTask(id: UUID): ReplicationTask? { return allReplicationTasks.filter { it.id == id }.findAny().orElse(null) } @@ -46,4 +46,4 @@ interface IReplicationTaskProvider { * Destroys all tasks this capability contains */ fun dropAllTasks() -} \ No newline at end of file +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt index 287726f49..d7682e9f0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt @@ -1,59 +1,31 @@ package ru.dbotthepony.mc.otm.capability.matter -import com.mojang.datafixers.Products import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.NbtOps import net.minecraft.nbt.Tag import net.minecraft.network.FriendlyByteBuf -import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.Items import net.minecraftforge.registries.ForgeRegistries -import ru.dbotthepony.mc.otm.core.readItemType -import ru.dbotthepony.mc.otm.core.writeItemType +import ru.dbotthepony.mc.otm.core.util.readBinaryJsonWithCodec +import ru.dbotthepony.mc.otm.core.util.writeBinaryJsonWithCodec import ru.dbotthepony.mc.otm.data.UUIDCodec import java.util.Optional import java.util.UUID -sealed interface IReplicationTask> { - val id: UUID - val patternId: Optional - val item: Item - val inProgress: Int - val finished: Int +data class ReplicationTask( + val id: UUID, + val patternId: Optional, + val item: Item, + val inProgress: Int, + val finished: Int, val required: Int - - fun asMutable(): MutableReplicationTask - fun asImmutable(): ReplicationTask - +) { val total get() = inProgress + finished + required - fun copyAsMutable( - id: UUID = this.id, - patternId: Optional = this.patternId, - item: Item = this.item, - inProgress: Int = this.inProgress, - finished: Int = this.finished, - required: Int = this.required, - ): MutableReplicationTask { - return MutableReplicationTask(id, patternId, item, inProgress, finished, required) - } - - fun copyAsImmutable( - id: UUID = this.id, - patternId: Optional = this.patternId, - item: Item = this.item, - inProgress: Int = this.inProgress, - finished: Int = this.finished, - required: Int = this.required, - ): ReplicationTask { - return ReplicationTask(id, patternId, item, inProgress, finished, required) - } - - fun matchId(other: IReplicationTask<*>): Boolean { + fun matchId(other: ReplicationTask): Boolean { return other.id == id } @@ -61,144 +33,41 @@ sealed interface IReplicationTask> { return ItemStack(item, count) } - fun allocate(amount: Int = 1): S - fun finish(amount: Int = 1): S - - fun serializeNBT(): CompoundTag - - fun write(buff: FriendlyByteBuf) { - buff.writeUUID(id) - - buff.writeBoolean(patternId.isPresent) - patternId.ifPresent(buff::writeUUID) - - buff.writeItemType(item) - - buff.writeInt(inProgress) - buff.writeInt(finished) - buff.writeInt(required) - } -} - -private fun > codec(builder: RecordCodecBuilder.Instance): Products.P6, UUID, Optional, Item, Int, Int, Int> { - return builder.group( - UUIDCodec.fieldOf("id").forGetter(IReplicationTask<*>::id), - UUIDCodec.optionalFieldOf("patternId").forGetter(IReplicationTask<*>::patternId), - ForgeRegistries.ITEMS.codec.fieldOf("item").forGetter(IReplicationTask<*>::item), - Codec.intRange(0, Int.MAX_VALUE).fieldOf("inProgress").forGetter(IReplicationTask<*>::inProgress), - Codec.intRange(0, Int.MAX_VALUE).fieldOf("finished").forGetter(IReplicationTask<*>::finished), - Codec.intRange(0, Int.MAX_VALUE).fieldOf("required").forGetter(IReplicationTask<*>::required), - ) -} - -private fun read(buff: FriendlyByteBuf, mutable: Boolean): IReplicationTask<*>? { - val id = buff.readUUID() - val patternId: UUID? = if (buff.readBoolean()) buff.readUUID() else null - val item = buff.readItemType() - val inProgress = buff.readInt() - val finished = buff.readInt() - val required = buff.readInt() - - item ?: return null - - if (mutable) { - return MutableReplicationTask(id, Optional.ofNullable(patternId), item, inProgress, finished, required) - } else { - return ReplicationTask(id, Optional.ofNullable(patternId), item, inProgress, finished, required) - } -} - -data class ReplicationTask( - override val id: UUID, - override val patternId: Optional, - override val item: Item, - override val inProgress: Int, - override val finished: Int, - override val required: Int -) : IReplicationTask { - override fun asMutable(): MutableReplicationTask { - return MutableReplicationTask(id, patternId, item, inProgress, finished, required) - } - - override fun asImmutable(): ReplicationTask { - return this - } - - override fun allocate(amount: Int): ReplicationTask { + fun allocate(amount: Int = 1): ReplicationTask { return ReplicationTask(id, patternId, item, inProgress + amount, finished, required - amount) } - override fun finish(amount: Int): ReplicationTask { + fun finish(amount: Int = 1): ReplicationTask { return ReplicationTask(id, patternId, item, inProgress - amount, finished + amount, required) } - override fun serializeNBT(): CompoundTag { + fun serializeNBT(): CompoundTag { return CODEC.encode(this, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).get().map({ it as CompoundTag }, { throw RuntimeException("Failed to serialize ReplicationTask: ${it.message()}") }) } + fun write(buff: FriendlyByteBuf) { + buff.writeBinaryJsonWithCodec(CODEC, this) + } + companion object { fun deserializeNBT(nbt: Tag?): ReplicationTask? { - nbt ?: return null - return CODEC.decode(NbtOps.INSTANCE, nbt).result().map { it.first }.orElse(null) + return CODEC.decode(NbtOps.INSTANCE, nbt ?: return null).result().orElse(null)?.first } - fun read(buff: FriendlyByteBuf): ReplicationTask? { - return read(buff, false) as ReplicationTask? + fun read(buff: FriendlyByteBuf): ReplicationTask { + return buff.readBinaryJsonWithCodec(CODEC) } val CODEC: Codec by lazy { RecordCodecBuilder.create { - codec(it).apply(it, ::ReplicationTask) - } - } - } -} - -data class MutableReplicationTask( - override val id: UUID, - override val patternId: Optional, - override val item: Item, - override var inProgress: Int, - override var finished: Int, - override var required: Int -) : IReplicationTask { - override fun asMutable(): MutableReplicationTask { - return this - } - - override fun asImmutable(): ReplicationTask { - return ReplicationTask(id, patternId, item, inProgress, finished, required) - } - - override fun allocate(amount: Int): MutableReplicationTask { - inProgress += amount - finished -= amount - return this - } - - override fun finish(amount: Int): MutableReplicationTask { - finished += amount - inProgress -= amount - return this - } - - override fun serializeNBT(): CompoundTag { - return CODEC.encode(this, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).get().map({ it as CompoundTag }, { throw RuntimeException("Failed to serialize MutableReplicationTask: ${it.message()}") }) - } - - companion object { - fun deserializeNBT(nbt: Tag?): MutableReplicationTask? { - nbt ?: return null - return CODEC.decode(NbtOps.INSTANCE, nbt).result().map { it.first }.orElse(null) - } - - fun read(buff: FriendlyByteBuf): MutableReplicationTask? { - return read(buff, true) as MutableReplicationTask? - } - - val CODEC: Codec by lazy { - RecordCodecBuilder.create { - codec(it).apply(it, ::MutableReplicationTask) + it.group( + UUIDCodec.fieldOf("id").forGetter(ReplicationTask::id), + UUIDCodec.optionalFieldOf("patternId").forGetter(ReplicationTask::patternId), + ForgeRegistries.ITEMS.codec.fieldOf("item").forGetter(ReplicationTask::item), + Codec.intRange(0, Int.MAX_VALUE).fieldOf("inProgress").forGetter(ReplicationTask::inProgress), + Codec.intRange(0, Int.MAX_VALUE).fieldOf("finished").forGetter(ReplicationTask::finished), + Codec.intRange(0, Int.MAX_VALUE).fieldOf("required").forGetter(ReplicationTask::required), + ).apply(it, ::ReplicationTask) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt index e39e56d9d..c38dc7764 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/matter/MatterPanelScreen.kt @@ -6,7 +6,7 @@ import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.capability.matter.PatternState -import ru.dbotthepony.mc.otm.capability.matter.IReplicationTask +import ru.dbotthepony.mc.otm.capability.matter.ReplicationTask import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.render.* import ru.dbotthepony.mc.otm.client.screen.MatteryScreen @@ -251,7 +251,7 @@ class MatterPanelScreen( return frame } - private fun openTask(task: IReplicationTask<*>): FramePanel { + private fun openTask(task: ReplicationTask): FramePanel { val frame = FramePanel.padded(this, null, 170f, 20f, TranslatableComponent("otm.gui.matter_panel.task")) frame.behaveAsWindow() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt index 0b3b95b53..6b6f332af 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/FriendlyStreams.kt @@ -294,6 +294,11 @@ fun FriendlyByteBuf.writeBinaryComponent(component: Component) { writeBinaryJson(Component.Serializer.toJsonTree(component)) } +// обратный порядок аргументов у лямбда выражения +fun FriendlyByteBuf.writeCollection(collection: Collection, writer: (T, FriendlyByteBuf) -> Unit) { + writeCollection(collection) { a, b -> writer.invoke(b, a) } +} + fun S.writeCollection(collection: Collection, writer: S.(V) -> Unit) { writeVarIntLE(collection.size) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphListener.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphListener.kt index 462f431e2..171668334 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphListener.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphListener.kt @@ -7,8 +7,8 @@ interface IMatterGraphListener { fun onPatternRemoved(state: PatternState) {} fun onPatternUpdated(newState: PatternState, oldState: PatternState) {} - fun onMatterTaskCreated(task: IReplicationTask<*>) {} - fun > onMatterTaskUpdated(newState: T, oldState: T) {} - fun onMatterTaskFinished(state: IReplicationTask<*>) {} - fun onMatterTaskRemoved(state: IReplicationTask<*>) {} + fun onMatterTaskCreated(task: ReplicationTask) {} + fun onMatterTaskUpdated(newState: ReplicationTask, oldState: ReplicationTask) {} + fun onMatterTaskFinished(state: ReplicationTask) {} + fun onMatterTaskRemoved(state: ReplicationTask) {} } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterGraph.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterGraph.kt index 08bc17579..2632bb0de 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterGraph.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterGraph.kt @@ -193,11 +193,11 @@ class MatterGraph : Abstract6Graph(), IMatterGraphListe return doInsertPattern(state, false, simulate) } - val tasks: Stream> get() { + val tasks: Stream get() { return nodes.stream().map { it.getTaskHandler()?.replicationTasks }.filterNotNull().flatMap { it } } - val allTasks: Stream> get() { + val allTasks: Stream get() { return nodes.stream().map { it.getTaskHandler()?.allReplicationTasks }.filterNotNull().flatMap { it } } @@ -312,22 +312,22 @@ class MatterGraph : Abstract6Graph(), IMatterGraphListe for (node in listeners) node.onPatternUpdated(newState, oldState) } - override fun onMatterTaskCreated(task: IReplicationTask<*>) { + override fun onMatterTaskCreated(task: ReplicationTask) { for (node in nodes) node.onMatterTaskCreated(task) for (node in listeners) node.onMatterTaskCreated(task) } - override fun > onMatterTaskUpdated(newState: T, oldState: T) { + override fun onMatterTaskUpdated(newState: ReplicationTask, oldState: ReplicationTask) { for (node in nodes) node.onMatterTaskUpdated(newState, oldState) for (node in listeners) node.onMatterTaskUpdated(newState, oldState) } - override fun onMatterTaskFinished(state: IReplicationTask<*>) { + override fun onMatterTaskFinished(state: ReplicationTask) { for (node in nodes) node.onMatterTaskFinished(state) for (node in listeners) node.onMatterTaskFinished(state) } - override fun onMatterTaskRemoved(state: IReplicationTask<*>) { + override fun onMatterTaskRemoved(state: ReplicationTask) { for (node in nodes) node.onMatterTaskRemoved(state) for (node in listeners) node.onMatterTaskRemoved(state) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt index 589564d7e..fb69a94a1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterPanelMenu.kt @@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.core.util.BooleanValueCodec import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec import ru.dbotthepony.mc.otm.core.util.ItemSorter import ru.dbotthepony.mc.otm.core.util.codec +import ru.dbotthepony.mc.otm.core.util.writeCollection import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener import ru.dbotthepony.mc.otm.graph.matter.MatterGraph import ru.dbotthepony.mc.otm.menu.MatteryMenu @@ -52,11 +53,7 @@ class CancelTaskPacket(val id: UUID) : MatteryPacket { class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection) : MatteryPacket { override fun write(buff: FriendlyByteBuf) { buff.writeBoolean(isUpdate) - buff.writeInt(patterns.size) - - for (pattern in patterns) { - pattern.write(buff) - } + buff.writeCollection(patterns, PatternState::write) } override fun play(context: Supplier) { @@ -74,23 +71,15 @@ class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection(size).also { - for (i in 0 until size) it.add(PatternState.read(buff) ?: throw NullPointerException("Unable to read PatternState from network at $i")) }) + return PatternsChangePacket(buff.readBoolean(), buff.readCollection(::ArrayList, PatternState::read)) } } } -class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection>) : MatteryPacket { +class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection) : MatteryPacket { override fun write(buff: FriendlyByteBuf) { buff.writeBoolean(isUpdate) - buff.writeInt(tasks.size) - - for (task in tasks) { - task.write(buff) - } + buff.writeCollection(tasks, ReplicationTask::write) } override fun play(context: Supplier) { @@ -108,11 +97,7 @@ class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection>(size).also { - for (i in 0 until size) it.add(ReplicationTask.read(buff) ?: throw NullPointerException("Unable to read Replication Task from network at $i")) }) + return TasksChangePacket(buff.readBoolean(), buff.readCollection(::ArrayList, ReplicationTask::read)) } } } @@ -142,16 +127,16 @@ class ReplicationRequestPacket(val id: UUID, amount: Int) : MatteryPacket { } } -class MatterPanelMenu @JvmOverloads constructor( +class MatterPanelMenu( p_38852_: Int, inventory: Inventory, tile: MatterPanelBlockEntity? = null ) : MatteryMenu(MMenus.MATTER_PANEL, p_38852_, inventory, tile), IMatterGraphListener { - fun taskUpdated(task: IReplicationTask<*>) { + fun taskUpdated(task: ReplicationTask) { sendNetwork(TasksChangePacket(true, listOf(task))) } - fun taskRemoved(task: IReplicationTask<*>) { + fun taskRemoved(task: ReplicationTask) { sendNetwork(TasksChangePacket(false, listOf(task))) } @@ -206,13 +191,13 @@ class MatterPanelMenu @JvmOverloads constructor( val isAscendingGS = GetterSetter.of(::isAscending, changeIsAscending::input) private val actualComparator = Comparator { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) } - private val actualTaskComparator = Comparator> { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) } + private val actualTaskComparator = Comparator { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) } private val patterns = ArrayList() - private val tasks = ArrayList>() + private val tasks = ArrayList() val patternsFiltered = ArrayList() - val tasksFiltered = ArrayList>() + val tasksFiltered = ArrayList() fun networkPatternsUpdated(patterns: Collection) { for (pattern in patterns) { @@ -242,7 +227,7 @@ class MatterPanelMenu @JvmOverloads constructor( } } - fun networkTasksUpdated(tasks: Collection>) { + fun networkTasksUpdated(tasks: Collection) { for (task in tasks) { val index = this.tasks.indexOfFirst(task::matchId) @@ -264,7 +249,7 @@ class MatterPanelMenu @JvmOverloads constructor( } } - fun networkTasksRemoved(tasks: Collection>) { + fun networkTasksRemoved(tasks: Collection) { for (task in tasks) { val index = this.tasks.indexOfFirst(task::matchId)