From ebabcdf731b2ae71acb01bc39abfb1818a42b0f9 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Wed, 26 Oct 2022 22:27:10 +0700 Subject: [PATCH] docs --- .../ru/dbotthepony/mc/otm/core/DataStreams.kt | 19 ++++++++++++++++++- .../mc/otm/network/FieldSynchronizer.kt | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt index bcef9aad4..109f6d260 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/DataStreams.kt @@ -10,11 +10,28 @@ import java.util.function.Predicate import kotlin.NoSuchElementException import kotlin.math.absoluteValue +/** + * Represents value which can be encoded onto or decoded from stream. + * + * Also provides [copy] and [compare] methods + */ interface IStreamCodec { fun read(stream: DataInputStream): V fun write(stream: DataOutputStream, value: V) + + /** + * if value is immutable, return it right away + */ fun copy(value: V): V - fun compare(a: V, b: V): Boolean + + /** + * Optional equality check override. Utilized to determine whenever e.g. network value is different from new value + * + * By default uses [Any.equals] + */ + fun compare(a: V, b: V): Boolean { + return a == b + } } class StreamCodec( diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt index fe6545364..2525cd189 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/FieldSynchronizer.kt @@ -94,6 +94,24 @@ enum class MapAction { CLEAR, ADD, REMOVE } +/** + * Universal one-to-many value synchronizer + * + * This class represent collection of synchronizable values (similar to entitydata or menu's dataslots) + * + * Advantages of this class are: + * * It can be freely pooled. You can call [collectNetworkPayload] and [FieldSynchronizer.Endpoint.collectNetworkPayload] as much as you like, + * because they use dirty lists to track which fields need networking. **Warning**: If you attach one or more "observed" values (more on them below), + * each call to above methods will cause scan on observed fields. + * * It is universal. No, seriously, you can use it anywhere, all it needs is you encode [FastByteArrayOutputStream], send it over your + * networking channel, and create [InputStream] to feed to [FieldSynchronizer.Endpoint] + * * Its capabilities at networking are only limited by codecs you provide, see [FieldSynchronizer.Field], [IStreamCodec] + * * Provides not only single values, but also smart [FieldSynchronizer.Map] map synchronization + * * Has network version "conflict" resolver. If source FieldSynchronizer and target FieldSynchronizer have different set of fields, they can figure out how to synchronize + * only known fields. **Keep in mind this only works if you manually specify names on ALL created fields** + * * Directly bytestream embeddable. [FieldSynchronizer.Endpoint] always knows how much bytes to read from incoming stream, you can directly embed it into your data flow + * on network channel. + */ @Suppress("unused") class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCallback: Boolean) { constructor() : this(Runnable {}, false)