Use synchronizers for research/features fields
This commit is contained in:
parent
97457ab027
commit
4acb362916
@ -1,31 +1,25 @@
|
||||
package ru.dbotthepony.mc.otm.android
|
||||
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.core.readNbt
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.writeNbt
|
||||
import ru.dbotthepony.mc.otm.network.FieldSynchronizer
|
||||
import java.io.DataInputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: MatteryPlayerCapability) : INBTSerializable<CompoundTag> {
|
||||
val entity get() = android.ply
|
||||
val synchronizer = FieldSynchronizer()
|
||||
|
||||
/**
|
||||
* Whenever there are changes to network
|
||||
*/
|
||||
var isDirty = false
|
||||
|
||||
open var level = 0
|
||||
set(value) {
|
||||
if (value != field) {
|
||||
field = value
|
||||
applyModifiers()
|
||||
}
|
||||
open var level by synchronizer.int(setter = setter@{ value, field, setByRemote ->
|
||||
if (value != field.read()) {
|
||||
field.write(value)
|
||||
applyModifiers()
|
||||
}
|
||||
})
|
||||
|
||||
open fun tickClient() {}
|
||||
open fun tickServer() {}
|
||||
@ -33,19 +27,21 @@ abstract class AndroidFeature(val type: AndroidFeatureType<*>, val android: Matt
|
||||
/**
|
||||
* Called when it is required to network everything again
|
||||
*/
|
||||
open fun invalidateNetwork() {}
|
||||
open fun invalidateNetwork() {
|
||||
synchronizer.invalidate()
|
||||
}
|
||||
|
||||
open fun applyModifiers() {}
|
||||
open fun removeModifiers() {}
|
||||
|
||||
open fun onHurt(event: LivingHurtEvent) {}
|
||||
|
||||
open fun writeNetwork(stream: OutputStream) {
|
||||
stream.writeNbt(serializeNBT())
|
||||
open fun collectNetworkPayload(): FastByteArrayOutputStream? {
|
||||
return synchronizer.collectNetworkPayload()
|
||||
}
|
||||
|
||||
open fun readNetwork(stream: InputStream) {
|
||||
deserializeNBT(stream.readNbt())
|
||||
open fun applyNetworkPayload(stream: InputStream) {
|
||||
synchronizer.applyNetworkPayload(DataInputStream(stream))
|
||||
}
|
||||
|
||||
override fun serializeNBT(): CompoundTag {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.android
|
||||
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.chat.Component
|
||||
@ -7,26 +8,23 @@ import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||
import ru.dbotthepony.mc.otm.core.readNbt
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.writeNbt
|
||||
import ru.dbotthepony.mc.otm.network.FieldSynchronizer
|
||||
import java.io.DataInputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability: MatteryPlayerCapability) : INBTSerializable<CompoundTag> {
|
||||
var isResearched = false
|
||||
protected set
|
||||
val synchronizer = FieldSynchronizer()
|
||||
|
||||
/**
|
||||
* Whenever there are changes to network
|
||||
*/
|
||||
var isDirty = false
|
||||
var isResearched by synchronizer.bool()
|
||||
protected set
|
||||
|
||||
/**
|
||||
* Called when it is required to network everything again
|
||||
*/
|
||||
abstract fun invalidateNetwork()
|
||||
open fun invalidateNetwork() {
|
||||
synchronizer.invalidate()
|
||||
}
|
||||
|
||||
fun unResearch() {
|
||||
if (!isResearched) {
|
||||
@ -35,7 +33,6 @@ abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability:
|
||||
|
||||
onUnResearch()
|
||||
isResearched = false
|
||||
isDirty = true
|
||||
}
|
||||
|
||||
abstract fun onUnResearch()
|
||||
@ -57,12 +54,12 @@ abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability:
|
||||
*/
|
||||
abstract fun refund(simulate: Boolean): Boolean
|
||||
|
||||
open fun writeNetwork(buff: OutputStream) {
|
||||
buff.writeNbt(serializeNBT())
|
||||
open fun collectNetworkPayload(): FastByteArrayOutputStream? {
|
||||
return synchronizer.collectNetworkPayload()
|
||||
}
|
||||
|
||||
open fun readNetwork(buff: InputStream) {
|
||||
deserializeNBT(buff.readNbt())
|
||||
open fun applyNetworkPayload(stream: InputStream) {
|
||||
synchronizer.applyNetworkPayload(DataInputStream(stream))
|
||||
}
|
||||
|
||||
open val canResearch: Boolean get() {
|
||||
@ -146,12 +143,10 @@ abstract class AndroidResearch(val type: AndroidResearchType<*>, val capability:
|
||||
if (force) {
|
||||
onResearched()
|
||||
isResearched = true
|
||||
isDirty = true
|
||||
return true
|
||||
} else if (consumeResearchCost(false)) {
|
||||
onResearched()
|
||||
isResearched = true
|
||||
isDirty = true
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -193,10 +193,6 @@ class AndroidResearchBuilder(
|
||||
|
||||
return object : AndroidResearchType<AndroidResearch>(factory@{ it, capability ->
|
||||
return@factory object : AndroidResearch(it, capability) {
|
||||
override fun invalidateNetwork() {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
override fun onUnResearch() {
|
||||
for (feature in features) {
|
||||
val level = oldResearchLevel[feature.feature]
|
||||
|
@ -30,7 +30,6 @@ import net.minecraftforge.event.TickEvent
|
||||
import net.minecraftforge.event.TickEvent.PlayerTickEvent
|
||||
import net.minecraftforge.event.entity.living.LivingDeathEvent
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent
|
||||
import net.minecraftforge.event.entity.living.LivingEvent
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||
import net.minecraftforge.event.entity.living.LivingSpawnEvent
|
||||
import net.minecraftforge.event.entity.player.EntityItemPickupEvent
|
||||
@ -279,7 +278,12 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
}
|
||||
|
||||
if (ply is ServerPlayer) {
|
||||
sendNetwork(AndroidFeatureSyncPacket(feature))
|
||||
feature.invalidateNetwork()
|
||||
val payload = feature.collectNetworkPayload()
|
||||
|
||||
if (payload != null) {
|
||||
sendNetwork(AndroidFeatureSyncPacket(feature.type, payload, null))
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
@ -299,7 +303,12 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
}
|
||||
|
||||
if (ply is ServerPlayer) {
|
||||
sendNetwork(AndroidFeatureSyncPacket(factory))
|
||||
factory.invalidateNetwork()
|
||||
val payload = factory.collectNetworkPayload()
|
||||
|
||||
if (payload != null) {
|
||||
sendNetwork(AndroidFeatureSyncPacket(feature, payload, null))
|
||||
}
|
||||
}
|
||||
|
||||
return factory
|
||||
@ -582,12 +591,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
synchronizer.invalidate()
|
||||
|
||||
for (instance in research.values) {
|
||||
instance.isDirty = true
|
||||
instance.invalidateNetwork()
|
||||
}
|
||||
|
||||
for (feature in features.values) {
|
||||
feature.isDirty = true
|
||||
feature.invalidateNetwork()
|
||||
}
|
||||
}
|
||||
@ -609,16 +616,18 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
}
|
||||
|
||||
for (instance in research.values) {
|
||||
if (instance.isDirty) {
|
||||
instance.isDirty = false
|
||||
sendNetwork(AndroidResearchSyncPacket(instance))
|
||||
val researchPayload = instance.collectNetworkPayload()
|
||||
|
||||
if (researchPayload != null) {
|
||||
sendNetwork(AndroidResearchSyncPacket(instance.type, researchPayload, null))
|
||||
}
|
||||
}
|
||||
|
||||
for (instance in features.values) {
|
||||
if (instance.isDirty) {
|
||||
instance.isDirty = false
|
||||
sendNetwork(AndroidFeatureSyncPacket(instance))
|
||||
val featurePayload = instance.collectNetworkPayload()
|
||||
|
||||
if (featurePayload != null) {
|
||||
sendNetwork(AndroidFeatureSyncPacket(instance.type, featurePayload, null))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package ru.dbotthepony.mc.otm.network
|
||||
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
@ -13,13 +12,9 @@ import ru.dbotthepony.mc.otm.android.AndroidFeature
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.MatteryGUI
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.readImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.writeImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import java.io.ByteArrayInputStream
|
||||
@ -75,15 +70,7 @@ class AndroidResearchRequestPacket(val type: AndroidResearchType<*>) : MatteryPa
|
||||
}
|
||||
}
|
||||
|
||||
private fun getData(invoke: (stream: OutputStream) -> Unit): FastByteArrayOutputStream {
|
||||
val stream = FastByteArrayOutputStream()
|
||||
invoke(stream)
|
||||
return stream
|
||||
}
|
||||
|
||||
class AndroidResearchSyncPacket(val type: AndroidResearchType<*>, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : MatteryPacket {
|
||||
constructor(feature: AndroidResearch) : this(feature.type, getData(feature::writeNetwork), null)
|
||||
|
||||
override fun write(buff: FriendlyByteBuf) {
|
||||
dataList ?: throw NullPointerException("No byte list is present")
|
||||
buff.writeInt(MRegistry.ANDROID_RESEARCH.getID(type))
|
||||
@ -97,7 +84,7 @@ class AndroidResearchSyncPacket(val type: AndroidResearchType<*>, val dataList:
|
||||
context.get().enqueueWork {
|
||||
val android = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
|
||||
android.getResearch(type).readNetwork(ByteArrayInputStream(dataBytes))
|
||||
android.getResearch(type).applyNetworkPayload(ByteArrayInputStream(dataBytes))
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,8 +99,6 @@ class AndroidResearchSyncPacket(val type: AndroidResearchType<*>, val dataList:
|
||||
}
|
||||
|
||||
class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val dataList: FastByteArrayOutputStream?, val dataBytes: ByteArray?) : MatteryPacket {
|
||||
constructor(feature: AndroidFeature) : this(feature.type, getData(feature::writeNetwork), null)
|
||||
|
||||
override fun write(buff: FriendlyByteBuf) {
|
||||
dataList ?: throw NullPointerException("No byte list is present")
|
||||
buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type))
|
||||
@ -127,7 +112,7 @@ class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val dataList: Fa
|
||||
context.get().enqueueWork {
|
||||
val android = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
|
||||
android.computeIfAbsent(type).readNetwork(ByteArrayInputStream(dataBytes))
|
||||
android.computeIfAbsent(type).applyNetworkPayload(ByteArrayInputStream(dataBytes))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user