Allow DynamicSynchableGroup to accept non-ISynchables
This commit is contained in:
parent
afb6cd5907
commit
d35da8c7f4
@ -10,29 +10,39 @@ import java.io.Closeable
|
|||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new [DynamicSynchableGroup] where [T] is itself an [ISynchable]
|
||||||
|
*/
|
||||||
|
fun <T : ISynchable> DynamicSynchableGroup(reader: RegistryFriendlyByteBuf.() -> T, writer: T.(RegistryFriendlyByteBuf) -> Unit): DynamicSynchableGroup<T> {
|
||||||
|
return DynamicSynchableGroup(reader, { this }, writer)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncher group/set, which deals with synchables of only one type, and which are created and removed
|
* Syncher group/set, which deals with synchables of only one type, and which are created and removed
|
||||||
* on remote (e.g. server adding and removing synchables at will), which makes it distinct from
|
* on remote (e.g. server adding and removing synchables at will), which makes it distinct from
|
||||||
* [SynchableGroup], in which attached synchables are created/removed manually on both sides.
|
* [SynchableGroup], in which attached synchables are created/removed manually on both sides.
|
||||||
*/
|
*/
|
||||||
class DynamicSynchableGroup<T : ISynchable>(
|
class DynamicSynchableGroup<T : Any>(
|
||||||
/**
|
/**
|
||||||
* Constructs new [T] instance locally, when remote created one.
|
* Constructs new [T] instance locally, when remote created one.
|
||||||
* Data written by [writer] must be read here, if there is any.
|
* Data written by [writer] must be read here, if there is any.
|
||||||
*/
|
*/
|
||||||
private val reader: RegistryFriendlyByteBuf.() -> T,
|
private val reader: RegistryFriendlyByteBuf.() -> T,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an [ISynchable] out of value [T] for synching state
|
||||||
|
*/
|
||||||
|
private val synchable: T.() -> ISynchable,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to write additional data to network stream during
|
* Allows to write additional data to network stream during
|
||||||
* first-time networking of [T] to remote
|
* first-time networking of [T] to remote
|
||||||
*/
|
*/
|
||||||
private val writer: T.(RegistryFriendlyByteBuf) -> Unit = {}
|
private val writer: T.(RegistryFriendlyByteBuf) -> Unit = {},
|
||||||
) : ISynchable, MutableSet<T> {
|
) : ISynchable, MutableSet<T> {
|
||||||
constructor(factory: () -> T) : this({ factory() }, {})
|
|
||||||
|
|
||||||
private inner class RemoteState(val listener: Runnable) : IRemoteState {
|
private inner class RemoteState(val listener: Runnable) : IRemoteState {
|
||||||
private inner class RemoteSlot(val slot: Slot<T>, fromConstructor: Boolean) : Runnable, Closeable {
|
private inner class RemoteSlot(val slot: Slot<T>, fromConstructor: Boolean) : Runnable, Closeable {
|
||||||
val remoteState = slot.synchable.createRemoteState(this)
|
val remoteState = synchable(slot.value).createRemoteState(this)
|
||||||
val isDirty = AtomicBoolean(true)
|
val isDirty = AtomicBoolean(true)
|
||||||
var isRemoved = false
|
var isRemoved = false
|
||||||
private set
|
private set
|
||||||
@ -114,7 +124,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
firstTime.forEach {
|
firstTime.forEach {
|
||||||
stream.writeByte(ADD_ENTRY)
|
stream.writeByte(ADD_ENTRY)
|
||||||
stream.writeVarInt(it.slot.id)
|
stream.writeVarInt(it.slot.id)
|
||||||
writer(it.slot.synchable, stream)
|
writer(it.slot.value, stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
firstTime.clear()
|
firstTime.clear()
|
||||||
@ -177,7 +187,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class Slot<T : Any>(val synchable: T, val id: Int)
|
private data class Slot<T : Any>(val value: T, val id: Int)
|
||||||
|
|
||||||
private val remoteStates = ArrayList<RemoteState>()
|
private val remoteStates = ArrayList<RemoteState>()
|
||||||
private val value2slot = HashMap<T, Slot<T>>()
|
private val value2slot = HashMap<T, Slot<T>>()
|
||||||
@ -199,7 +209,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
REMOVE_ENTRY -> {
|
REMOVE_ENTRY -> {
|
||||||
val id = stream.readVarInt()
|
val id = stream.readVarInt()
|
||||||
val slot = checkNotNull(id2slot.remove(id)) { "No such slot with ID: $id" }
|
val slot = checkNotNull(id2slot.remove(id)) { "No such slot with ID: $id" }
|
||||||
check(value2slot.remove(slot.synchable) == value2slot)
|
check(value2slot.remove(slot.value) == value2slot)
|
||||||
remoteStates.forEach { it.remove(slot) }
|
remoteStates.forEach { it.remove(slot) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +222,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
|
|
||||||
if (id2slot.containsKey(id)) {
|
if (id2slot.containsKey(id)) {
|
||||||
val slot = id2slot.remove(id)!!
|
val slot = id2slot.remove(id)!!
|
||||||
check(value2slot.remove(slot.synchable) == value2slot)
|
check(value2slot.remove(slot.value) == value2slot)
|
||||||
remoteStates.forEach { it.remove(slot) }
|
remoteStates.forEach { it.remove(slot) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +235,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
SYNC_ENTRY -> {
|
SYNC_ENTRY -> {
|
||||||
val id = stream.readVarInt()
|
val id = stream.readVarInt()
|
||||||
val slot = checkNotNull(id2slot.get(id)) { "No such slot with ID: $id" }
|
val slot = checkNotNull(id2slot.get(id)) { "No such slot with ID: $id" }
|
||||||
slot.synchable.read(stream)
|
synchable(slot.value).read(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEAR -> {
|
CLEAR -> {
|
||||||
@ -299,7 +309,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
override fun next(): T {
|
override fun next(): T {
|
||||||
val slot = parent.next()
|
val slot = parent.next()
|
||||||
last = KOptional(slot)
|
last = KOptional(slot)
|
||||||
return slot.synchable
|
return slot.value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun remove() {
|
override fun remove() {
|
||||||
|
Loading…
Reference in New Issue
Block a user