From 6e824db2f5ca6335e88eb4e45a0587bb16d0939a Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 3 Sep 2022 14:59:35 +0700 Subject: [PATCH] Revise and streamline pattern and replication tasks API --- .../mc/otm/capability/MatteryCapability.java | 6 +- .../mc/otm/capability/matter/MatterTask.java | 146 ------------ .../otm/capability/matter/PatternState.java | 94 -------- .../block/entity/PatternStorageBlockEntity.kt | 24 +- .../entity/matter/MatterPanelBlockEntity.kt | 84 ++++--- .../matter/MatterReplicatorBlockEntity.kt | 22 +- .../entity/matter/MatterScannerBlockEntity.kt | 39 ++-- .../mc/otm/capability/matter/API.kt | 80 +++---- .../mc/otm/capability/matter/Data.kt | 16 +- .../mc/otm/capability/matter/PatternState.kt | 146 ++++++++++++ .../otm/capability/matter/ReplicationTask.kt | 210 ++++++++++++++++++ .../mc/otm/client/screen/MatterPanelScreen.kt | 23 +- .../mc/otm/core/CapabilityIterators.kt | 2 +- .../dbotthepony/mc/otm/core/CompoundTagExt.kt | 13 ++ .../kotlin/ru/dbotthepony/mc/otm/core/Ext.kt | 26 +++ .../mc/otm/graph/matter/IMatterGraphNode.kt | 16 +- .../mc/otm/graph/matter/MatterNetworkGraph.kt | 131 ++++------- .../mc/otm/item/PatternStorageItem.kt | 46 ++-- .../mc/otm/menu/MatterPanelMenu.kt | 82 +++---- .../mc/otm/menu/MatterScannerMenu.kt | 8 +- .../mc/otm/menu/PatternStorageMenu.kt | 4 +- 21 files changed, 660 insertions(+), 558 deletions(-) delete mode 100644 src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterTask.java delete mode 100644 src/main/java/ru/dbotthepony/mc/otm/capability/matter/PatternState.java create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java index 461330c6b..50c423a7b 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -5,7 +5,7 @@ import net.minecraftforge.common.capabilities.*; import org.jetbrains.annotations.NotNull; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; -import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider; +import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider; import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage; import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode; import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode; @@ -36,7 +36,7 @@ public class MatteryCapability { @Nonnull @NotNull - public static final Capability TASK = CapabilityManager.get(new CapabilityToken<>() {}); + public static final Capability TASK = CapabilityManager.get(new CapabilityToken<>() {}); @Nonnull @NotNull @@ -56,7 +56,7 @@ public class MatteryCapability { event.register(MatteryPlayerCapability.class); event.register(IMatterHandler.class); event.register(IPatternStorage.class); - event.register(IMatterTaskProvider.class); + event.register(IReplicationTaskProvider.class); event.register(IMatteryDrive.class); event.register(IStorageGraphNode.class); event.register(IMatterGraphNode.class); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterTask.java b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterTask.java deleted file mode 100644 index d42f81cae..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterTask.java +++ /dev/null @@ -1,146 +0,0 @@ -package ru.dbotthepony.mc.otm.capability.matter; - -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.nbt.CompoundTag; -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 net.minecraftforge.registries.ForgeRegistry; -import ru.dbotthepony.mc.otm.core.UnOverengineeringKt; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; -import java.util.Objects; -import java.util.UUID; - -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public record MatterTask(UUID id, @Nullable UUID pattern, Item item, int in_progress, int finished, int required) { - public MatterTask(UUID id, @Nullable UUID pattern, Item item, int in_progress, int finished, int required) { - this.id = id; - this.pattern = pattern; - this.item = item; - this.in_progress = Math.max(0, in_progress); - this.finished = Math.max(0, finished); - this.required = Math.max(0, required); - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof MatterTask obj1) - return obj1.id.equals(id); - - return false; - } - - public ItemStack stack() { - return new ItemStack(item, 1); - } - - public ItemStack stack(int amount) { - return new ItemStack(item, amount); - } - - public int total() { - return in_progress + finished + required; - } - - public MatterTask shrinkRequired(int amount) { - return new MatterTask(id, pattern, item, in_progress + amount, finished, required - amount); - } - - public MatterTask shrinkInProgress(int amount) { - return new MatterTask(id, pattern, item, in_progress - amount, finished + amount, required); - } - - public CompoundTag serializeNBT() { - CompoundTag tag = new CompoundTag(); - - tag.putLong("id_l", id.getLeastSignificantBits()); - tag.putLong("id_u", id.getMostSignificantBits()); - - if (pattern != null) { - tag.putLong("pattern_l", pattern.getLeastSignificantBits()); - tag.putLong("pattern_u", pattern.getMostSignificantBits()); - } - - tag.putString("item", Objects.requireNonNull(UnOverengineeringKt.getRegistryName(item)).toString()); - tag.putInt("in_progress", in_progress); - tag.putInt("finished", finished); - tag.putInt("required", required); - - return tag; - } - - @Nullable - public static MatterTask deserializeNBT(@Nullable Tag nbt) { - if (nbt == null) - return null; - - if (nbt instanceof CompoundTag tag) { - Item get_item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(tag.getString("item"))); - - if (get_item != null && get_item != Items.AIR) { - long a = tag.getLong("pattern_u"); - long b = tag.getLong("pattern_l"); - - UUID pattern = a != 0 && b != 0 ? new UUID(a, b) : null; - - return new MatterTask( - new UUID(tag.getLong("id_u"), tag.getLong("id_l")), - pattern, - get_item, - tag.getInt("in_progress"), - tag.getInt("finished"), - tag.getInt("required") - ); - } - } - - return null; - } - - public void write(FriendlyByteBuf buffer) { - buffer.writeLong(id.getMostSignificantBits()); - buffer.writeLong(id.getLeastSignificantBits()); - - if (pattern != null) { - buffer.writeBoolean(true); - - buffer.writeLong(pattern.getMostSignificantBits()); - buffer.writeLong(pattern.getLeastSignificantBits()); - } else { - buffer.writeBoolean(false); - } - - buffer.writeInt(((ForgeRegistry) ForgeRegistries.ITEMS).getID(item)); - buffer.writeInt(in_progress); - buffer.writeInt(finished); - buffer.writeInt(required); - } - - @Nullable - public static MatterTask read(FriendlyByteBuf buffer) { - var id = new UUID(buffer.readLong(), buffer.readLong()); - var pattern = buffer.readBoolean() ? new UUID(buffer.readLong(), buffer.readLong()) : null; - var item = ((ForgeRegistry) ForgeRegistries.ITEMS).getValue(buffer.readInt()); - - if (item == null) - return null; - - var in_progress = buffer.readInt(); - var finished = buffer.readInt(); - var required = buffer.readInt(); - - return new MatterTask(id, pattern, item, in_progress, finished, required); - } -} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/PatternState.java b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/PatternState.java deleted file mode 100644 index cb3d3b889..000000000 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/PatternState.java +++ /dev/null @@ -1,94 +0,0 @@ -package ru.dbotthepony.mc.otm.capability.matter; - -import net.minecraft.nbt.CompoundTag; -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.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.ForgeRegistry; -import ru.dbotthepony.mc.otm.core.UnOverengineeringKt; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.Objects; -import java.util.UUID; - -public record PatternState(@Nonnull UUID id, @Nonnull Item item, double research) { - public PatternState(@Nonnull UUID id, @Nonnull Item item, double research) { - this.id = id; - this.item = item; - this.research = Math.max(0, Math.min(1, research)); - } - - @Override - public boolean equals(Object state) { - if (state instanceof PatternState state1) - return state1.id.equals(id); - - return false; - } - - public ItemStack stack() { - return new ItemStack(item, 1); - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - public CompoundTag serializeNBT() { - var tag = new CompoundTag(); - - tag.putLong("id_m", id.getMostSignificantBits()); - tag.putLong("id_l", id.getLeastSignificantBits()); - tag.putString("item", Objects.requireNonNull(UnOverengineeringKt.getRegistryName(item)).toString()); - tag.putDouble("research_percent", research); - - return tag; - } - - @Nullable - public static PatternState deserializeNBT(Tag nbt) { - if (nbt instanceof CompoundTag tag) { - var item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(tag.getString("item"))); - - if (item == null) - return null; - - var id = new UUID(tag.getLong("id_m"), tag.getLong("id_l")); - var research_percent = tag.getDouble("research_percent"); - - return new PatternState(id, item, research_percent); - } - - return null; - } - - public void write(FriendlyByteBuf buffer) { - buffer.writeLong(id.getMostSignificantBits()); - buffer.writeLong(id.getLeastSignificantBits()); - - buffer.writeInt(((ForgeRegistry) ForgeRegistries.ITEMS).getID(item)); - - buffer.writeDouble(research); - } - - @Nullable - public static PatternState read(FriendlyByteBuf buffer) { - long ida = buffer.readLong(); - long idb = buffer.readLong(); - - int item = buffer.readInt(); - double percent = buffer.readDouble(); - - Item get_item = ((ForgeRegistry) ForgeRegistries.ITEMS).getValue(item); - - if (get_item == null) - return null; - - return new PatternState(new UUID(ida, idb), get_item, percent); - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/PatternStorageBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/PatternStorageBlockEntity.kt index 3e20f6baa..2296f4f5f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/PatternStorageBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/PatternStorageBlockEntity.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.block.entity +import com.google.common.collect.Streams import javax.annotation.ParametersAreNonnullByDefault import net.minecraft.core.BlockPos import net.minecraft.world.level.block.state.BlockState @@ -32,6 +33,7 @@ import ru.dbotthepony.mc.otm.core.ifHas import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.core.set import java.util.ArrayList +import java.util.stream.Stream @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault @@ -50,13 +52,13 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : if (grid != null && !ItemStack.isSameItemSameTags(new, old)) { if (!old.isEmpty) { old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage -> - cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternRemoved(state!!) } + cap.storedPatterns.forEach { grid.onPatternRemoved(it) } } } if (!new.isEmpty) { new.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage -> - cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternAdded(state!!) } + cap.storedPatterns.forEach { grid.onPatternAdded(it) } } } @@ -147,10 +149,14 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : return PatternStorageMenu(containerID, inventory, this) } - override val storedPatterns: Collection get() { - val list = ArrayList() - patterns.forEachCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) } - return list + override val storedPatterns: Stream get() { + val streams = ArrayList>() + + for (provider in patterns.iterator(MatteryCapability.PATTERN)) { + streams.add(provider.second.storedPatterns) + } + + return Streams.concat(*streams.toTypedArray()) } override val capacity: Int get() { @@ -176,9 +182,9 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : matterNode.destroy(::MatterNetworkGraph) } - override fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus { - for ((_, storage) in patterns.iterator(MatteryCapability.PATTERN)) { - val status = storage.insertPattern(pattern, only_update, simulate) + override fun insertPattern(pattern: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus { + for (pair in patterns.iterator(MatteryCapability.PATTERN)) { + val status = pair.second.insertPattern(pattern, onlyUpdate, simulate) if (!status.isFailed) { if (!simulate) { 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 d26a57718..6cd1340d2 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 @@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.block.entity.matter import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.world.level.block.state.BlockState -import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider import ru.dbotthepony.mc.otm.menu.MatterPanelMenu import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player @@ -12,10 +11,6 @@ import net.minecraftforge.common.util.LazyOptional import ru.dbotthepony.mc.otm.capability.MatteryCapability import java.util.HashMap import java.util.UUID -import ru.dbotthepony.mc.otm.capability.matter.MatterTask -import java.util.stream.Collectors -import ru.dbotthepony.mc.otm.capability.matter.MatterTaskAllocation -import ru.dbotthepony.mc.otm.capability.matter.PatternState import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.Tag @@ -25,15 +20,16 @@ import net.minecraft.world.level.Level import net.minecraftforge.common.capabilities.Capability import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity +import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.registry.MBlockEntities import java.util.ArrayList -import java.util.List +import java.util.stream.Stream class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : - MatteryBlockEntity(MBlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IMatterTaskProvider { + MatteryBlockEntity(MBlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IReplicationTaskProvider { private val listeners = ArrayList() override val matterNode = Graph6Node(this) @@ -88,61 +84,59 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : matterNode.destroy(::MatterNetworkGraph) } - override fun getTaskHandler(): IMatterTaskProvider? { + override fun getTaskHandler(): IReplicationTaskProvider { return this } - private val _tasks = HashMap() + private val _tasks = HashMap() - override val tasks: Collection get() { - return _tasks.values.stream().filter { task: MatterTask? -> task!!.required() > 0 }.collect(Collectors.toList()) as Collection + override val replicationTasks: Stream get() { + return _tasks.values.stream().filter { it.required > 0 } } - override val allTasks: Collection get() { - return List.copyOf(_tasks.values) as Collection + override val allReplicationTasks: Stream get() { + return _tasks.values.stream() } - override fun allocateTask(simulate: Boolean): MatterTaskAllocation? { + override fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? { val graph = matterNode.graph as MatterNetworkGraph? ?: return null for ((key, task) in _tasks) { if (task.required > 0) { - val getPattern = graph.getPattern(task.pattern!!) + val pattern = task.patternId?.let(graph::getPattern) ?: continue - if (getPattern != null) { - if (!simulate) { - val new = task.shrinkRequired(1) - _tasks[key] = new - listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(new) } - graph.onMatterTaskUpdated(new, task) - setChanged() - } - - return MatterTaskAllocation(task, getPattern) + if (!simulate) { + val new = task.allocate() + _tasks[key] = new + listeners.forEach { it.taskUpdated(new) } + graph.onMatterTaskUpdated(new, task) + setChanged() } + + return ReplicationTaskAllocation(task, pattern) } } return null } - override fun notifyTaskCompletion(task: MatterTask): Boolean { - var localTask = _tasks[task.id] ?: return false + override fun notifyTaskCompletion(taskId: UUID): Boolean { + var localTask = _tasks[taskId] ?: return false val oldTask = localTask - localTask = localTask.shrinkInProgress(1) + localTask = localTask.finish() val graph = matterNode.graph as MatterNetworkGraph? // Задача полностью выполнена - if (localTask.required <= 0 && localTask.in_progress <= 0) { - _tasks.remove(task.id) - graph?.onMatterTaskCreated(task) - listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(localTask) } + if (localTask.required <= 0 && localTask.inProgress <= 0) { + _tasks.remove(taskId) + graph?.onMatterTaskFinished(localTask) + listeners.forEach { it.taskRemoved(localTask) } } else { // Задача обновлена - _tasks[task.id()] = localTask + _tasks[taskId] = localTask graph?.onMatterTaskUpdated(localTask, oldTask) - listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(localTask) } + listeners.forEach { it.taskUpdated(localTask) } } setChanged() @@ -155,7 +149,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : val list = ListTag() for (task in _tasks.values) { - list.add(task!!.serializeNBT()) + list.add(task.serializeNBT()) } nbt.put("tasks", list) @@ -167,16 +161,16 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : val list = nbt.getList("tasks", Tag.TAG_COMPOUND.toInt()) for (tag in list) { - val task = MatterTask.deserializeNBT(tag) + val task = ReplicationTask.deserializeNBT(tag) if (task != null) { - _tasks[task.id()] = task + _tasks[task.id] = task } } } - override fun getTask(id: UUID): MatterTask? { - return _tasks[id] + override fun getTask(id: UUID): ReplicationTask? { + return _tasks[id]?.asImmutable() } fun removeTask(id: UUID) { @@ -185,19 +179,17 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : (matterNode.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task) - listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(task) } + listeners.forEach { it.taskRemoved(task) } setChanged() } - fun removeTask(state: PatternState) = removeTask(state.id) - - fun addTask(state: PatternState, how_much: Int): MatterTask { - val task = MatterTask(UUID.randomUUID(), state.id, state.item, 0, 0, how_much) - _tasks[task.id()] = task + fun addTask(state: IPatternState, count: Int): IReplicationTask<*> { + val task = ReplicationTask(UUID.randomUUID(), state.id, state.item, 0, 0, count) + _tasks[task.id] = task (matterNode.graph as MatterNetworkGraph?)?.onMatterTaskCreated(task) - listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(task) } + listeners.forEach { it.taskUpdated(task) } setChanged() return 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 aaa58728c..edffdc60d 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 @@ -35,7 +35,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : class ReplicatorJob : ItemJob { val matterPerTick: ImpreciseFraction - val task: MatterTask + val task: ReplicationTask var matterValue: ImpreciseFraction val pattern: PatternState? val asDust: Boolean @@ -45,13 +45,13 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : matterValue = tag.getImpreciseFraction("value") pattern = tag.map("pattern", PatternState::deserializeNBT) asDust = tag.getBoolean("as_dust") - task = tag.map("task", MatterTask::deserializeNBT) ?: throw NullPointerException("Unable to deserialize matter task") + task = tag.map("task", ReplicationTask::deserializeNBT) ?: throw NullPointerException("Unable to deserialize matter task") } constructor( itemStack: ItemStack, matterPerTick: ImpreciseFraction, - task: MatterTask, + task: ReplicationTask, matterValue: ImpreciseFraction, pattern: PatternState?, asDust: Boolean, @@ -93,7 +93,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : return Status.FAILURE_WAIT } - (matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task) + (matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id) return Status.SUCCESS } @@ -101,23 +101,23 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : return Status.FAILURE_ITEM } - (matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task) + (matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id) return Status.SUCCESS } - override fun onMatterTaskCreated(task: MatterTask) { + override fun onMatterTaskCreated(task: IReplicationTask<*>) { if (idleReason == IdleReason.OBSERVING) { isIdling = false } } - override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) { + override fun > onMatterTaskUpdated(newState: T, oldState: T) { if (idleReason == IdleReason.OBSERVING) { isIdling = false } } - override fun onPatternAdded(state: PatternState) { + override fun onPatternAdded(state: IPatternState) { if (idleReason == IdleReason.OBSERVING) { isIdling = false } @@ -149,10 +149,10 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : return ReplicatorJob( itemStack = stack, matterPerTick = matter.value / ticks, - task = allocation.task, + task = allocation.task.asImmutable(), matterValue = matter.value, - pattern = allocation.pattern, - asDust = (level?.random?.nextDouble() ?: 1.0) > (allocation.pattern?.research ?: 2.0), + pattern = allocation.pattern?.asImmutable(), + asDust = (level?.random?.nextDouble() ?: 1.0) > (allocation.pattern?.researchPercent ?: 2.0), ticks = ticks, ) to null } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt index cfa8e5e8b..a604d99c4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt @@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage +import ru.dbotthepony.mc.otm.capability.matter.IPatternState import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainerFilter @@ -47,19 +48,19 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : }) // IMatterGraphNode - override fun onPatternAdded(state: PatternState) { + override fun onPatternAdded(state: IPatternState) { if (idleReason == IdleReason.OBSERVING) { isIdling = false } } - override fun onPatternRemoved(state: PatternState) { + override fun onPatternRemoved(state: IPatternState) { if (idleReason == IdleReason.OBSERVING) { isIdling = false } } - override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) { + override fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) { if (idleReason == IdleReason.OBSERVING) { isIdling = false } @@ -122,22 +123,19 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : val stack = job.itemStack if (stack.isEmpty || !hasMatterValue(stack)) return Status.SUCCESS - val getState = grid.findPatterns(stack.item) - var findState: PatternState? = null + var findState: IPatternState? = null - for (state in getState) { - if (state.item() === stack.item) { - if (findState == null && state.research() < 1.0) { - findState = state - } else if (findState != null && findState.research() < state.research()) { - findState = state - } + for (state in grid.patterns.filter { it.item === stack.item }) { + if (findState == null && state.researchPercent < 1.0) { + findState = state + } else if (findState != null && findState.researchPercent < state.researchPercent) { + findState = state } } val new = if (findState != null) { - PatternState(findState.id(), stack.item, findState.research() + 0.2) + PatternState(findState.id, stack.item, findState.researchPercent + 0.2) } else { PatternState(UUID.randomUUID(), stack.item, 0.2) } @@ -159,20 +157,19 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : val stack = container.getItem(0) if (stack.isEmpty || !canDecompose(stack)) return null to IdleReason.ITEM - val getState = grid.findPatterns(stack.item) - var findState: PatternState? = null + var findState: IPatternState? = null - for (state in getState) { - if (state.item === stack.item && state.research < 1.0) { + for (state in grid.patterns.filter { it.item === stack.item }) { + if (state.researchPercent < 1.0) { findState = state - } else if (state.item === stack.item && state.research >= 1.0) { - return null to IdleReason.OBSERVING + } else if (state.researchPercent >= 1.0) { + return null to IdleReason.ITEM } } - val new: PatternState = + val new: IPatternState = if (findState != null) { - PatternState(findState.id, stack.item, findState.research + 0.2) + PatternState(findState.id, stack.item, findState.researchPercent + 0.2) } else { PatternState(UUID.randomUUID(), stack.item, 0.2) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/API.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/API.kt index 4362f0e79..c7ebe7311 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/API.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/API.kt @@ -5,6 +5,7 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction import java.util.* import java.util.function.Predicate import java.util.stream.Collectors +import java.util.stream.Stream interface IMatterHandler { val storedMatter: ImpreciseFraction @@ -14,6 +15,7 @@ interface IMatterHandler { fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction + val direction: MatterDirection val missingMatter: ImpreciseFraction get() = maxStoredMatter.minus(storedMatter).moreThanZero() @@ -27,42 +29,44 @@ interface IMatterHandler { enum class MatterDirection { RECEIVE, EXTRACT, BIDIRECTIONAL } -interface IMatterTaskProvider { +interface IReplicationTaskProvider { /** - * @return immutable collection of tasks that can be allocated by a worker + * It must return new stream each time */ - val tasks: Collection + val replicationTasks: Stream> /** - * @return immutable collection of all stored tasks, even fully allocated by workers + * It must return new stream each time */ - val allTasks: Collection + val allReplicationTasks: Stream> /** * Allocates (marks as work-in-progress) a task - * by incrementing it's in_progress by 1 - * and shrinking required by 1 + * by incrementing it's [IReplicationTask.inProgress] by 1 + * and shrinking [IReplicationTask.required] by 1 * - * If required == 0, it should not be returned by this method + * If [IReplicationTask.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 */ - fun allocateTask(simulate: Boolean): MatterTaskAllocation? + fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? /** * Notify about task completion. If this provider indeed contain this task, it should * shrink in_progress by 1 * If in_progress == 0 and required == 0, it should discard the task - * @param task task being completed. this method should ignore tasks that are not owned by it. + * @param taskId task being completed. this method should ignore tasks that are not owned by it. * @return whenever task indeed belong to this provider and internal state was updated */ - fun notifyTaskCompletion(task: MatterTask): Boolean + fun notifyTaskCompletion(taskId: UUID): Boolean /** * @param id uuid of task * @return MatterTask that this capability holds with this id, or null */ - fun getTask(id: UUID): MatterTask? + fun getTask(id: UUID): IReplicationTask<*>? { + return allReplicationTasks.filter { it.id == id }.findAny().orElse(null) + } /** * Destroys all tasks this capability contains @@ -72,50 +76,36 @@ interface IMatterTaskProvider { interface IPatternStorage { /** - * @return unmodifiable collection of stored patterns + * It must return new stream each time */ - val storedPatterns: Collection + val storedPatterns: Stream - fun findPatterns(item: Item): Collection { - return findPatterns { item2: PatternState -> item == item2.item() } + fun findPatterns(item: Item): Collection { + return findPatterns { item == it.item } } - fun findPatterns(predicate: Predicate?): Collection { - return storedPatterns.stream().filter(predicate).collect(Collectors.toList()) + fun findPatterns(predicate: Predicate): Collection { + return storedPatterns.filter(predicate).collect(Collectors.toList()) } - fun findPattern(item: Item): PatternState? { - return findPattern { item2: PatternState -> item == item2.item() } + fun findPattern(item: Item): IPatternState? { + return storedPatterns.filter { it.item == item }.findAny().orElse(null) } - fun findPattern(predicate: Predicate): PatternState? { - for (pattern in storedPatterns) { - if (predicate.test(pattern)) { - return pattern - } - } - - return null + fun getPattern(id: UUID?): IPatternState? { + return storedPatterns.filter { it.id == id }.findAny().orElse(null) } - fun getPattern(id: UUID?): PatternState? { - id ?: return null - - for (pattern in storedPatterns) { - if (pattern.id == id) { - return pattern - } - } - - return null + fun hasPattern(item: Item): Boolean { + return storedPatterns.filter { it.item == item }.findAny().isPresent } - fun hasPattern(state: PatternState): Boolean { - return getPattern(state.id) != null + fun hasPattern(state: IPatternState): Boolean { + return hasPattern(state.id) } fun hasPattern(id: UUID?): Boolean { - return getPattern(id) != null + return storedPatterns.filter { it.id == id }.findAny().isPresent } val capacity: Int @@ -126,17 +116,17 @@ interface IPatternStorage { * and if it fail, try only_update = false * * @param pattern pattern to be inserted or update value from - * @param only_update do not insert new pattern if this pattern's UUID is not matched + * @param onlyUpdate do not insert new pattern if this pattern's UUID is not matched * @param simulate whenever to affect state * @return record of status of the operation (at status() FAIL, UPDATED, INSERTED) as well as new_state and old_state */ - fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus + fun insertPattern(pattern: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus - fun insertPattern(pattern: PatternState, simulate: Boolean): PatternInsertStatus { + fun insertPattern(pattern: IPatternState, simulate: Boolean): PatternInsertStatus { return insertPattern(pattern, false, simulate) } - fun updatePattern(pattern: PatternState, simulate: Boolean): PatternInsertStatus { + fun updatePattern(pattern: IPatternState, simulate: Boolean): PatternInsertStatus { return insertPattern(pattern, true, simulate) } } 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 9ca6150db..78df561cc 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 @@ -8,17 +8,17 @@ private enum class PatternInsertResult { sealed class PatternInsertStatus( private val status: PatternInsertResult, - val newState: PatternState?, - val oldState: PatternState? + val newState: IPatternState?, + val oldState: IPatternState? ) { - val isFailed get() = status === PatternInsertResult.FAIL - val isUpdated get() = status === PatternInsertResult.UPDATED - val isInserted get() = status === PatternInsertResult.INSERTED + val isFailed get() = status == PatternInsertResult.FAIL + val isUpdated get() = status == PatternInsertResult.UPDATED + val isInserted get() = status == PatternInsertResult.INSERTED } object PatternInsertFailure : PatternInsertStatus(PatternInsertResult.FAIL, null, null) -class PatternInsertUpdated(new: PatternState, old: PatternState) : PatternInsertStatus(PatternInsertResult.UPDATED, new, old) -class PatternInsertInserted(new: PatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null) +class PatternInsertUpdated(new: IPatternState, old: IPatternState) : PatternInsertStatus(PatternInsertResult.UPDATED, new, old) +class PatternInsertInserted(new: IPatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null) @JvmRecord -data class MatterTaskAllocation(val task: MatterTask, val pattern: PatternState?) +data class ReplicationTaskAllocation(val task: IReplicationTask<*>, val pattern: IPatternState?) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt new file mode 100644 index 000000000..c53bcc134 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/PatternState.kt @@ -0,0 +1,146 @@ +package ru.dbotthepony.mc.otm.capability.matter + +import net.minecraft.nbt.CompoundTag +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.* +import java.util.* + +sealed interface IPatternState { + val id: UUID + val item: Item + val researchPercent: Double + + fun asMutable(): MutablePatternState + fun asImmutable() : PatternState + + fun matchId(other: IPatternState): Boolean { + return other.id == id + } + + fun copyAsMutable( + id: UUID = this.id, + item: Item = this.item, + researchPercent: Double = this.researchPercent, + ): MutablePatternState { + return MutablePatternState(id, item, researchPercent) + } + + fun copyAsImmutable( + id: UUID = this.id, + item: Item = this.item, + researchPercent: Double = this.researchPercent, + ) : PatternState { + return PatternState(id, item, researchPercent) + } + + fun stack(count: Int = 1): ItemStack { + return ItemStack(item, count) + } + + fun serializeNBT(): CompoundTag { + return CompoundTag().also { + it["id"] = id + it["item"] = item.registryName!!.toString() + it["researchPercent"] = researchPercent + } + } + + fun write(buff: FriendlyByteBuf) { + buff.writeUUID(id) + buff.writeItemType(item) + buff.writeDouble(researchPercent) + } +} + +private fun deserializeNBT(nbt: Tag?, mutable: Boolean): IPatternState? { + if (nbt !is CompoundTag) + return null + + if (!nbt.contains("id", "researchPercent", "item")) + return null + + val id = nbt.getUUID("id") + val researchPercent = nbt.getDouble("researchPercent") + val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(nbt.getString("item"))) ?: return null + + if (item == Items.AIR) + return null + + if (mutable) { + return MutablePatternState(id, item, researchPercent) + } else { + return PatternState(id, item, researchPercent) + } +} + +private fun read(buff: FriendlyByteBuf, mutable: Boolean): IPatternState? { + val id = buff.readUUID() + val item = buff.readItemType() + val researchPercent = buff.readDouble() + + item ?: return null + + if (mutable) { + return MutablePatternState(id, item, researchPercent) + } else { + return PatternState(id, item, researchPercent) + } +} + +data class PatternState( + override val id: UUID, + override val item: Item, + override val researchPercent: Double, +) : IPatternState { + override fun asMutable(): MutablePatternState { + return MutablePatternState(id, item, researchPercent) + } + + override fun asImmutable(): PatternState { + return this + } + + companion object { + fun deserializeNBT(tag: Tag?): PatternState? { + return deserializeNBT(tag, false) as PatternState? + } + + fun read(buff: FriendlyByteBuf): PatternState? { + return read(buff, false) as PatternState? + } + } +} + +data class MutablePatternState( + override val id: UUID, + override val item: Item, + override var researchPercent: Double, +) : IPatternState { + override fun asMutable(): MutablePatternState { + return this + } + + override fun asImmutable(): PatternState { + return PatternState(id, item, researchPercent) + } + + companion object { + fun deserializeNBT(tag: Tag?): MutablePatternState? { + return deserializeNBT(tag, true) as MutablePatternState? + } + + fun read(buff: FriendlyByteBuf): MutablePatternState? { + return read(buff, true) as MutablePatternState? + } + } +} + +fun FriendlyByteBuf.writePatternState(state: IPatternState) = state.write(this) +fun FriendlyByteBuf.readPatternState() = PatternState.read(this) +fun FriendlyByteBuf.readMutablePatternState() = MutablePatternState.read(this) 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 new file mode 100644 index 000000000..0dd3991d9 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/ReplicationTask.kt @@ -0,0 +1,210 @@ +package ru.dbotthepony.mc.otm.capability.matter + +import net.minecraft.nbt.CompoundTag +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.registryName +import ru.dbotthepony.mc.otm.core.set +import ru.dbotthepony.mc.otm.core.writeItemType +import java.util.UUID + +sealed interface IReplicationTask> { + val id: UUID + val patternId: UUID? + 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: UUID? = 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: UUID? = 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 { + return other.id == id + } + + fun stack(count: Int = 1): ItemStack { + return ItemStack(item, count) + } + + fun allocate(amount: Int = 1): S + fun finish(amount: Int = 1): S + + fun serializeNBT(): CompoundTag { + return CompoundTag().also { + it["id"] = id + + if (patternId != null) + it["patternId"] = patternId!! + + it["item"] = item.registryName!!.toString() + it["inProgress"] = inProgress + it["finished"] = finished + it["required"] = required + } + } + + fun write(buff: FriendlyByteBuf) { + buff.writeUUID(id) + + buff.writeBoolean(patternId != null) + patternId?.let(buff::writeUUID) + + buff.writeItemType(item) + + buff.writeInt(inProgress) + buff.writeInt(finished) + buff.writeInt(required) + } +} + +private fun deserializeNBT(nbt: Tag?, mutable: Boolean): IReplicationTask<*>? { + if (nbt !is CompoundTag) + return null + + if (!nbt.contains("id") || !nbt.contains("inProgress") || !nbt.contains("finished") || !nbt.contains("required") || !nbt.contains("item")) + return null + + val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(nbt.getString("item"))) ?: return null + + if (item == Items.AIR) + return null + + val id = nbt.getUUID("id") + val patternId = if (nbt.contains("patternId")) nbt.getUUID("patternId") else null + + val inProgress = nbt.getInt("inProgress") + val finished = nbt.getInt("finished") + val required = nbt.getInt("required") + + if (mutable) { + return MutableReplicationTask(id, patternId, item, inProgress, finished, required) + } else { + return ReplicationTask(id, patternId, item, inProgress, finished, 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, patternId, item, inProgress, finished, required) + } else { + return ReplicationTask(id, patternId, item, inProgress, finished, required) + } +} + +data class ReplicationTask( + override val id: UUID, + override val patternId: UUID?, + 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 { + return ReplicationTask(id, patternId, item, inProgress + amount, finished, required - amount) + } + + override fun finish(amount: Int): ReplicationTask { + return ReplicationTask(id, patternId, item, inProgress - amount, finished + amount, required) + } + + companion object { + fun deserializeNBT(nbt: Tag?): ReplicationTask? { + return deserializeNBT(nbt, false) as ReplicationTask? + } + + fun read(buff: FriendlyByteBuf): ReplicationTask? { + return read(buff, false) as ReplicationTask? + } + } +} + +data class MutableReplicationTask( + override val id: UUID, + override val patternId: UUID?, + 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 + } + + companion object { + fun deserializeNBT(nbt: Tag?): MutableReplicationTask? { + return deserializeNBT(nbt, true) as MutableReplicationTask? + } + + fun read(buff: FriendlyByteBuf): MutableReplicationTask? { + return read(buff, true) as MutableReplicationTask? + } + } +} + +fun FriendlyByteBuf.writeReplicationTask(task: IReplicationTask<*>) = task.write(this) +fun FriendlyByteBuf.readReplicationTask() = ReplicationTask.read(this) +fun FriendlyByteBuf.readMutableReplicationTask() = MutableReplicationTask.read(this) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatterPanelScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatterPanelScreen.kt index fab73529a..17d8008b7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatterPanelScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/MatterPanelScreen.kt @@ -5,7 +5,8 @@ import net.minecraft.client.gui.components.EditBox 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.MatterTask +import ru.dbotthepony.mc.otm.capability.matter.IPatternState +import ru.dbotthepony.mc.otm.capability.matter.IReplicationTask import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.core.TranslatableComponent @@ -70,7 +71,7 @@ class MatterPanelScreen( if (isPatternView) { return menu.patterns.getOrNull(index)?.stack() ?: ItemStack.EMPTY } else { - return menu.tasks.getOrNull(index)?.stack() ?: ItemStack.EMPTY + return menu.tasks.getOrNull(index)?.let { it.stack(it.required + it.inProgress) } ?: ItemStack.EMPTY } } @@ -81,14 +82,14 @@ class MatterPanelScreen( menu.patterns.getOrNull(index)?.let { list.add(TranslatableComponent( "otm.item.pattern.research", - String.format("%.2f", it.research() * 100.0) + String.format("%.2f", it.researchPercent * 100.0) ).withStyle(ChatFormatting.AQUA)) } } else { menu.tasks.getOrNull(index)?.let { - list.add(TranslatableComponent("otm.gui.matter_task.total", it.total()).withStyle(ChatFormatting.GRAY)) - list.add(TranslatableComponent("otm.gui.matter_task.required", it.required()).withStyle(ChatFormatting.GRAY)) - list.add(TranslatableComponent("otm.gui.matter_task.in_progress", it.in_progress()).withStyle(ChatFormatting.GRAY)) - list.add(TranslatableComponent("otm.gui.matter_task.finished", it.finished()).withStyle(ChatFormatting.GRAY)) + list.add(TranslatableComponent("otm.gui.matter_task.total", it.total).withStyle(ChatFormatting.GRAY)) + list.add(TranslatableComponent("otm.gui.matter_task.required", it.required).withStyle(ChatFormatting.GRAY)) + list.add(TranslatableComponent("otm.gui.matter_task.in_progress", it.inProgress).withStyle(ChatFormatting.GRAY)) + list.add(TranslatableComponent("otm.gui.matter_task.finished", it.finished).withStyle(ChatFormatting.GRAY)) } } @@ -115,7 +116,7 @@ class MatterPanelScreen( return frame } - private fun openTask(task: MatterTask) { + private fun openTask(task: IReplicationTask<*>) { val frame = FramePanel.padded(this, null, 170f, 20f, TranslatableComponent("otm.container.matter_panel.task")) object : AbstractSlotPanel(this@MatterPanelScreen, frame) { @@ -155,7 +156,7 @@ class MatterPanelScreen( frame.toScreenCenter() } - private fun openPattern(pattern: PatternState) { + private fun openPattern(pattern: IPatternState) { val frame = FramePanel.padded(this, null, 213f, (ButtonPanel.HEIGHT + 3f) * 4f, TranslatableComponent("otm.container.matter_panel.task")) val rowTop = EditablePanel(this, frame, height = ButtonPanel.HEIGHT) @@ -186,7 +187,7 @@ class MatterPanelScreen( return super.getItemStackTooltip(stack).toMutableList().also { it.add(TranslatableComponent( "otm.item.pattern.research", - String.format("%.2f", pattern.research() * 100.0) + String.format("%.2f", pattern.researchPercent * 100.0) ).withStyle(ChatFormatting.AQUA)) } } @@ -236,7 +237,7 @@ class MatterPanelScreen( } catch (_: NumberFormatException) { } - MenuNetworkChannel.sendToServer(ReplicationRequestPacket(pattern, value)) + MenuNetworkChannel.sendToServer(ReplicationRequestPacket(pattern.id, value)) frame.remove() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/CapabilityIterators.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/CapabilityIterators.kt index c8c756788..a04c6358b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/CapabilityIterators.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/CapabilityIterators.kt @@ -56,4 +56,4 @@ class MutableCapabilityIterator

(override val parent: fun Container.iterator(cap: Capability) = CapabilityIterator(iterator().nonEmpty(), cap) fun

Iterator

.filtered(cap: Capability) = CapabilityIterator(this, cap) -fun

MutableIterator

.filtered(cap: Capability) = MutableCapabilityIterator(this, cap) \ No newline at end of file +fun

MutableIterator

.filtered(cap: Capability) = MutableCapabilityIterator(this, cap) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/CompoundTagExt.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/CompoundTagExt.kt index 5e8f59e33..1aad61935 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/CompoundTagExt.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/CompoundTagExt.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.core import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag +import java.util.UUID operator fun CompoundTag.set(index: String, value: Tag) = put(index, value) operator fun CompoundTag.set(index: String, value: Int) = putInt(index, value) @@ -16,6 +17,18 @@ operator fun CompoundTag.set(index: String, value: ByteArray) = putByteArray(i operator fun CompoundTag.set(index: String, value: IntArray) = putIntArray(index, value) operator fun CompoundTag.set(index: String, value: LongArray) = putLongArray(index, value) +operator fun CompoundTag.set(index: String, value: UUID) = putUUID(index, value) + +fun CompoundTag.contains(vararg keys: String): Boolean { + for (key in keys) { + if (!contains(key)) { + return false + } + } + + return true +} + inline fun CompoundTag.map(s: String, consumer: (T) -> R): R? { val tag = get(s) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt index 668d540bf..e8688386c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt @@ -10,11 +10,17 @@ import net.minecraft.nbt.ByteArrayTag import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag import net.minecraft.network.FriendlyByteBuf +import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.Entity +import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.phys.Vec3 import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.items.IItemHandler +import net.minecraftforge.registries.ForgeRegistries +import net.minecraftforge.registries.ForgeRegistry +import net.minecraftforge.registries.IForgeRegistry +import net.minecraftforge.registries.RegistryManager import java.math.BigInteger /** @@ -299,3 +305,23 @@ inline fun ImmutableList(size: Int, initializer: (index: Int) -> T): Immutab } } } + +fun IForgeRegistry.getID(value: T): Int { + return (this as ForgeRegistry).getID(value) +} + +fun IForgeRegistry.getValue(index: Int): T? { + return (this as ForgeRegistry).getValue(index) +} + +fun IForgeRegistry<*>.getID(value: ResourceLocation): Int { + return (this as ForgeRegistry<*>).getID(value) +} + +fun FriendlyByteBuf.writeItemType(value: Item) { + writeInt(ForgeRegistries.ITEMS.getID(value)) +} + +fun FriendlyByteBuf.readItemType(): Item? { + return ForgeRegistries.ITEMS.getValue(readInt()) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphNode.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphNode.kt index 7ae1750aa..c1c995cfc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphNode.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/IMatterGraphNode.kt @@ -4,20 +4,20 @@ import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.graph.Graph6Node interface IMatterGraphListener { - fun onPatternAdded(state: PatternState) {} - fun onPatternRemoved(state: PatternState) {} - fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {} + fun onPatternAdded(state: IPatternState) {} + fun onPatternRemoved(state: IPatternState) {} + fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) {} - fun onMatterTaskCreated(task: MatterTask) {} - fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {} - fun onMatterTaskFinished(state: MatterTask) {} - fun onMatterTaskRemoved(state: MatterTask) {} + fun onMatterTaskCreated(task: IReplicationTask<*>) {} + fun > onMatterTaskUpdated(newState: T, oldState: T) {} + fun onMatterTaskFinished(state: IReplicationTask<*>) {} + fun onMatterTaskRemoved(state: IReplicationTask<*>) {} } interface IMatterGraphNode : IMatterGraphListener { fun getMatterHandler(): IMatterHandler? = null fun getPatternHandler(): IPatternStorage? = null - fun getTaskHandler(): IMatterTaskProvider? = null + fun getTaskHandler(): IReplicationTaskProvider? = null val matterNode: Graph6Node val matterGraph: MatterNetworkGraph? get() = matterNode.graph as MatterNetworkGraph? diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt index 88100391a..f15adf116 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.graph.matter +import com.google.common.collect.Streams import net.minecraft.server.level.ServerLevel import net.minecraft.world.item.Item import net.minecraft.world.level.block.entity.BlockEntity @@ -9,7 +10,8 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.Abstract6Graph import ru.dbotthepony.mc.otm.graph.Graph6Node import java.util.* -import kotlin.collections.ArrayList +import java.util.function.Predicate +import java.util.stream.Stream import kotlin.collections.HashSet @Suppress("unused") @@ -31,26 +33,26 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe val tasks = node.value.getTaskHandler() if (tasks != null) { - for (task in tasks.tasks) { + for (task in tasks.replicationTasks) { onMatterTaskRemoved(task) } } - for (pattern in getStoredPatterns()) { + for (pattern in this.patterns) { node.value.onPatternRemoved(pattern) } - for (task in getTasks()) { + for (task in this.tasks) { node.value.onMatterTaskRemoved(task) } } override fun onNodeAdded(node: Graph6Node) { - for (pattern in getStoredPatterns()) { + for (pattern in this.patterns) { node.value.onPatternAdded(pattern) } - for (task in getTasks()) { + for (task in this.tasks) { node.value.onMatterTaskCreated(task) } @@ -65,7 +67,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe val tasks = node.value.getTaskHandler() if (tasks != null) { - for (task in tasks.tasks) { + for (task in tasks.replicationTasks) { onMatterTaskCreated(task) } } @@ -103,6 +105,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe if (howMuch <= ImpreciseFraction.ZERO) return ImpreciseFraction.ZERO + @Suppress("name_shadowing") var howMuch = howMuch var extracted = ImpreciseFraction.ZERO @@ -126,6 +129,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe if (howMuch <= ImpreciseFraction.ZERO) return ImpreciseFraction.ZERO + @Suppress("name_shadowing") var howMuch = howMuch var received = ImpreciseFraction.ZERO @@ -149,6 +153,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe if (howMuch <= ImpreciseFraction.ZERO) return ImpreciseFraction.ZERO + @Suppress("name_shadowing") var howMuch = howMuch var received = ImpreciseFraction.ZERO @@ -168,7 +173,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return received } - private fun _insertPattern(state: PatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus { + private fun doInsertPattern(state: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus { for (node in nodes) { val storage = node.value.getPatternHandler() @@ -184,42 +189,26 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return PatternInsertFailure } - fun insertPattern(state: PatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus { - if (onlyUpdate) return _insertPattern(state, true, simulate) - val status = _insertPattern(state, true, simulate) + fun insertPattern(state: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus { + if (onlyUpdate) return doInsertPattern(state, true, simulate) + val status = doInsertPattern(state, true, simulate) if (!status.isFailed) return status - return _insertPattern(state, false, simulate) + return doInsertPattern(state, false, simulate) } - fun getTasks(): Collection { - val list = ArrayList() - - for (node in nodes) { - val tasks = node.value.getTaskHandler() - - if (tasks != null) { - list.addAll(tasks.tasks) - } - } - - return list + val tasks: Stream> get() { + return Streams.concat(*nodes.mapNotNull { it.value.getTaskHandler()?.replicationTasks }.toTypedArray()) } - fun getStoredPatterns(): Collection { - val list = ArrayList() - - for (node in nodes) { - val storage = node.value.getPatternHandler() - - if (storage != null) { - list.addAll(storage.storedPatterns) - } - } - - return list + val allTasks: Stream> get() { + return Streams.concat(*nodes.mapNotNull { it.value.getTaskHandler()?.allReplicationTasks }.toTypedArray()) } - fun getPatternCount(): Long { + val patterns: Stream get() { + return Streams.concat(*nodes.mapNotNull { it.value.getPatternHandler()?.storedPatterns }.toTypedArray()) + } + + val patternCount: Long get() { var value = 0L for (node in nodes) { @@ -233,7 +222,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return value } - fun getPatternCapacity(): Long { + val patternCapacity: Long get() { var value = 0L for (node in nodes) { @@ -247,7 +236,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return value } - fun getPattern(id: UUID): PatternState? { + fun getPattern(id: UUID): IPatternState? { for (node in nodes) { val storage = node.value.getPatternHandler() @@ -267,15 +256,15 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe fun hasPattern(state: PatternState) = getPattern(state.id) != null fun hasPattern(id: UUID) = getPattern(id) != null - fun findPattern(predicate: (PatternState) -> Boolean): PatternState? { + fun findPattern(predicate: Predicate): IPatternState? { for (node in nodes) { val storage = node.value.getPatternHandler() if (storage != null) { - for (state in storage.storedPatterns) { - if (predicate(state)) { - return state - } + val find = storage.storedPatterns.filter(predicate).findAny() + + if (find.isPresent) { + return find.get() } } } @@ -285,27 +274,13 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe fun findPattern(predicate: Item) = findPattern { it.item == predicate } - fun findPatterns(predicate: (PatternState) -> Boolean): Collection { - val list = ArrayList() - - for (node in nodes) { - val storage = node.value.getPatternHandler() - - if (storage != null) { - for (state in storage.storedPatterns) { - if (predicate(state)) { - list.add(state) - } - } - } - } - - return list + fun findPatterns(predicate: Predicate): List { + return patterns.filter(predicate).toList() } fun findPatterns(predicate: Item) = findPatterns { it.item == predicate } - fun allocateTask(simulate: Boolean): MatterTaskAllocation? { + fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? { for (node in nodes) { val tasks = node.value.getTaskHandler() @@ -321,49 +296,41 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return null } - fun notifyTaskCompletion(task: MatterTask): Boolean { - for (node in nodes) { - val tasks = node.value.getTaskHandler() - - if (tasks != null && tasks.notifyTaskCompletion(task)) { - return true - } - } - - return false + fun notifyTaskCompletion(taskId: UUID): Boolean { + return nodes.any { it.value.getTaskHandler()?.notifyTaskCompletion(taskId) == true } } - override fun onPatternAdded(state: PatternState) { + override fun onPatternAdded(state: IPatternState) { for (node in nodes) node.value.onPatternAdded(state) for (node in listeners) node.onPatternAdded(state) } - override fun onPatternRemoved(state: PatternState) { + override fun onPatternRemoved(state: IPatternState) { for (node in nodes) node.value.onPatternRemoved(state) for (node in listeners) node.onPatternRemoved(state) } - override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) { - for (node in nodes) node.value.onPatternUpdated(new_state, old_state) - for (node in listeners) node.onPatternUpdated(new_state, old_state) + override fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) { + for (node in nodes) node.value.onPatternUpdated(newState, oldState) + for (node in listeners) node.onPatternUpdated(newState, oldState) } - override fun onMatterTaskCreated(task: MatterTask) { + override fun onMatterTaskCreated(task: IReplicationTask<*>) { for (node in nodes) node.value.onMatterTaskCreated(task) for (node in listeners) node.onMatterTaskCreated(task) } - override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) { - for (node in nodes) node.value.onMatterTaskUpdated(new_state, old_state) - for (node in listeners) node.onMatterTaskUpdated(new_state, old_state) + override fun > onMatterTaskUpdated(newState: T, oldState: T) { + for (node in nodes) node.value.onMatterTaskUpdated(newState, oldState) + for (node in listeners) node.onMatterTaskUpdated(newState, oldState) } - override fun onMatterTaskFinished(state: MatterTask) { + override fun onMatterTaskFinished(state: IReplicationTask<*>) { for (node in nodes) node.value.onMatterTaskFinished(state) for (node in listeners) node.onMatterTaskFinished(state) } - override fun onMatterTaskRemoved(state: MatterTask) { + override fun onMatterTaskRemoved(state: IReplicationTask<*>) { for (node in nodes) node.value.onMatterTaskRemoved(state) for (node in listeners) node.onMatterTaskRemoved(state) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PatternStorageItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PatternStorageItem.kt index d0b542d6d..e8bdab4d2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/PatternStorageItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/PatternStorageItem.kt @@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.core.ifHas import java.util.* +import java.util.stream.Stream class PatternStorageItem : Item { val capacity: Int @@ -53,8 +54,8 @@ class PatternStorageItem : Item { list.add( TranslatableComponent( "otm.item.pattern.line", - state.item().getName(ItemStack(state.item(), 1)), - String.format("%.2f", state.research() * 100.0) + state.item.getName(ItemStack(state.item, 1)), + String.format("%.2f", state.researchPercent * 100.0) ).withStyle(ChatFormatting.AQUA) ) } @@ -71,47 +72,40 @@ class PatternStorageItem : Item { } override val stored: Int get() { - return storedPatterns.size + stack.tag?.ifHas("otm_patterns", ListTag::class.java) { + return it.size + } + + return 0 } override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - return if (cap === MatteryCapability.PATTERN) resolver.cast() else LazyOptional.empty() + return if (cap == MatteryCapability.PATTERN) resolver.cast() else LazyOptional.empty() } - override val storedPatterns: Collection get() { + override val storedPatterns: Stream get() { stack.tag?.ifHas("otm_patterns", ListTag::class.java) { - val list = ArrayList() - - for (tag in it) { - if (tag is CompoundTag) { - val state = PatternState.deserializeNBT(tag) - - if (state != null) - list.add(state) - } - } - - return list + return it.stream().map { PatternState.deserializeNBT(it) }.filter { it != null } as Stream } - return emptyList() + return Stream.empty() } override fun insertPattern( - pattern: PatternState, - only_update: Boolean, + pattern: IPatternState, + onlyUpdate: Boolean, simulate: Boolean ): PatternInsertStatus { val tag = stack.orCreateTag var list = tag["otm_patterns"] if (list !is ListTag) { - if (only_update) + if (onlyUpdate) return PatternInsertFailure if (simulate) { if (capacity > 0) - return PatternInsertInserted(pattern) + return PatternInsertInserted(pattern.asImmutable()) else return PatternInsertFailure } @@ -126,24 +120,24 @@ class PatternStorageItem : Item { val state = PatternState.deserializeNBT(list.getCompound(i)) if (state != null) { - if (state == pattern) { + if (state.id == pattern.id) { if (!simulate) { list[i] = pattern.serializeNBT() } - return PatternInsertUpdated(pattern, state) + return PatternInsertUpdated(pattern.asImmutable(), state) } } else { invalidCounter++ } } - if (only_update || capacity <= list.size - invalidCounter) + if (onlyUpdate || capacity <= list.size - invalidCounter) return PatternInsertFailure if (invalidCounter > 0) { if (simulate) - return PatternInsertInserted(pattern) + return PatternInsertInserted(pattern.asImmutable()) for (i in list.indices) { val state = PatternState.deserializeNBT(list.getCompound(i)) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterPanelMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterPanelMenu.kt index 3f0e02e76..bb09664b1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterPanelMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterPanelMenu.kt @@ -9,8 +9,7 @@ import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.PacketDistributor import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.block.entity.matter.MatterPanelBlockEntity -import ru.dbotthepony.mc.otm.capability.matter.MatterTask -import ru.dbotthepony.mc.otm.capability.matter.PatternState +import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph @@ -40,7 +39,7 @@ class CancelTaskPacket(val id: UUID) : MatteryPacket { } } -class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection) : MatteryPacket { +class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection) : MatteryPacket { override fun write(buff: FriendlyByteBuf) { buff.writeBoolean(isUpdate) buff.writeInt(patterns.size) @@ -74,7 +73,7 @@ class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection) : MatteryPacket { +class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection>) : MatteryPacket { override fun write(buff: FriendlyByteBuf) { buff.writeBoolean(isUpdate) buff.writeInt(tasks.size) @@ -102,17 +101,17 @@ class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection val isUpdate = buff.readBoolean() val size = buff.readInt() - return TasksChangePacket(isUpdate, ArrayList(size).also { - for (i in 0 until size) it.add(MatterTask.read(buff) ?: throw NullPointerException("Unable to read PatternState from network at $i")) }) + return TasksChangePacket(isUpdate, ArrayList>(size).also { + for (i in 0 until size) it.add(buff.readReplicationTask() ?: throw NullPointerException("Unable to read Replication Task from network at $i")) }) } } } -class ReplicationRequestPacket(val state: PatternState, amount: Int) : MatteryPacket { +class ReplicationRequestPacket(val id: UUID, amount: Int) : MatteryPacket { val amount = amount.coerceAtLeast(1).coerceAtMost(99999) override fun write(buff: FriendlyByteBuf) { - state.write(buff) + buff.writeUUID(id) buff.writeInt(amount) } @@ -122,13 +121,13 @@ class ReplicationRequestPacket(val state: PatternState, amount: Int) : MatteryPa val sender = context.sender ?: return@enqueueWork val menu = sender.containerMenu as? MatterPanelMenu ?: return@enqueueWork - menu.requestReplication(sender, state, amount) + menu.requestReplication(sender, id, amount) } } companion object { fun read(buff: FriendlyByteBuf): ReplicationRequestPacket { - return ReplicationRequestPacket(PatternState.read(buff)!!, buff.readInt()) + return ReplicationRequestPacket(buff.readUUID(), buff.readInt()) } } } @@ -138,24 +137,24 @@ class MatterPanelMenu @JvmOverloads constructor( inventory: Inventory, tile: MatterPanelBlockEntity? = null ) : MatteryMenu(MMenus.MATTER_PANEL, p_38852_, inventory, tile), IMatterGraphListener { - fun taskUpdated(task: MatterTask) { + fun taskUpdated(task: IReplicationTask<*>) { sendNetwork(TasksChangePacket(true, listOf(task))) } - fun taskRemoved(task: MatterTask) { + fun taskRemoved(task: IReplicationTask<*>) { sendNetwork(TasksChangePacket(false, listOf(task))) } // client code - val patterns = ArrayList() - val tasks = ArrayList() + val patterns = ArrayList() + val tasks = ArrayList>() var changeset = 0 - fun networkPatternsUpdated(patterns: Collection) { + fun networkPatternsUpdated(patterns: Collection) { changeset++ for (pattern in patterns) { - val index = this.patterns.indexOf(pattern) + val index = this.patterns.indexOfFirst(pattern::matchId) if (index != -1) { this.patterns[index] = pattern @@ -165,7 +164,7 @@ class MatterPanelMenu @JvmOverloads constructor( } } - fun networkPatternsRemoved(patterns: Collection) { + fun networkPatternsRemoved(patterns: Collection) { changeset++ for (pattern in patterns) { @@ -173,11 +172,11 @@ class MatterPanelMenu @JvmOverloads constructor( } } - fun networkTasksUpdated(tasks: Collection) { + fun networkTasksUpdated(tasks: Collection>) { changeset++ for (task in tasks) { - val index = this.tasks.indexOf(task) + val index = this.tasks.indexOfFirst(task::matchId) if (index != -1) { this.tasks[index] = task @@ -185,39 +184,40 @@ class MatterPanelMenu @JvmOverloads constructor( this.tasks.add(task) } - watcher_update?.accept(task) + updateWatcher?.accept(task) } } - fun networkTasksRemoved(tasks: Collection) { + fun networkTasksRemoved(tasks: Collection>) { changeset++ for (task in tasks) { this.tasks.remove(task) - watcher_delete?.accept(task) + deleteWatcher?.accept(task) } } - private var watcher_delete: Consumer? = null - private var watcher_update: Consumer? = null + private var deleteWatcher: Consumer>? = null + private var updateWatcher: Consumer>? = null - fun networkTaskWatcher(watcher_update: Consumer, watcher_delete: Consumer) { - this.watcher_delete = watcher_delete - this.watcher_update = watcher_update + fun networkTaskWatcher(updateWatcher: Consumer>, deleteWatcher: Consumer>) { + this.deleteWatcher = deleteWatcher + this.updateWatcher = updateWatcher } // server code - fun requestReplication(ply: ServerPlayer, state: PatternState, how_much: Int) { + fun requestReplication(ply: ServerPlayer, id: UUID, count: Int) { val tile = tile as MatterPanelBlockEntity? ?: return val graph = tile.matterGraph ?: return + val state = graph.getPattern(id) - if (graph.getPattern(state) == null) { - OverdriveThatMatters.LOGGER.error("Received replication request from {} of {}, but it is no longer in grid", ply, state) + if (state == null) { + OverdriveThatMatters.LOGGER.error("Received replication request from {} of {}, but it is not found in grid", ply, id) return } - tile.addTask(state, how_much) + tile.addTask(state, count) } fun receiveTaskCancel(ply: ServerPlayer, id: UUID) { @@ -228,19 +228,19 @@ class MatterPanelMenu @JvmOverloads constructor( MenuNetworkChannel.sendToServer(CancelTaskPacket(id)) } - override fun onPatternAdded(state: PatternState) { + override fun onPatternAdded(state: IPatternState) { sendNetwork(PatternsChangePacket(true, listOf(state))) } - override fun onPatternRemoved(state: PatternState) { + override fun onPatternRemoved(state: IPatternState) { sendNetwork(PatternsChangePacket(false, listOf(state))) } - override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) { - sendNetwork(PatternsChangePacket(true, listOf(new_state))) + override fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) { + sendNetwork(PatternsChangePacket(true, listOf(newState))) } - private var initial_send = false + private var initialSend = false private var listeningGrid: MatterNetworkGraph? = null @@ -260,7 +260,7 @@ class MatterPanelMenu @JvmOverloads constructor( override fun broadcastChanges() { super.broadcastChanges() - if (!initial_send) fullPatternBroadcast() + if (!initialSend) fullPatternBroadcast() } private fun sendNetwork(packet: Any) { @@ -269,7 +269,7 @@ class MatterPanelMenu @JvmOverloads constructor( fun fullPatternBroadcast() { if (inventory.player.level.isClientSide) { - initial_send = true + initialSend = true return } @@ -279,11 +279,11 @@ class MatterPanelMenu @JvmOverloads constructor( val grid = tile.matterGraph if (grid != null) { - initial_send = true - sendNetwork(PatternsChangePacket(true, grid.getStoredPatterns())) + initialSend = true + sendNetwork(PatternsChangePacket(true, grid.patterns.toList())) } - sendNetwork(TasksChangePacket(true, tile.allTasks)) + sendNetwork(TasksChangePacket(true, tile.allReplicationTasks.toList())) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterScannerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterScannerMenu.kt index fa796cb87..12e05363e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterScannerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatterScannerMenu.kt @@ -36,10 +36,10 @@ class MatterScannerMenu @JvmOverloads constructor( addSlot(input) if (tile != null) { - progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }, tile::isUnableToProcess) + progress = ProgressGaugeWidget(this, tile::workProgress, tile::isUnableToProcess) patterns = LevelGaugeWidget(this, - { ImpreciseFraction(tile.matterGraph?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) }, - { ImpreciseFraction(tile.matterGraph?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) }) + { ImpreciseFraction(tile.matterGraph?.patternCount ?: 0L) }, + { ImpreciseFraction(tile.matterGraph?.patternCapacity ?: 0L) }) } else { progress = ProgressGaugeWidget(this) patterns = LevelGaugeWidget(this) @@ -49,4 +49,4 @@ class MatterScannerMenu @JvmOverloads constructor( } override val storageSlots: List = listOf(input) -} \ No newline at end of file +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/PatternStorageMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/PatternStorageMenu.kt index b26c70b99..a7b456194 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/PatternStorageMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/PatternStorageMenu.kt @@ -28,9 +28,9 @@ class PatternStorageMenu @JvmOverloads constructor( } else { storedThis = LevelGaugeWidget(this, tile) storedGrid = LevelGaugeWidget(this, { - ImpreciseFraction(tile.matterGraph?.getPatternCount() ?: 0) + ImpreciseFraction(tile.matterGraph?.patternCount ?: 0) }, { - ImpreciseFraction(tile.matterGraph?.getPatternCapacity() ?: 0) + ImpreciseFraction(tile.matterGraph?.patternCapacity ?: 0) }) }