Send packets immediately instead of on the next tick

This commit is contained in:
Shadowfacts 2019-10-30 13:59:28 -04:00
parent 2a9fc29cdd
commit 98134825a6
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 23 additions and 32 deletions

View File

@ -14,13 +14,11 @@ import java.util.*
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), Tickable, PacketSink { abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), PacketSink {
var macAddress = MACAddress.random() var macAddress = MACAddress.random()
protected set protected set
private val sendQueue = LinkedList<Pair<Packet, WeakReference<PacketSink>>>()
override fun getMACAddress(): MACAddress { override fun getMACAddress(): MACAddress {
return macAddress return macAddress
} }
@ -33,7 +31,7 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), T
protected abstract fun handlePacket(packet: Packet) protected abstract fun handlePacket(packet: Packet)
fun acceptsPacket(packet: Packet): Boolean { protected fun acceptsPacket(packet: Packet): Boolean {
return when (packet.destination.type) { return when (packet.destination.type) {
MACAddress.Type.BROADCAST -> true MACAddress.Type.BROADCAST -> true
MACAddress.Type.UNICAST -> macAddress == packet.destination MACAddress.Type.UNICAST -> macAddress == packet.destination
@ -45,33 +43,28 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), T
return false return false
} }
fun enqueue(packet: Packet, destination: PacketSink) { fun send(packet: Packet, destination: PacketSink) {
sendQueue.add(packet to WeakReference(destination)) destination.handle(packet)
} }
// todo: better name for this // todo: better name for this
fun enqueueToSingle(packet: Packet) { fun sendToSingle(packet: Packet) {
val destinations = NetworkUtil.findDestinations(world!!, pos) val destinations = NetworkUtil.findDestinations(world!!, pos)
if (destinations.size != 1) { if (destinations.size != 1) {
// todo: handle this better // todo: handle this better
println("Can't send packet, multiple destinations available: $destinations") println("Can't send packet, multiple destinations available: $destinations")
return return
} }
enqueue(packet, destinations.first()) send(packet, destinations.first())
} }
fun enqueueToAll(packet: Packet) { fun sendToAll(packet: Packet) {
enqueueToAll(packet, NetworkUtil.findDestinations(world!!, pos)) sendToAll(packet, NetworkUtil.findDestinations(world!!, pos))
} }
fun enqueueToAll(packet: Packet, destinations: Iterable<PacketSink>) { fun sendToAll(packet: Packet, destinations: Iterable<PacketSink>) {
sendQueue.addAll(destinations.map { packet to WeakReference(it) }) destinations.forEach {
} it.handle(packet)
override fun tick() {
if (sendQueue.isNotEmpty()) {
val (packet, destination) = sendQueue.pop()
destination.get()?.handle(packet)
} }
} }
@ -86,7 +79,7 @@ abstract class DeviceBlockEntity(type: BlockEntityType<*>): BlockEntity(type), T
} }
fun onBreak() { fun onBreak() {
enqueueToAll(DeviceRemovedPacket(this)) sendToAll(DeviceRemovedPacket(this))
} }
} }

View File

@ -43,21 +43,21 @@ class InterfaceBlockEntity: DeviceBlockEntity(PhyBlockEntities.INTERFACE) {
private fun handleRequestInventory(packet: RequestInventoryPacket) { private fun handleRequestInventory(packet: RequestInventoryPacket) {
getInventory()?.also { inv -> getInventory()?.also { inv ->
enqueueToSingle(ReadInventoryPacket(inv, macAddress, packet.source)) sendToSingle(ReadInventoryPacket(inv, macAddress, packet.source))
} }
} }
private fun handleLocateStack(packet: LocateStackPacket) { private fun handleLocateStack(packet: LocateStackPacket) {
getInventory()?.also { inv -> getInventory()?.also { inv ->
val amount = inv.getAmount(packet.stack) val amount = inv.getAmount(packet.stack)
enqueueToSingle(StackLocationPacket(packet.stack, amount, this, macAddress, packet.source)) sendToSingle(StackLocationPacket(packet.stack, amount, this, macAddress, packet.source))
} }
} }
private fun handleExtractStack(packet: ExtractStackPacket) { private fun handleExtractStack(packet: ExtractStackPacket) {
getInventory()?.also { inv -> getInventory()?.also { inv ->
val extracted = inv.extract(packet.stack, packet.amount) val extracted = inv.extract(packet.stack, packet.amount)
enqueueToSingle(ItemStackPacket(extracted, macAddress, packet.source)) sendToSingle(ItemStackPacket(extracted, macAddress, packet.source))
} }
} }

View File

@ -8,7 +8,6 @@ import net.shadowfacts.phycon.init.PhyBlockEntities
import net.shadowfacts.phycon.network.DeviceBlockEntity import net.shadowfacts.phycon.network.DeviceBlockEntity
import net.shadowfacts.phycon.network.NetworkUtil import net.shadowfacts.phycon.network.NetworkUtil
import java.lang.RuntimeException import java.lang.RuntimeException
import javax.print.attribute.standard.Destination
/** /**
* @author shadowfacts * @author shadowfacts
@ -24,13 +23,13 @@ class SwitchBlockEntity: DeviceBlockEntity(PhyBlockEntities.SWITCH) {
override fun handle(packet: Packet) { override fun handle(packet: Packet) {
if (packet.destination == MACAddress.BROADCAST) { if (packet.destination == MACAddress.BROADCAST) {
val allDestinations = NetworkUtil.findDestinations(world!!, pos).filter { it.macAddress != packet.source } val allDestinations = NetworkUtil.findDestinations(world!!, pos).filter { it.macAddress != packet.source }
enqueueToAll(packet, allDestinations) sendToAll(packet, allDestinations)
} else { } else {
val direction = macTable[packet.destination] val direction = macTable[packet.destination]
if (direction != null) { if (direction != null) {
val dest = findDestination(direction) val dest = findDestination(direction)
if (dest != null && packet.destination == dest.macAddress) { if (dest != null && packet.destination == dest.macAddress) {
enqueue(packet, dest) send(packet, dest)
return return
} }
} }
@ -53,7 +52,7 @@ class SwitchBlockEntity: DeviceBlockEntity(PhyBlockEntities.SWITCH) {
val dest = findDestination(dir) val dest = findDestination(dir)
if (dest != null && packet.destination == dest.macAddress) { if (dest != null && packet.destination == dest.macAddress) {
macTable[packet.destination] = dir macTable[packet.destination] = dir
enqueue(packet, dest) send(packet, dest)
break break
} }
} }

View File

@ -13,6 +13,7 @@ import net.minecraft.inventory.InventoryListener
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag import net.minecraft.nbt.ListTag
import net.minecraft.util.Tickable
import net.shadowfacts.phycon.api.packet.Packet import net.shadowfacts.phycon.api.packet.Packet
import net.shadowfacts.phycon.api.util.MACAddress import net.shadowfacts.phycon.api.util.MACAddress
import net.shadowfacts.phycon.init.PhyBlockEntities import net.shadowfacts.phycon.init.PhyBlockEntities
@ -27,7 +28,7 @@ import kotlin.math.min
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), InventoryListener, BlockEntityClientSerializable { class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), InventoryListener, BlockEntityClientSerializable, Tickable {
companion object { companion object {
val LOCATE_REQUEST_TIMEOUT = 40 // ticks val LOCATE_REQUEST_TIMEOUT = 40 // ticks
@ -119,8 +120,6 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), Invento
} }
override fun tick() { override fun tick() {
super.tick()
if (observers > 0 && (++counter % 20) == 0) { if (observers > 0 && (++counter % 20) == 0) {
if (world!!.isClient) { if (world!!.isClient) {
println(cachedNetItems) println(cachedNetItems)
@ -137,7 +136,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), Invento
sync() sync()
inventoryCache.clear() inventoryCache.clear()
enqueueToSingle(RequestInventoryPacket(macAddress)) sendToSingle(RequestInventoryPacket(macAddress))
ContainerProviderRegistry.INSTANCE.openContainer(TerminalContainer.ID, player) { buf -> ContainerProviderRegistry.INSTANCE.openContainer(TerminalContainer.ID, player) { buf ->
buf.writeBlockPos(pos) buf.writeBlockPos(pos)
} }
@ -147,7 +146,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), Invento
fun requestItem(stack: ItemStack, amount: Int = stack.count) { fun requestItem(stack: ItemStack, amount: Int = stack.count) {
pendingRequests.add(StackLocateRequest(stack, amount, counter)) pendingRequests.add(StackLocateRequest(stack, amount, counter))
enqueueToSingle(LocateStackPacket(stack, macAddress)) sendToSingle(LocateStackPacket(stack, macAddress))
} }
private fun stackLocateRequestCompleted(request: StackLocateRequest) { private fun stackLocateRequestCompleted(request: StackLocateRequest) {
@ -158,7 +157,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), Invento
val (sourceAmount, sourceInterface) = sortedResults.removeAt(0) val (sourceAmount, sourceInterface) = sortedResults.removeAt(0)
val amountToRequest = min(sourceAmount, request.amount - amountRequested) val amountToRequest = min(sourceAmount, request.amount - amountRequested)
amountRequested += amountToRequest amountRequested += amountToRequest
enqueueToSingle(ExtractStackPacket(request.stack, amountToRequest, macAddress, sourceInterface.macAddress)) sendToSingle(ExtractStackPacket(request.stack, amountToRequest, macAddress, sourceInterface.macAddress))
} }
} }