Rename Graph to Chart, insanely more memory efficient chart networking

This commit is contained in:
DBotThePony 2024-09-24 22:52:22 +07:00
parent e49a65a2de
commit 19a7a8ddf6
Signed by: DBot
GPG Key ID: DCC23B5715498507
9 changed files with 53 additions and 70 deletions

View File

@ -4,8 +4,6 @@ import com.google.common.collect.ImmutableList
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.HolderLookup import net.minecraft.core.HolderLookup
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.IntTag
import net.minecraft.nbt.ListTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
@ -23,14 +21,12 @@ import ru.dbotthepony.mc.otm.core.math.BlockRotation
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.math.RelativeSide
import ru.dbotthepony.mc.otm.core.math.getDecimal import ru.dbotthepony.mc.otm.core.math.getDecimal
import ru.dbotthepony.mc.otm.core.nbt.getByteArrayList
import ru.dbotthepony.mc.otm.core.nbt.map import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.mapPresent import ru.dbotthepony.mc.otm.core.nbt.mapPresent
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.util.countingLazy import ru.dbotthepony.mc.otm.core.util.countingLazy
import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import java.util.*
class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) { class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) {
var passed by syncher.decimal() var passed by syncher.decimal()
@ -39,13 +35,13 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
BlockRotation.of(blockState[EnergyCounterBlock.INPUT_DIRECTION]) BlockRotation.of(blockState[EnergyCounterBlock.INPUT_DIRECTION])
} }
val history5s = DecimalHistoryGraph(1, 100) val history5s = DecimalHistoryChart(1, 100)
val history15s = DecimalHistoryGraph(3, 100) val history15s = DecimalHistoryChart(3, 100)
val history1m = DecimalHistoryGraph(12, 100) val history1m = DecimalHistoryChart(12, 100)
val history10m = DecimalHistoryGraph(120, 100) val history10m = DecimalHistoryChart(120, 100)
val history1h = DecimalHistoryGraph(720, 100) val history1h = DecimalHistoryChart(720, 100)
val history6h = DecimalHistoryGraph(720 * 6, 100) val history6h = DecimalHistoryChart(720 * 6, 100)
val history24h = DecimalHistoryGraph(720 * 24, 100) val history24h = DecimalHistoryChart(720 * 24, 100)
private val graphs = ImmutableList.of( private val graphs = ImmutableList.of(
history5s, history15s, history1m, history10m, history1h, history6h, history24h, history5s, history15s, history1m, history10m, history1h, history6h, history24h,

View File

@ -4,14 +4,14 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList
import net.minecraft.core.HolderLookup import net.minecraft.core.HolderLookup
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.neoforged.neoforge.common.util.INBTSerializable import net.neoforged.neoforge.common.util.INBTSerializable
import ru.dbotthepony.mc.otm.core.DecimalHistoryGraph import ru.dbotthepony.mc.otm.core.DecimalHistoryChart
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.nbt.map import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<CompoundTag?> { abstract class AbstractProfiledStorage<out P>(val parent: P) : INBTSerializable<CompoundTag?> {
val received = DecimalHistoryGraph(ticks = HISTORY_SIZE) val received = DecimalHistoryChart(ticks = HISTORY_SIZE)
val transferred = DecimalHistoryGraph(ticks = HISTORY_SIZE) val transferred = DecimalHistoryChart(ticks = HISTORY_SIZE)
var receivedThisTick = Decimal.ZERO var receivedThisTick = Decimal.ZERO
private set private set

View File

@ -1,9 +1,9 @@
package ru.dbotthepony.mc.otm.client.screen.panels package ru.dbotthepony.mc.otm.client.screen.panels
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.AbstractHistoryGraph import ru.dbotthepony.mc.otm.core.AbstractHistoryChart
abstract class AbstractHistoryGraphPanel<out S : MatteryScreen<*>, G : AbstractHistoryGraph<V>, V : Any>( abstract class AbstractHistoryGraphPanel<out S : MatteryScreen<*>, G : AbstractHistoryChart<V>, V : Any>(
screen: S, screen: S,
parent: EditablePanel<*>, parent: EditablePanel<*>,
val graph: G, val graph: G,

View File

@ -6,14 +6,14 @@ import ru.dbotthepony.mc.otm.client.render.GraphMouseLabels
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.renderGraph import ru.dbotthepony.mc.otm.client.render.renderGraph
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.DecimalHistoryGraph import ru.dbotthepony.mc.otm.core.DecimalHistoryChart
import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
open class DecimalHistoryGraphPanel<out S : MatteryScreen<*>>( open class DecimalHistoryChartPanel<out S : MatteryScreen<*>>(
screen: S, screen: S,
parent: EditablePanel<*>, parent: EditablePanel<*>,
val graph: DecimalHistoryGraph, val graph: DecimalHistoryChart,
val formatText: (Decimal) -> Component = { TextComponent(it.toString(2)) }, val formatText: (Decimal) -> Component = { TextComponent(it.toString(2)) },
x: Float = 0f, x: Float = 0f,
y: Float = 0f, y: Float = 0f,

View File

@ -4,7 +4,6 @@ import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.ShiftPressedCond
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.TextIcon import ru.dbotthepony.mc.otm.client.render.TextIcon
import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
@ -35,7 +34,7 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
for ((graph, text) in graphs) { for ((graph, text) in graphs) {
val tab = frame.Tab(activeIcon = TextIcon(color = RGBAColor.BLACK, font = font, text = TextComponent(text))) val tab = frame.Tab(activeIcon = TextIcon(color = RGBAColor.BLACK, font = font, text = TextComponent(text)))
val panel = DecimalHistoryGraphPanel(this, tab.canvas, graph, formatText = { it.formatPower(formatAsReadable = ShiftPressedCond) }) val panel = DecimalHistoryChartPanel(this, tab.canvas, graph, formatText = { it.formatPower(formatAsReadable = ShiftPressedCond) })
panel.dock = Dock.FILL panel.dock = Dock.FILL
} }

View File

@ -13,7 +13,7 @@ import ru.dbotthepony.mc.otm.network.syncher.IRemoteState
import ru.dbotthepony.mc.otm.network.syncher.ISynchable import ru.dbotthepony.mc.otm.network.syncher.ISynchable
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
abstract class AbstractHistoryGraph<V : Any>( abstract class AbstractHistoryChart<V : Any>(
/** /**
* How many measurements one graph value contains * How many measurements one graph value contains
*/ */
@ -67,39 +67,30 @@ abstract class AbstractHistoryGraph<V : Any>(
remotes.add(this) remotes.add(this)
} }
private var shouldFullyNetwork = true private var fresh = true
private val networkValues = ArrayList<V>() private var currentIndex = values.size
override fun write(stream: RegistryFriendlyByteBuf) { override fun write(stream: RegistryFriendlyByteBuf) {
stream.writeBoolean(shouldFullyNetwork) stream.writeBoolean(fresh)
stream.writeVarInt(currentIndex)
if (shouldFullyNetwork) { for (i in currentIndex - 1 downTo 0) {
shouldFullyNetwork = false streamCodec.encode(stream, values[i])
stream.writeVarInt(values.size)
values.forEach { streamCodec.encode(stream, it) }
} else {
stream.writeVarInt(networkValues.size)
networkValues.forEach { streamCodec.encode(stream, it) }
networkValues.clear()
} }
currentIndex = 0
fresh = false
} }
fun add(value: V) { fun push() {
if (shouldFullyNetwork) { if (currentIndex >= width) return
return currentIndex++
} else if (networkValues.size + 1 >= (width / 2).coerceIn(20, 100)) { listener.run()
shouldFullyNetwork = true
networkValues.clear()
listener.run()
} else {
networkValues.add(value)
listener.run()
}
} }
override fun invalidate() { override fun invalidate() {
networkValues.clear() currentIndex = values.size
shouldFullyNetwork = true fresh = true
} }
override fun close() { override fun close() {
@ -110,15 +101,13 @@ abstract class AbstractHistoryGraph<V : Any>(
override fun read(stream: RegistryFriendlyByteBuf) { override fun read(stream: RegistryFriendlyByteBuf) {
if (stream.readBoolean()) { if (stream.readBoolean()) {
values.clear() values.clear()
for (i in 0 until stream.readVarInt()) {
values.add(streamCodec.decode(stream))
}
} else {
for (i in 0 until stream.readVarInt()) {
values.addFirst(streamCodec.decode(stream))
}
} }
for (i in 0 until stream.readVarInt()) {
values.addFirst(streamCodec.decode(stream))
}
while (values.size > width) values.removeLast()
} }
override fun createRemoteState(listener: Runnable): IRemoteState { override fun createRemoteState(listener: Runnable): IRemoteState {
@ -145,9 +134,9 @@ abstract class AbstractHistoryGraph<V : Any>(
if (accumulator.size >= resolution) { if (accumulator.size >= resolution) {
val calc = calculateAverage(accumulator) val calc = calculateAverage(accumulator)
values.addFirst(calc) values.addFirst(calc)
remotes.forEach { it.add(calc) } remotes.forEach { it.push() }
accumulator.clear() accumulator.clear()
while (values.size >= width) values.removeLast() while (values.size > width) values.removeLast()
} }
} }
@ -204,7 +193,7 @@ abstract class AbstractHistoryGraph<V : Any>(
} }
override fun next(): V { override fun next(): V {
return this@AbstractHistoryGraph[index++] return this@AbstractHistoryChart[index++]
} }
} }
} }

View File

@ -8,7 +8,7 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.data.DecimalCodec import ru.dbotthepony.mc.otm.data.DecimalCodec
import ru.dbotthepony.mc.otm.network.MatteryStreamCodec import ru.dbotthepony.mc.otm.network.MatteryStreamCodec
class DecimalHistoryGraph : AbstractHistoryGraph<Decimal> { class DecimalHistoryChart : AbstractHistoryChart<Decimal> {
constructor(resolution: Int, width: Int) : super(resolution, width) constructor(resolution: Int, width: Int) : super(resolution, width)
constructor(ticks: Int) : this(1, ticks) constructor(ticks: Int) : this(1, ticks)

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.mc.otm.menu.tech package ru.dbotthepony.mc.otm.menu.tech
import net.minecraft.core.Direction import net.minecraft.core.Direction
import kotlin.jvm.JvmOverloads
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import ru.dbotthepony.kommons.util.getValue import ru.dbotthepony.kommons.util.getValue
@ -9,7 +8,7 @@ import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock
import ru.dbotthepony.mc.otm.block.entity.tech.EnergyCounterBlockEntity import ru.dbotthepony.mc.otm.block.entity.tech.EnergyCounterBlockEntity
import ru.dbotthepony.mc.otm.core.DecimalHistoryGraph import ru.dbotthepony.mc.otm.core.DecimalHistoryChart
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.toDecimal import ru.dbotthepony.mc.otm.core.math.toDecimal
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
@ -26,13 +25,13 @@ class EnergyCounterMenu(
var lastTick by mSynchronizer.decimal() var lastTick by mSynchronizer.decimal()
var maxIO by mSynchronizer.decimal() var maxIO by mSynchronizer.decimal()
val history5s = tile?.history5s ?: DecimalHistoryGraph(1, 100) val history5s = tile?.history5s ?: DecimalHistoryChart(1, 100)
val history15s = tile?.history15s ?: DecimalHistoryGraph(3, 100) val history15s = tile?.history15s ?: DecimalHistoryChart(3, 100)
val history1m = tile?.history1m ?: DecimalHistoryGraph(12, 100) val history1m = tile?.history1m ?: DecimalHistoryChart(12, 100)
val history10m = tile?.history10m ?: DecimalHistoryGraph(120, 100) val history10m = tile?.history10m ?: DecimalHistoryChart(120, 100)
val history1h = tile?.history1h ?: DecimalHistoryGraph(720, 100) val history1h = tile?.history1h ?: DecimalHistoryChart(720, 100)
val history6h = tile?.history6h ?: DecimalHistoryGraph(720 * 6, 100) val history6h = tile?.history6h ?: DecimalHistoryChart(720 * 6, 100)
val history24h = tile?.history24h ?: DecimalHistoryGraph(720 * 24, 100) val history24h = tile?.history24h ?: DecimalHistoryChart(720 * 24, 100)
init { init {
mSynchronizer.add(history5s) mSynchronizer.add(history5s)

View File

@ -5,7 +5,7 @@ import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage
import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage.Companion.HISTORY_SIZE import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage.Companion.HISTORY_SIZE
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
import ru.dbotthepony.mc.otm.core.DecimalHistoryGraph import ru.dbotthepony.mc.otm.core.DecimalHistoryChart
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.StreamCodecs import ru.dbotthepony.mc.otm.network.StreamCodecs
@ -22,8 +22,8 @@ class ProfiledLevelGaugeWidget<P : AbstractProfiledStorage<*>>(
gauge: LevelGaugeWidget = LevelGaugeWidget(menu.mSynchronizer) gauge: LevelGaugeWidget = LevelGaugeWidget(menu.mSynchronizer)
) : this(menu.mSynchronizer, storage, gauge) ) : this(menu.mSynchronizer, storage, gauge)
val received = storage?.received ?: DecimalHistoryGraph(ticks = HISTORY_SIZE) val received = storage?.received ?: DecimalHistoryChart(ticks = HISTORY_SIZE)
val transferred = storage?.transferred ?: DecimalHistoryGraph(ticks = HISTORY_SIZE) val transferred = storage?.transferred ?: DecimalHistoryChart(ticks = HISTORY_SIZE)
val receivedThisTick by synchronizer.computed({ storage?.receivedThisTick ?: Decimal.ZERO }, StreamCodecs.DECIMAL) val receivedThisTick by synchronizer.computed({ storage?.receivedThisTick ?: Decimal.ZERO }, StreamCodecs.DECIMAL)
val transferredThisTick by synchronizer.computed({ storage?.transferredThisTick ?: Decimal.ZERO }, StreamCodecs.DECIMAL) val transferredThisTick by synchronizer.computed({ storage?.transferredThisTick ?: Decimal.ZERO }, StreamCodecs.DECIMAL)