Update pattern monitor
This commit is contained in:
parent
182bb4c8ba
commit
0428b60561
@ -824,6 +824,10 @@ private fun gui(provider: MatteryLanguageProvider) {
|
|||||||
gui("matter_panel.label", "Replication request")
|
gui("matter_panel.label", "Replication request")
|
||||||
gui("matter_panel.task", "Ongoing replication task")
|
gui("matter_panel.task", "Ongoing replication task")
|
||||||
gui("matter_panel.task_line", "%s: %s | %s / %s")
|
gui("matter_panel.task_line", "%s: %s | %s / %s")
|
||||||
|
gui("matter_panel.is_providing_tasks", "Tasks are dispatched to replicators")
|
||||||
|
gui("matter_panel.not_providing_tasks", "Tasks are NOT dispatched to replicators")
|
||||||
|
gui("matter_panel.cancel_all", "Cancel all tasks")
|
||||||
|
gui("matter_panel.cancel_all.desc", "Do you really want to cancel all replication tasks?")
|
||||||
|
|
||||||
gui("matter_panel.tasks", "Tasks")
|
gui("matter_panel.tasks", "Tasks")
|
||||||
gui("matter_panel.patterns", "Patterns")
|
gui("matter_panel.patterns", "Patterns")
|
||||||
|
@ -821,6 +821,10 @@ private fun gui(provider: MatteryLanguageProvider) {
|
|||||||
gui("matter_panel.cancel", "Отмена")
|
gui("matter_panel.cancel", "Отмена")
|
||||||
gui("matter_panel.label", "Запрос на репликацию")
|
gui("matter_panel.label", "Запрос на репликацию")
|
||||||
gui("matter_panel.task", "Будущий запрос на репликацию")
|
gui("matter_panel.task", "Будущий запрос на репликацию")
|
||||||
|
gui("matter_panel.is_providing_tasks", "Задачи передаются на репликаторы")
|
||||||
|
gui("matter_panel.not_providing_tasks", "Задачи НЕ передаются на репликаторы")
|
||||||
|
gui("matter_panel.cancel_all", "Отменить все задачи")
|
||||||
|
gui("matter_panel.cancel_all.desc", "Вы действительно хотите отменить все задачи репликации?")
|
||||||
|
|
||||||
gui("matter_panel.tasks", "Задачи")
|
gui("matter_panel.tasks", "Задачи")
|
||||||
gui("matter_panel.patterns", "Шаблоны")
|
gui("matter_panel.patterns", "Шаблоны")
|
||||||
|
@ -15,22 +15,32 @@ import net.minecraft.world.level.Level
|
|||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
|
import ru.dbotthepony.mc.otm.core.collect.WeakHashSet
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.getBoolean
|
import ru.dbotthepony.mc.otm.core.nbt.getBoolean
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
|
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.map
|
import ru.dbotthepony.mc.otm.core.nbt.map
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.mapString
|
import ru.dbotthepony.mc.otm.core.nbt.mapString
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterPanelBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.MATTER_PANEL, blockPos, blockState), IReplicationTaskProvider {
|
||||||
MatteryDeviceBlockEntity(MBlockEntities.MATTER_PANEL, p_155229_, p_155230_), IReplicationTaskProvider {
|
inner class PlayerSettings : INBTSerializable<CompoundTag> {
|
||||||
|
var sorter: ItemSorter = ItemSorter.DEFAULT
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
markDirtyFast()
|
||||||
|
}
|
||||||
|
|
||||||
|
var ascending: Boolean = true
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
markDirtyFast()
|
||||||
|
}
|
||||||
|
|
||||||
class PlayerSettings(var sorter: ItemSorter = ItemSorter.DEFAULT, var ascending: Boolean = true) : INBTSerializable<CompoundTag> {
|
|
||||||
override fun serializeNBT(): CompoundTag {
|
override fun serializeNBT(): CompoundTag {
|
||||||
return CompoundTag().also {
|
return CompoundTag().also {
|
||||||
it["sorter"] = sorter.name
|
it["sorter"] = sorter.name
|
||||||
@ -44,20 +54,35 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isProvidingTasks = true
|
||||||
|
set(value) {
|
||||||
|
if (field != value) {
|
||||||
|
field = value
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
_tasks.values.forEach { matterNode.graph.onMatterTaskCreated(it) }
|
||||||
|
} else {
|
||||||
|
_tasks.values.forEach { if (it.inProgress == 0) matterNode.graph.onMatterTaskRemoved(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
markDirtyFast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val playerSettings = Object2ObjectOpenHashMap<UUID, PlayerSettings>()
|
private val playerSettings = Object2ObjectOpenHashMap<UUID, PlayerSettings>()
|
||||||
|
|
||||||
fun getPlayerSettings(ply: Player): PlayerSettings {
|
fun getPlayerSettings(ply: Player): PlayerSettings {
|
||||||
return playerSettings.computeIfAbsent(ply.uuid, Object2ObjectFunction { PlayerSettings() })
|
return playerSettings.computeIfAbsent(ply.uuid, Object2ObjectFunction { PlayerSettings() })
|
||||||
}
|
}
|
||||||
|
|
||||||
private val listeners = ArrayList<MatterPanelMenu>()
|
private val listeners = WeakHashSet<MatterPanelMenu>()
|
||||||
val matterNode = SimpleMatterNode(tasks = this)
|
val matterNode = SimpleMatterNode(tasks = this)
|
||||||
|
|
||||||
fun attachMenu(menu: MatterPanelMenu) {
|
fun attachMenu(menu: MatterPanelMenu) {
|
||||||
listeners.add(menu)
|
listeners.add(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deatachMenu(menu: MatterPanelMenu) {
|
fun detachMenu(menu: MatterPanelMenu) {
|
||||||
listeners.remove(menu)
|
listeners.remove(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,18 +116,18 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
override fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
||||||
val graph = matterNode.graph as MatterGraph? ?: return null
|
if (!isProvidingTasks) return null
|
||||||
|
|
||||||
for ((key, task) in _tasks) {
|
for ((key, task) in _tasks) {
|
||||||
if (task.required > 0) {
|
if (task.required > 0) {
|
||||||
val pattern = task.patternId.map(graph::getPattern).orElse(null) ?: continue
|
val pattern = task.patternId.map(matterNode.graph::getPattern).orElse(null) ?: continue
|
||||||
|
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
val new = task.allocate()
|
val new = task.allocate()
|
||||||
_tasks[key] = new
|
_tasks[key] = new
|
||||||
listeners.forEach { it.taskUpdated(new) }
|
listeners.forEach { it.taskUpdated(new) }
|
||||||
graph.onMatterTaskUpdated(new, task)
|
matterNode.graph.onMatterTaskUpdated(new, task)
|
||||||
setChanged()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReplicationTaskAllocation(task, pattern)
|
return ReplicationTaskAllocation(task, pattern)
|
||||||
@ -115,23 +140,21 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
override fun notifyTaskCompletion(taskId: UUID): Boolean {
|
override fun notifyTaskCompletion(taskId: UUID): Boolean {
|
||||||
var localTask = _tasks[taskId] ?: return false
|
var localTask = _tasks[taskId] ?: return false
|
||||||
val oldTask = localTask
|
val oldTask = localTask
|
||||||
|
|
||||||
localTask = localTask.finish()
|
localTask = localTask.finish()
|
||||||
val graph = matterNode.graph as MatterGraph?
|
|
||||||
|
|
||||||
// Задача полностью выполнена
|
// Задача полностью выполнена
|
||||||
if (localTask.required <= 0 && localTask.inProgress <= 0) {
|
if (localTask.required <= 0 && localTask.inProgress <= 0) {
|
||||||
_tasks.remove(taskId)
|
_tasks.remove(taskId)
|
||||||
graph?.onMatterTaskFinished(localTask)
|
matterNode.graph.onMatterTaskFinished(localTask)
|
||||||
listeners.forEach { it.taskRemoved(localTask) }
|
listeners.forEach { it.taskRemoved(localTask) }
|
||||||
} else {
|
} else {
|
||||||
// Задача обновлена
|
// Задача обновлена
|
||||||
_tasks[taskId] = localTask
|
_tasks[taskId] = localTask
|
||||||
graph?.onMatterTaskUpdated(localTask, oldTask)
|
matterNode.graph.onMatterTaskUpdated(localTask, oldTask)
|
||||||
listeners.forEach { it.taskUpdated(localTask) }
|
listeners.forEach { it.taskUpdated(localTask) }
|
||||||
}
|
}
|
||||||
|
|
||||||
setChanged()
|
markDirtyFast()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,27 +212,26 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
matterNode.graph.onMatterTaskRemoved(task)
|
matterNode.graph.onMatterTaskRemoved(task)
|
||||||
|
|
||||||
listeners.forEach { it.taskRemoved(task) }
|
listeners.forEach { it.taskRemoved(task) }
|
||||||
setChanged()
|
markDirtyFast()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addTask(state: PatternState, count: Int): ReplicationTask {
|
fun addTask(state: PatternState, count: Int): ReplicationTask {
|
||||||
val task = ReplicationTask(UUID.randomUUID(), Optional.of(state.id), state.item, 0, 0, count)
|
val task = ReplicationTask(UUID.randomUUID(), Optional.of(state.id), state.item, 0, 0, count)
|
||||||
_tasks[task.id] = task
|
_tasks[task.id] = task
|
||||||
|
|
||||||
matterNode.graph.onMatterTaskCreated(task)
|
if (isProvidingTasks)
|
||||||
|
matterNode.graph.onMatterTaskCreated(task)
|
||||||
|
|
||||||
listeners.forEach { it.taskUpdated(task) }
|
listeners.forEach { it.taskUpdated(task) }
|
||||||
setChanged()
|
markDirtyFast()
|
||||||
|
|
||||||
return task
|
return task
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dropAllTasks() {
|
override fun dropAllTasks() {
|
||||||
val graph = matterNode.graph as MatterGraph?
|
|
||||||
|
|
||||||
for (task in _tasks.values) {
|
for (task in _tasks.values) {
|
||||||
graph?.onMatterTaskRemoved(task)
|
matterNode.graph.onMatterTaskRemoved(task)
|
||||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(task) }
|
listeners.forEach { it.taskRemoved(task) }
|
||||||
}
|
}
|
||||||
|
|
||||||
_tasks.clear()
|
_tasks.clear()
|
||||||
|
@ -50,6 +50,9 @@ object Widgets18 {
|
|||||||
val ONLY_STORE = storageGrid.next()
|
val ONLY_STORE = storageGrid.next()
|
||||||
val ONLY_EXTRACT = storageGrid.next()
|
val ONLY_EXTRACT = storageGrid.next()
|
||||||
val STORE_EXTRACT = storageGrid.next()
|
val STORE_EXTRACT = storageGrid.next()
|
||||||
|
val PAUSE = storageGrid.next()
|
||||||
|
val PLAY = storageGrid.next()
|
||||||
|
val STOP = storageGrid.next()
|
||||||
|
|
||||||
private val miscGrid = WidgetLocation.MISC_18.grid(4, 4)
|
private val miscGrid = WidgetLocation.MISC_18.grid(4, 4)
|
||||||
|
|
||||||
|
@ -14,13 +14,14 @@ import ru.dbotthepony.mc.otm.client.screen.panels.*
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeBooleanRectangleButtonPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeBooleanRectangleButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeEnumRectangleButtonPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.util.ScrollBarConstants
|
import ru.dbotthepony.mc.otm.client.screen.panels.util.ScrollBarConstants
|
||||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.asGetterSetter
|
||||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.core.math.integerDivisionDown
|
import ru.dbotthepony.mc.otm.core.math.integerDivisionDown
|
||||||
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
||||||
@ -54,12 +55,39 @@ class MatterPanelScreen(
|
|||||||
|
|
||||||
val controls = DeviceControls(this, frame)
|
val controls = DeviceControls(this, frame)
|
||||||
|
|
||||||
controls.sortingButtons(menu.isAscendingGS, menu.sortingGS, ItemSorter.DEFAULT) {
|
controls.sortingButtons(menu::isAscending.asGetterSetter(), menu::sorting.asGetterSetter(), ItemSorter.DEFAULT) {
|
||||||
for (v in ItemSorter.entries) {
|
for (v in ItemSorter.entries) {
|
||||||
add(v, skinElement = v.icon, tooltip = v.title)
|
add(v, skinElement = v.icon, tooltip = v.title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controls.addButton(
|
||||||
|
LargeBooleanRectangleButtonPanel(
|
||||||
|
this,
|
||||||
|
frame,
|
||||||
|
prop = menu::isProvidingTasks.asGetterSetter(),
|
||||||
|
iconActive = Widgets18.PLAY,
|
||||||
|
iconInactive = Widgets18.PAUSE,
|
||||||
|
tooltipActive = TranslatableComponent("otm.gui.matter_panel.is_providing_tasks"),
|
||||||
|
tooltipInactive = TranslatableComponent("otm.gui.matter_panel.not_providing_tasks"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
controls.addButton(
|
||||||
|
LargeRectangleButtonPanel(
|
||||||
|
this,
|
||||||
|
frame,
|
||||||
|
skinElement = Widgets18.STOP,
|
||||||
|
onPress = {
|
||||||
|
frame.queryUser(
|
||||||
|
TranslatableComponent("otm.gui.matter_panel.cancel_all"),
|
||||||
|
listOf(TranslatableComponent("otm.gui.matter_panel.cancel_all.desc")),
|
||||||
|
{ menu.cancelAll.accept(null) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val scrollBar = DiscreteScrollBarPanel(this, frame, {
|
val scrollBar = DiscreteScrollBarPanel(this, frame, {
|
||||||
if (isPatternView) {
|
if (isPatternView) {
|
||||||
integerDivisionDown(menu.patternsFiltered.size, GRID_WIDTH)
|
integerDivisionDown(menu.patternsFiltered.size, GRID_WIDTH)
|
||||||
|
@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.core.value
|
import ru.dbotthepony.mc.otm.core.value
|
||||||
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
|
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
|
||||||
|
|
||||||
@ -20,8 +21,8 @@ abstract class BooleanRectangleButtonPanel<out S : Screen>(
|
|||||||
width: Float,
|
width: Float,
|
||||||
height: Float,
|
height: Float,
|
||||||
val prop: GetterSetter<Boolean>,
|
val prop: GetterSetter<Boolean>,
|
||||||
var skinElementActive: IGUIRenderable? = null,
|
var iconActive: IGUIRenderable? = null,
|
||||||
var skinElementInactive: IGUIRenderable? = null,
|
var iconInactive: IGUIRenderable? = null,
|
||||||
val onChange: ((newValue: Boolean) -> Unit)? = null,
|
val onChange: ((newValue: Boolean) -> Unit)? = null,
|
||||||
var tooltipActive: Component? = null,
|
var tooltipActive: Component? = null,
|
||||||
var tooltipInactive: Component? = null,
|
var tooltipInactive: Component? = null,
|
||||||
@ -48,11 +49,17 @@ abstract class BooleanRectangleButtonPanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tooltipActive != null) {
|
if (tooltipActive != null) {
|
||||||
tooltips.add(tooltipActive.copy().withStyle(if (prop.get()) ChatFormatting.WHITE else ChatFormatting.GRAY))
|
if (prop.get())
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.tooltip.enum.active", tooltipActive.copy().withStyle(ChatFormatting.WHITE)))
|
||||||
|
else
|
||||||
|
tooltips.add(tooltipActive.copy().withStyle(ChatFormatting.GRAY))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooltipInactive != null) {
|
if (tooltipInactive != null) {
|
||||||
tooltips.add(tooltipInactive.copy().withStyle(if (!prop.get()) ChatFormatting.WHITE else ChatFormatting.GRAY))
|
if (prop.get())
|
||||||
|
tooltips.add(tooltipInactive.copy().withStyle(ChatFormatting.GRAY))
|
||||||
|
else
|
||||||
|
tooltips.add(TranslatableComponent("otm.gui.tooltip.enum.active", tooltipInactive.copy().withStyle(ChatFormatting.WHITE)))
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.renderComponentTooltip(font, tooltips, mouseX.toInt(), mouseY.toInt())
|
graphics.renderComponentTooltip(font, tooltips, mouseX.toInt(), mouseY.toInt())
|
||||||
@ -76,9 +83,9 @@ abstract class BooleanRectangleButtonPanel<out S : Screen>(
|
|||||||
super.innerRender(graphics, mouseX, mouseY, partialTick)
|
super.innerRender(graphics, mouseX, mouseY, partialTick)
|
||||||
|
|
||||||
if (prop.value) {
|
if (prop.value) {
|
||||||
skinElementActive?.render(graphics, width = width, height = height)
|
iconActive?.render(graphics, width = width, height = height)
|
||||||
} else {
|
} else {
|
||||||
skinElementInactive?.render(graphics, width = width, height = height)
|
iconInactive?.render(graphics, width = width, height = height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ import ru.dbotthepony.mc.otm.client.render.ItemStackIcon
|
|||||||
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
|
||||||
@ -30,7 +29,6 @@ import ru.dbotthepony.mc.otm.core.TextComponent
|
|||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.core.immutableList
|
import ru.dbotthepony.mc.otm.core.immutableList
|
||||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||||
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
|
||||||
import ru.dbotthepony.mc.otm.core.value
|
import ru.dbotthepony.mc.otm.core.value
|
||||||
import ru.dbotthepony.mc.otm.menu.UpgradeSlots
|
import ru.dbotthepony.mc.otm.menu.UpgradeSlots
|
||||||
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
||||||
@ -359,8 +357,8 @@ class DeviceControls<out S : MatteryScreen<*>>(
|
|||||||
screen,
|
screen,
|
||||||
this,
|
this,
|
||||||
prop = ascending,
|
prop = ascending,
|
||||||
skinElementActive = Widgets18.ARROW_UP,
|
iconActive = Widgets18.ARROW_UP,
|
||||||
skinElementInactive = Widgets18.ARROW_DOWN,
|
iconInactive = Widgets18.ARROW_DOWN,
|
||||||
tooltipActive = TranslatableComponent("otm.gui.sorting.ascending"),
|
tooltipActive = TranslatableComponent("otm.gui.sorting.ascending"),
|
||||||
tooltipInactive = TranslatableComponent("otm.gui.sorting.descending"),
|
tooltipInactive = TranslatableComponent("otm.gui.sorting.descending"),
|
||||||
).also {
|
).also {
|
||||||
@ -466,8 +464,8 @@ class DeviceControls<out S : MatteryScreen<*>>(
|
|||||||
balanceInputsButton = addButton(LargeBooleanRectangleButtonPanel(
|
balanceInputsButton = addButton(LargeBooleanRectangleButtonPanel(
|
||||||
screen, this,
|
screen, this,
|
||||||
prop = balanceInputs,
|
prop = balanceInputs,
|
||||||
skinElementActive = Widgets18.BALANCING_ENABLED,
|
iconActive = Widgets18.BALANCING_ENABLED,
|
||||||
skinElementInactive = Widgets18.BALANCING_DISABLED).also {
|
iconInactive = Widgets18.BALANCING_DISABLED).also {
|
||||||
it.tooltips.add(TranslatableComponent("otm.gui.balance_inputs"))
|
it.tooltips.add(TranslatableComponent("otm.gui.balance_inputs"))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,7 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels.button
|
|||||||
|
|
||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite
|
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
|
||||||
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
@ -15,12 +15,12 @@ open class LargeBooleanRectangleButtonPanel<out S : Screen>(
|
|||||||
width: Float = SIZE,
|
width: Float = SIZE,
|
||||||
height: Float = SIZE,
|
height: Float = SIZE,
|
||||||
prop: GetterSetter<Boolean>,
|
prop: GetterSetter<Boolean>,
|
||||||
skinElementActive: AbstractMatterySprite? = null,
|
iconActive: IGUIRenderable? = null,
|
||||||
skinElementInactive: AbstractMatterySprite? = null,
|
iconInactive: IGUIRenderable? = null,
|
||||||
onChange: ((newValue: Boolean) -> Unit)? = null,
|
onChange: ((newValue: Boolean) -> Unit)? = null,
|
||||||
tooltipActive: Component? = null,
|
tooltipActive: Component? = null,
|
||||||
tooltipInactive: Component? = null,
|
tooltipInactive: Component? = null,
|
||||||
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, skinElementActive, skinElementInactive, onChange, tooltipActive, tooltipInactive) {
|
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive) {
|
||||||
final override val IDLE = Widgets18.BUTTON_IDLE
|
final override val IDLE = Widgets18.BUTTON_IDLE
|
||||||
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
||||||
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
||||||
|
@ -375,12 +375,30 @@ fun <T> Comparator<in T>.nullsLast(): Comparator<T?> {
|
|||||||
return Comparator.nullsLast(this as Comparator<in T?>)
|
return Comparator.nullsLast(this as Comparator<in T?>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MappedComparator<T, O>(private val parent: Comparator<O>, private val mapper: (T) -> O) : Comparator<T> {
|
||||||
|
override fun compare(o1: T, o2: T): Int {
|
||||||
|
return parent.compare(mapper.invoke(o1), mapper.invoke(o2))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return other is MappedComparator<*, *> && parent == other.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return parent.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "MappedComparator[$parent]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun <A, B> Comparator<A>.map(mapper: (B) -> A): Comparator<B> {
|
fun <A, B> Comparator<A>.map(mapper: (B) -> A): Comparator<B> {
|
||||||
return Comparator { a, b -> this@map.compare(mapper.invoke(a), mapper.invoke(b)) }
|
return MappedComparator(this, mapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Comparator<T>.suppliers(): Comparator<Supplier<T>> {
|
fun <T> Comparator<T>.suppliers(): Comparator<Supplier<T>> {
|
||||||
return Comparator { o1, o2 -> this@suppliers.compare(o1.get(), o2.get()) }
|
return MappedComparator(this) { it.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,11 +43,7 @@ interface GetterSetter<V> : Supplier<V>, Consumer<V>, ReadWriteProperty<Any?, V>
|
|||||||
fun watch(watch: (old: V, new: V) -> Unit): GetterSetter<V> {
|
fun watch(watch: (old: V, new: V) -> Unit): GetterSetter<V> {
|
||||||
val self = this
|
val self = this
|
||||||
|
|
||||||
return object : GetterSetter<V> {
|
return object : GetterSetter<V> by self {
|
||||||
override fun get(): V {
|
|
||||||
return self.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun accept(t: V) {
|
override fun accept(t: V) {
|
||||||
val old = get()
|
val old = get()
|
||||||
self.accept(t)
|
self.accept(t)
|
||||||
@ -116,7 +112,20 @@ interface GetterSetter<V> : Supplier<V>, Consumer<V>, ReadWriteProperty<Any?, V>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SentientGetterSetter<V> : GetterSetter<V>, ISubscriptable<V>
|
interface SentientGetterSetter<V> : GetterSetter<V>, ISubscriptable<V> {
|
||||||
|
override fun watch(watch: (old: V, new: V) -> Unit): SentientGetterSetter<V> {
|
||||||
|
val self = this
|
||||||
|
|
||||||
|
return object : SentientGetterSetter<V> by self {
|
||||||
|
override fun accept(t: V) {
|
||||||
|
val old = get()
|
||||||
|
self.accept(t)
|
||||||
|
watch.invoke(old, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
operator fun <T> Supplier<T>.getValue(thisRef: Any?, property: KProperty<*>): T {
|
operator fun <T> Supplier<T>.getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
return get()
|
return get()
|
||||||
|
@ -7,8 +7,23 @@ interface IMatterGraphListener {
|
|||||||
fun onPatternRemoved(state: PatternState) {}
|
fun onPatternRemoved(state: PatternState) {}
|
||||||
fun onPatternUpdated(newState: PatternState, oldState: PatternState) {}
|
fun onPatternUpdated(newState: PatternState, oldState: PatternState) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be called any amount of times with the same task
|
||||||
|
*/
|
||||||
fun onMatterTaskCreated(task: ReplicationTask) {}
|
fun onMatterTaskCreated(task: ReplicationTask) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be called any amount of times with the same task
|
||||||
|
*/
|
||||||
fun onMatterTaskUpdated(newState: ReplicationTask, oldState: ReplicationTask) {}
|
fun onMatterTaskUpdated(newState: ReplicationTask, oldState: ReplicationTask) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be called any amount of times with the same task
|
||||||
|
*/
|
||||||
fun onMatterTaskFinished(state: ReplicationTask) {}
|
fun onMatterTaskFinished(state: ReplicationTask) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be called any amount of times with the same task
|
||||||
|
*/
|
||||||
fun onMatterTaskRemoved(state: ReplicationTask) {}
|
fun onMatterTaskRemoved(state: ReplicationTask) {}
|
||||||
}
|
}
|
||||||
|
@ -13,21 +13,22 @@ import ru.dbotthepony.mc.otm.capability.matter.*
|
|||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
import ru.dbotthepony.mc.otm.core.addSorted
|
import ru.dbotthepony.mc.otm.core.addSorted
|
||||||
|
import ru.dbotthepony.mc.otm.core.map
|
||||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.util.BooleanValueCodec
|
|
||||||
import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec
|
import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec
|
||||||
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.NullValueCodec
|
||||||
import ru.dbotthepony.mc.otm.core.util.codec
|
import ru.dbotthepony.mc.otm.core.util.codec
|
||||||
import ru.dbotthepony.mc.otm.core.util.writeCollection
|
import ru.dbotthepony.mc.otm.core.util.writeCollection
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
|
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
||||||
import ru.dbotthepony.mc.otm.network.*
|
import ru.dbotthepony.mc.otm.network.*
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
import kotlin.Comparator
|
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class CancelTaskPacket(val id: UUID) : MatteryPacket {
|
class CancelTaskPacket(val id: UUID) : MatteryPacket {
|
||||||
@ -128,10 +129,10 @@ class ReplicationRequestPacket(val id: UUID, amount: Int) : MatteryPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MatterPanelMenu(
|
class MatterPanelMenu(
|
||||||
p_38852_: Int,
|
containerId: Int,
|
||||||
inventory: Inventory,
|
inventory: Inventory,
|
||||||
tile: MatterPanelBlockEntity? = null
|
tile: MatterPanelBlockEntity? = null
|
||||||
) : MatteryMenu(MMenus.MATTER_PANEL, p_38852_, inventory, tile), IMatterGraphListener {
|
) : MatteryMenu(MMenus.MATTER_PANEL, containerId, inventory, tile), IMatterGraphListener {
|
||||||
fun taskUpdated(task: ReplicationTask) {
|
fun taskUpdated(task: ReplicationTask) {
|
||||||
sendNetwork(TasksChangePacket(true, listOf(task)))
|
sendNetwork(TasksChangePacket(true, listOf(task)))
|
||||||
}
|
}
|
||||||
@ -140,25 +141,36 @@ class MatterPanelMenu(
|
|||||||
sendNetwork(TasksChangePacket(false, listOf(task)))
|
sendNetwork(TasksChangePacket(false, listOf(task)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val sorting: ItemSorter by mSynchronizer.ComputedField(
|
private fun updateComparators() {
|
||||||
getter = { tile?.getPlayerSettings(player)?.sorter ?: ItemSorter.DEFAULT },
|
var p = sorting.map(PatternState::item)
|
||||||
codec = ItemSorter::class.codec(),
|
var t = sorting.map(ReplicationTask::item)
|
||||||
observer = {
|
|
||||||
patterns.sortWith(actualComparator)
|
|
||||||
patternsFiltered.sortWith(actualComparator)
|
|
||||||
tasks.sortWith(actualTaskComparator)
|
|
||||||
tasksFiltered.sortWith(actualTaskComparator)
|
|
||||||
})
|
|
||||||
|
|
||||||
val isAscending: Boolean by mSynchronizer.ComputedField(
|
if (!isAscending) {
|
||||||
getter = { tile?.getPlayerSettings(player)?.ascending ?: true },
|
p = p.reversed()
|
||||||
codec = BooleanValueCodec,
|
t = t.reversed()
|
||||||
observer = {
|
}
|
||||||
patterns.sortWith(actualComparator)
|
|
||||||
patternsFiltered.sortWith(actualComparator)
|
patternComparator = p
|
||||||
tasks.sortWith(actualTaskComparator)
|
taskComparator = t
|
||||||
tasksFiltered.sortWith(actualTaskComparator)
|
}
|
||||||
})
|
|
||||||
|
var sorting: ItemSorter by GetterSetter.of(
|
||||||
|
mSynchronizer.ComputedField(
|
||||||
|
getter = { tile?.getPlayerSettings(player)?.sorter ?: ItemSorter.DEFAULT },
|
||||||
|
codec = ItemSorter::class.codec(),
|
||||||
|
observer = { updateComparators() }),
|
||||||
|
PlayerInput(ItemSorter::class.codec(), allowSpectators = true) { tile?.getPlayerSettings(player)?.sorter = it }
|
||||||
|
)
|
||||||
|
|
||||||
|
var isAscending: Boolean by GetterSetter.of(
|
||||||
|
mSynchronizer.ComputedBooleanField(
|
||||||
|
getter = { tile?.getPlayerSettings(player)?.ascending ?: true },
|
||||||
|
observer = { updateComparators() }),
|
||||||
|
booleanInput(allowSpectators = true) { tile?.getPlayerSettings(player)?.ascending = it }
|
||||||
|
)
|
||||||
|
|
||||||
|
var isProvidingTasks by BooleanInputWithFeedback(this, tile?.let { it::isProvidingTasks })
|
||||||
|
val cancelAll = PlayerInput(NullValueCodec) { tile?.dropAllTasks() }
|
||||||
|
|
||||||
val totalMatterStored: Decimal by mSynchronizer.ComputedField(
|
val totalMatterStored: Decimal by mSynchronizer.ComputedField(
|
||||||
getter = { tile?.matterNode?.graph?.getMatterStorageLevel() ?: Decimal.ZERO },
|
getter = { tile?.matterNode?.graph?.getMatterStorageLevel() ?: Decimal.ZERO },
|
||||||
@ -184,14 +196,23 @@ class MatterPanelMenu(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val changeIsAscending = booleanInput(allowSpectators = true) { tile?.getPlayerSettings(player)?.ascending = it }
|
private var patternComparator = sorting.map(PatternState::item)
|
||||||
val changeSorting = PlayerInput(ItemSorter::class.codec(), allowSpectators = true) { tile?.getPlayerSettings(player)?.sorter = it }
|
set(value) {
|
||||||
|
if (value != field) {
|
||||||
|
field = value
|
||||||
|
patterns.sortWith(value)
|
||||||
|
patternsFiltered.sortWith(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val sortingGS = GetterSetter.of(::sorting, changeSorting::accept)
|
private var taskComparator = sorting.map(ReplicationTask::item)
|
||||||
val isAscendingGS = GetterSetter.of(::isAscending, changeIsAscending::accept)
|
set(value) {
|
||||||
|
if (value != field) {
|
||||||
private val actualComparator = Comparator<PatternState> { o1, o2 -> sorting.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) }
|
field = value
|
||||||
private val actualTaskComparator = Comparator<ReplicationTask> { o1, o2 -> sorting.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) }
|
tasks.sortWith(value)
|
||||||
|
tasksFiltered.sortWith(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val patterns = ArrayList<PatternState>()
|
private val patterns = ArrayList<PatternState>()
|
||||||
private val tasks = ArrayList<ReplicationTask>()
|
private val tasks = ArrayList<ReplicationTask>()
|
||||||
@ -206,7 +227,7 @@ class MatterPanelMenu(
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.patterns[index] = pattern
|
this.patterns[index] = pattern
|
||||||
} else {
|
} else {
|
||||||
this.patterns.addSorted(pattern, actualComparator)
|
this.patterns.addSorted(pattern, patternComparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter.test(pattern.item)) {
|
if (filter.test(pattern.item)) {
|
||||||
@ -215,7 +236,7 @@ class MatterPanelMenu(
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.patternsFiltered[index] = pattern
|
this.patternsFiltered[index] = pattern
|
||||||
} else {
|
} else {
|
||||||
this.patternsFiltered.addSorted(pattern, actualComparator)
|
this.patternsFiltered.addSorted(pattern, patternComparator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,7 +255,7 @@ class MatterPanelMenu(
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.tasks[index] = task
|
this.tasks[index] = task
|
||||||
} else {
|
} else {
|
||||||
this.tasks.addSorted(task, actualTaskComparator)
|
this.tasks.addSorted(task, taskComparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter.test(task.item)) {
|
if (filter.test(task.item)) {
|
||||||
@ -243,7 +264,7 @@ class MatterPanelMenu(
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.tasksFiltered[index] = task
|
this.tasksFiltered[index] = task
|
||||||
} else {
|
} else {
|
||||||
this.tasksFiltered.addSorted(task, actualTaskComparator)
|
this.tasksFiltered.addSorted(task, taskComparator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,7 +341,7 @@ class MatterPanelMenu(
|
|||||||
|
|
||||||
override fun removed(p_38940_: Player) {
|
override fun removed(p_38940_: Player) {
|
||||||
super.removed(p_38940_)
|
super.removed(p_38940_)
|
||||||
(tile as MatterPanelBlockEntity?)?.deatachMenu(this)
|
(tile as MatterPanelBlockEntity?)?.detachMenu(this)
|
||||||
listeningGrid?.removeListener(this)
|
listeningGrid?.removeListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,12 +1092,18 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|||||||
inner class ComputedField<V>(
|
inner class ComputedField<V>(
|
||||||
private val getter: () -> V,
|
private val getter: () -> V,
|
||||||
private val codec: IStreamCodec<V>,
|
private val codec: IStreamCodec<V>,
|
||||||
private val observer: (new: V) -> Unit = {}
|
observer: ((new: V) -> Unit)? = null
|
||||||
) : AbstractField<V>(), IField<V> {
|
) : AbstractField<V>(), IField<V> {
|
||||||
private var remote: Any? = Mark
|
private var remote: Any? = Mark
|
||||||
private var clientValue: Any? = Mark
|
private var clientValue: Any? = Mark
|
||||||
private val subs = ISubscriptable.Impl<V>()
|
private val subs = ISubscriptable.Impl<V>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (observer != null) {
|
||||||
|
subs.addListener(observer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun addListener(listener: Consumer<V>): ISubscriptable.L {
|
override fun addListener(listener: Consumer<V>): ISubscriptable.L {
|
||||||
return subs.addListener(listener)
|
return subs.addListener(listener)
|
||||||
}
|
}
|
||||||
@ -1141,7 +1147,6 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|||||||
check(!isRemoved) { "Field was removed" }
|
check(!isRemoved) { "Field was removed" }
|
||||||
val newValue = codec.read(stream)
|
val newValue = codec.read(stream)
|
||||||
clientValue = newValue
|
clientValue = newValue
|
||||||
observer.invoke(newValue)
|
|
||||||
subs.accept(newValue)
|
subs.accept(newValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 981 B After Width: | Height: | Size: 1020 B |
Binary file not shown.
Loading…
Reference in New Issue
Block a user