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