Add network stack receiver priority

This commit is contained in:
Shadowfacts 2021-03-03 23:13:09 -05:00
parent 868b0d42f9
commit 8dbccc541e
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
8 changed files with 90 additions and 7 deletions

View File

@ -39,7 +39,7 @@ class ExtractorBlockEntity: DeviceBlockEntity(PhyBlockEntities.EXTRACTOR),
private var inventory: FixedItemInv? = null
override val pendingInsertions = mutableListOf<PendingInsertion>()
override val dispatchStackTimeout = 40L
override val dispatchStackTimeout = 1L
override val controller = ActivationController(SLEEP_TIME, this)
fun updateInventory() {

View File

@ -33,6 +33,7 @@ class InterfaceBlockEntity: DeviceBlockEntity(PhyBlockEntities.INTERFACE),
get() = cachedState[FaceDeviceBlock.FACING]
override var providerPriority = 0
override var receiverPriority = 0
// todo: should this be a weak ref?
private var inventory: GroupedItemInv? = null
@ -119,10 +120,12 @@ class InterfaceBlockEntity: DeviceBlockEntity(PhyBlockEntities.INTERFACE),
override fun writeDeviceConfiguration(tag: CompoundTag) {
tag.putInt("ProviderPriority", providerPriority)
tag.putInt("ReceiverPriority", receiverPriority)
}
override fun loadDeviceConfiguration(tag: CompoundTag) {
providerPriority = tag.getInt("ProviderPriority")
receiverPriority = tag.getInt("ReceiverPriority")
}
}

View File

@ -41,10 +41,10 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
NetworkStackDispatcher<TerminalBlockEntity.PendingInsertion> {
companion object {
// the locate request timeout is only 1 tick because that's long enough to hear from every device on the network
// the locate/insertion timeouts are only 1 tick because that's long enough to hear from every device on the network
// in a degraded state (when there's latency in the network), not handling interface priorities correctly is acceptable
val LOCATE_REQUEST_TIMEOUT: Long = 1 // ticks
val INSERTION_TIMEOUT: Long = 40
val INSERTION_TIMEOUT: Long = 1
}
private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInvView>()

View File

@ -44,8 +44,15 @@ interface NetworkStackDispatcher<Insertion: NetworkStackDispatcher.PendingInsert
fun finishInsertion(insertion: Insertion): ItemStack {
pendingInsertions.remove(insertion)
// todo: also sort results by interface priority
val sortedResults = insertion.results.sortedBy { it.first }.toMutableList()
val sortedResults = insertion.results.toMutableList()//.sortedBy { it.first }.toMutableList()
sortedResults.sortWith { a, b ->
// sort results first by receiver priority, and then by capacity
if (a.second.receiverPriority == b.second.receiverPriority) {
b.first - a.first
} else {
b.second.receiverPriority - a.second.receiverPriority
}
}
// copy the insertion stack so subclasses that override this method can still see the originally dispatched stack after the super call
val remaining = insertion.stack.copy()
while (!remaining.isEmpty && sortedResults.isNotEmpty()) {
@ -70,7 +77,8 @@ interface NetworkStackDispatcher<Insertion: NetworkStackDispatcher.PendingInsert
get() = results.fold(0) { acc, (amount, _) -> acc + amount }
fun isFinishable(owner: NetworkStackDispatcher<Self>): Boolean {
return totalCapacity >= stack.count || owner.counter - timestamp >= owner.dispatchStackTimeout
// can't check totalCapacity >= stack.count because we need to wait for all responses to correctly sort by priority
return owner.counter - timestamp >= owner.dispatchStackTimeout
}
}
}

View File

@ -1,9 +1,13 @@
package net.shadowfacts.phycon.component
import net.shadowfacts.phycon.api.NetworkDevice
import net.shadowfacts.phycon.util.ClientConfigurableDevice
/**
* @author shadowfacts
*/
interface NetworkStackReceiver: NetworkDevice {
interface NetworkStackReceiver: NetworkDevice, ClientConfigurableDevice {
var receiverPriority: Int
}

View File

@ -17,6 +17,7 @@ import net.shadowfacts.phycon.block.miner.MinerBlockEntity
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlockEntity
import net.shadowfacts.phycon.component.ActivationController
import net.shadowfacts.phycon.component.NetworkStackProvider
import net.shadowfacts.phycon.component.NetworkStackReceiver
import org.lwjgl.glfw.GLFW
/**
@ -72,6 +73,13 @@ class DeviceConsoleScreen(
device::canConfigureProviderPriority
))
}
if (device is NetworkStackReceiver) {
tabs.add(TabViewController.SimpleTab(
Label("R").apply { textColor = Color.TEXT },
TranslatableText("gui.phycon.console.receiver"),
ReceiverViewController(device),
))
}
tabController = TabViewController(tabs)

View File

@ -0,0 +1,57 @@
package net.shadowfacts.phycon.screen.console
import net.minecraft.block.entity.BlockEntity
import net.minecraft.client.MinecraftClient
import net.minecraft.text.TranslatableText
import net.shadowfacts.cacao.util.Color
import net.shadowfacts.cacao.view.Label
import net.shadowfacts.cacao.view.textfield.NumberField
import net.shadowfacts.cacao.viewcontroller.ViewController
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.phycon.component.NetworkStackReceiver
import net.shadowfacts.phycon.networking.C2SConfigureDevice
/**
* @author shadowfacts
*/
class ReceiverViewController<T>(
private val device: T
): ViewController() where T: BlockEntity, T: NetworkStackReceiver {
override fun viewDidLoad() {
super.viewDidLoad()
val label = Label(TranslatableText("gui.phycon.console.receiver.priority")).apply {
textColor = Color.TEXT
}
view.addSubview(label)
val field = NumberField(device.receiverPriority) {
if (it.number != null) {
device.receiverPriority = it.number!!
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureDevice(device))
}
}
view.addSubview(field)
val desc = Label(TranslatableText("gui.phycon.console.receiver.priority_desc")).apply {
textColor = Color.TEXT
}
view.addSubview(desc)
view.solver.dsl {
field.widthAnchor equalTo 100
field.heightAnchor equalTo 20
field.rightAnchor equalTo view.rightAnchor
field.topAnchor equalTo view.topAnchor
label.centerYAnchor equalTo field.centerYAnchor
label.rightAnchor equalTo (field.leftAnchor - 4)
desc.topAnchor equalTo (field.bottomAnchor + 4)
desc.leftAnchor equalTo view.leftAnchor
desc.rightAnchor equalTo view.rightAnchor
}
}
}

View File

@ -24,6 +24,9 @@
"gui.phycon.console.provider": "Item Provider",
"gui.phycon.console.provider.priority": "Provider Priority",
"gui.phycon.console.provider.priority_desc": "When a device requests items from the network, it send requests to providers (e.g., interfaces) with higher priorities first. Priorities can be negative.",
"gui.phycon.console.receiver": "Item Receiver",
"gui.phycon.console.receiver.priority": "Receiver Priority",
"gui.phycon.console.receiver.priority_desc": "When a device puts items into the network, it starts with receiver (e.g., interfaces) with higher priorities. Priorities can be negative.",
"gui.phycon.redstone_mode.high": "High",
"gui.phycon.redstone_mode.low": "Low",
"gui.phycon.redstone_mode.toggle": "Toggle",