rework controls
This commit is contained in:
parent
7c7a671315
commit
91e2470947
7 changed files with 87 additions and 40 deletions
|
|
@ -1,6 +1,9 @@
|
|||
package net.liquidev.dawd3.audio.device
|
||||
|
||||
import net.minecraft.nbt.NbtElement
|
||||
import net.minecraft.nbt.NbtFloat
|
||||
import net.minecraft.util.Identifier
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class ControlName(parent: Identifier, name: String) {
|
||||
|
|
@ -20,37 +23,58 @@ class ControlName(parent: Identifier, name: String) {
|
|||
}
|
||||
}
|
||||
|
||||
data class ControlDescriptor(
|
||||
data class ControlDescriptor<T>(
|
||||
val name: ControlName,
|
||||
val initialValue: Float,
|
||||
val initialValue: T,
|
||||
) {
|
||||
constructor(
|
||||
parent: Identifier,
|
||||
name: String,
|
||||
initialValue: Float,
|
||||
initialValue: T,
|
||||
) : this(ControlName(parent, name), initialValue)
|
||||
}
|
||||
|
||||
class Control(val descriptor: ControlDescriptor) {
|
||||
sealed interface Control {
|
||||
fun valueToNBT(): NbtElement
|
||||
fun valueFromNBT(element: NbtElement)
|
||||
|
||||
fun valueToBytes(): ByteArray
|
||||
fun valueFromBytes(buffer: ByteArray)
|
||||
}
|
||||
|
||||
class FloatControl(val descriptor: ControlDescriptor<Float>) : Control {
|
||||
private val internalValue = AtomicInteger(descriptor.initialValue.toBits())
|
||||
var value: Float
|
||||
get() = Float.fromBits(internalValue.get())
|
||||
set(value) = internalValue.set(value.toBits())
|
||||
|
||||
override fun valueToNBT(): NbtElement = NbtFloat.of(value)
|
||||
|
||||
override fun valueFromNBT(element: NbtElement) {
|
||||
value = (element as? NbtFloat)?.floatValue() ?: 0f
|
||||
}
|
||||
|
||||
override fun valueToBytes(): ByteArray =
|
||||
ByteBuffer.allocate(4).putFloat(value).array()
|
||||
|
||||
override fun valueFromBytes(buffer: ByteArray) {
|
||||
value = ByteBuffer.wrap(buffer).getFloat()
|
||||
}
|
||||
}
|
||||
|
||||
interface ControlSet {
|
||||
fun visitControls(visit: (ControlDescriptor, Control) -> Unit)
|
||||
fun visitControls(visit: (ControlName, Control) -> Unit)
|
||||
}
|
||||
|
||||
object NoControls : ControlSet {
|
||||
override fun visitControls(visit: (ControlDescriptor, Control) -> Unit) {}
|
||||
override fun visitControls(visit: (ControlName, Control) -> Unit) {}
|
||||
}
|
||||
|
||||
class ControlMap(set: ControlSet) {
|
||||
private val map = hashMapOf<ControlName, Control>()
|
||||
|
||||
init {
|
||||
set.visitControls { controlDescriptor, control -> map[controlDescriptor.name] = control }
|
||||
set.visitControls { controlName, control -> map[controlName] = control }
|
||||
}
|
||||
|
||||
operator fun get(name: ControlName): Control? = map[name]
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ class AmplifierDevice : Device<AmplifierDevice.Controls> {
|
|||
}
|
||||
|
||||
class Controls : ControlSet {
|
||||
val amplitude = Control(amplitudeControl)
|
||||
val amplitudeCV = Control(amplitudeCVControl)
|
||||
val amplitude = FloatControl(amplitudeControl)
|
||||
val amplitudeCV = FloatControl(amplitudeCVControl)
|
||||
|
||||
override fun visitControls(visit: (ControlDescriptor, Control) -> Unit) {
|
||||
visit(amplitudeControl, amplitude)
|
||||
visit(amplitudeCVControl, amplitudeCV)
|
||||
override fun visitControls(visit: (ControlName, Control) -> Unit) {
|
||||
visit(amplitudeControl.name, amplitude)
|
||||
visit(amplitudeCVControl.name, amplitudeCV)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ class ConstantDevice : Device<ConstantDevice.Controls> {
|
|||
}
|
||||
|
||||
class Controls : ControlSet {
|
||||
val value = Control(valueControl)
|
||||
val value = FloatControl(valueControl)
|
||||
|
||||
override fun visitControls(visit: (ControlDescriptor, Control) -> Unit) {
|
||||
visit(valueControl, value)
|
||||
override fun visitControls(visit: (ControlName, Control) -> Unit) {
|
||||
visit(valueControl.name, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ class FmaDevice : Device<FmaDevice.Controls> {
|
|||
}
|
||||
|
||||
class Controls : ControlSet {
|
||||
val multiply = Control(multiplyControl)
|
||||
val add = Control(addControl)
|
||||
val multiply = FloatControl(multiplyControl)
|
||||
val add = FloatControl(addControl)
|
||||
|
||||
override fun visitControls(visit: (ControlDescriptor, Control) -> Unit) {
|
||||
visit(multiplyControl, multiply)
|
||||
visit(addControl, add)
|
||||
override fun visitControls(visit: (ControlName, Control) -> Unit) {
|
||||
visit(multiplyControl.name, multiply)
|
||||
visit(addControl.name, add)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ import net.liquidev.dawd3.block.entity.D3BlockEntity
|
|||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.entity.BlockEntityType
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.nbt.*
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.nbt.NbtElement
|
||||
import net.minecraft.nbt.NbtHelper
|
||||
import net.minecraft.nbt.NbtList
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
private typealias DeviceBlockFactory = FabricBlockEntityTypeBuilder.Factory<DeviceBlockEntity>
|
||||
|
|
@ -63,11 +66,13 @@ class DeviceBlockEntity(
|
|||
super.readNbt(nbt)
|
||||
|
||||
val controlsNbt = nbt.getCompound(Nbt.controls)
|
||||
controls.visitControls { controlDescriptor, control ->
|
||||
val controlName = controlDescriptor.name.toString()
|
||||
if (controlName in controlsNbt) {
|
||||
val value = controlsNbt.getFloat(controlName)
|
||||
control.value = value
|
||||
controls.visitControls { controlName, control ->
|
||||
val controlNameString = controlName.toString()
|
||||
if (controlNameString in controlsNbt) {
|
||||
val element = controlsNbt.get(controlNameString)
|
||||
if (element != null) {
|
||||
control.valueFromNBT(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,8 +124,8 @@ class DeviceBlockEntity(
|
|||
super.writeNbt(nbt)
|
||||
|
||||
val controlsNbt = NbtCompound()
|
||||
controls.visitControls { controlDescriptor, control ->
|
||||
controlsNbt.put(controlDescriptor.name.toString(), NbtFloat.of(control.value))
|
||||
controls.visitControls { controlName, control ->
|
||||
controlsNbt.put(controlName.toString(), control.valueToNBT())
|
||||
}
|
||||
nbt.put(Nbt.controls, controlsNbt)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import net.minecraft.network.PacketByteBuf
|
|||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
data class TweakControl(val position: BlockPos, val control: Identifier, val newValue: Float) {
|
||||
data class TweakControl(val position: BlockPos, val control: Identifier, val data: ByteArray) {
|
||||
companion object {
|
||||
val id = Identifier(Mod.id, "tweak_control")
|
||||
|
||||
|
|
@ -28,8 +28,8 @@ data class TweakControl(val position: BlockPos, val control: Identifier, val new
|
|||
?: return@execute
|
||||
val controlName =
|
||||
ControlName.fromString(packet.control.toString()) ?: return@execute
|
||||
val control = blockEntity.controlMap[controlName]
|
||||
control?.value = packet.newValue
|
||||
val control = blockEntity.controlMap[controlName] ?: return@execute
|
||||
control.valueFromBytes(packet.data)
|
||||
|
||||
val witnesses = PlayerLookup.tracking(blockEntity)
|
||||
for (witness in witnesses) {
|
||||
|
|
@ -42,7 +42,7 @@ data class TweakControl(val position: BlockPos, val control: Identifier, val new
|
|||
TweakControl(
|
||||
packet.position,
|
||||
packet.control,
|
||||
packet.newValue,
|
||||
packet.data,
|
||||
).serialize()
|
||||
)
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ data class TweakControl(val position: BlockPos, val control: Identifier, val new
|
|||
val controlName =
|
||||
ControlName.fromString(packet.control.toString()) ?: return@execute
|
||||
val control = blockEntity.controlMap[controlName]
|
||||
control?.value = packet.newValue
|
||||
control?.valueFromBytes(packet.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ data class TweakControl(val position: BlockPos, val control: Identifier, val new
|
|||
TweakControl(
|
||||
position = buffer.readBlockPos(),
|
||||
control = buffer.readIdentifier(),
|
||||
newValue = buffer.readFloat(),
|
||||
data = buffer.readByteArray(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +81,25 @@ data class TweakControl(val position: BlockPos, val control: Identifier, val new
|
|||
val buffer = PacketByteBufs.create()
|
||||
buffer.writeBlockPos(position)
|
||||
buffer.writeIdentifier(control)
|
||||
buffer.writeFloat(newValue)
|
||||
buffer.writeByteArray(data)
|
||||
return buffer
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as TweakControl
|
||||
|
||||
if (position != other.position) return false
|
||||
if (control != other.control) return false
|
||||
return data.contentEquals(other.data)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = position.hashCode()
|
||||
result = 31 * result + control.hashCode()
|
||||
result = 31 * result + data.contentHashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package net.liquidev.dawd3.ui.widget
|
||||
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
||||
import net.liquidev.dawd3.audio.device.Control
|
||||
import net.liquidev.dawd3.audio.device.FloatControl
|
||||
import net.liquidev.dawd3.common.Degrees
|
||||
import net.liquidev.dawd3.common.Radians
|
||||
import net.liquidev.dawd3.common.clamp
|
||||
|
|
@ -23,7 +23,7 @@ import kotlin.math.sin
|
|||
class Knob(
|
||||
x: Int,
|
||||
y: Int,
|
||||
val control: Control,
|
||||
val control: FloatControl,
|
||||
val min: Float,
|
||||
val max: Float,
|
||||
val color: Color,
|
||||
|
|
@ -130,16 +130,16 @@ class Knob(
|
|||
if (draggingInfo != null) {
|
||||
val guiScale = client.options.guiScale.value.toFloat()
|
||||
val deltaY = (draggingInfo.previousMouseY - event.absoluteMouseY) * guiScale
|
||||
// Reflect the change locally immediately for lower latency.
|
||||
control.value = alterValue(control.value, by = deltaY.toFloat())
|
||||
ClientPlayNetworking.send(
|
||||
TweakControl.id,
|
||||
TweakControl(
|
||||
context.blockPosition,
|
||||
control.descriptor.name.id,
|
||||
newValue = alterValue(control.value, by = deltaY.toFloat()),
|
||||
control.valueToBytes()
|
||||
).serialize()
|
||||
)
|
||||
// Reflect the change locally immediately for lower latency.
|
||||
control.value = alterValue(control.value, by = deltaY.toFloat())
|
||||
draggingInfo.previousMouseY = event.absoluteMouseY
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue