mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-20 02:59:19 +01:00
Merge branch 'feature/relay-gui' into develop
This commit is contained in:
commit
9d323138d3
@ -1 +1 @@
|
||||
Subproject commit 4691682de8b765ac0f862c57a08e29f8d776fb46
|
||||
Subproject commit e1968df8a58fab83572e657d981b7263c7edd72a
|
||||
@ -186,3 +186,7 @@ OcelotCardTooltip = #c1905f
|
||||
RackRelayButtonText = #e0e0e0
|
||||
|
||||
Flash = #ffffff
|
||||
|
||||
RelayTextLow = #009900
|
||||
RelayTextMid = #999900
|
||||
RelayTextHigh = #990000
|
||||
|
||||
@ -12,6 +12,7 @@ import ocelot.desktop.util.ReflectionUtils.findUnaryConstructor
|
||||
import totoro.ocelot.brain.entity.traits.{Entity, Environment, Inventory => BrainInventory}
|
||||
import totoro.ocelot.brain.event.{InventoryEntityAddedEvent, InventoryEntityRemovedEvent}
|
||||
import totoro.ocelot.brain.nbt.NBTTagCompound
|
||||
import totoro.ocelot.brain.network.Network
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
@ -98,6 +99,17 @@ trait SyncedInventory extends PersistedInventory with EventAware with Logging {
|
||||
|
||||
override def onItemAdded(slot: Slot): Unit = {
|
||||
if (!isLoading) {
|
||||
// FIXME: the sheer scope of this atrocity is mind-blowing:
|
||||
// we strip nodes of their free will and forcefully imprint onto them an address —
|
||||
// and only because there is no other way to identify brain entities!
|
||||
// in an ideal world, persistable objects should have a stable identifier
|
||||
// which is in no way tied to environments and their addresses.
|
||||
// alas, for the time being we have to bear the burden of grave sins and war crimes.
|
||||
val component = slot.get.get.asInstanceOf[ComponentItem].component
|
||||
if (component.node.address == null) {
|
||||
Network.joinNewNetwork(component.node)
|
||||
}
|
||||
|
||||
sync(slot.index, SyncDirection.DesktopToBrain)
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ class ServerItem(val server: Server)
|
||||
server.tier match {
|
||||
case Tier.One =>
|
||||
cardSlots = addSlotWidgets(new CardSlotWidget(_, Tier.Two), new CardSlotWidget(_, Tier.Two))
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.Two))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Two))
|
||||
componentBusSlots = addSlotWidgets(new ComponentBusSlotWidget(_, Tier.Two))
|
||||
memorySlots = addSlotWidgets(new MemorySlotWidget(_, Tier.Two), new MemorySlotWidget(_, Tier.Two))
|
||||
diskSlots = addSlotWidgets(new HddSlotWidget(_, Tier.Two))
|
||||
@ -45,7 +45,7 @@ class ServerItem(val server: Server)
|
||||
|
||||
case Tier.Two =>
|
||||
cardSlots = addSlotWidgets(new CardSlotWidget(_, Tier.Three), new CardSlotWidget(_, Tier.Two), new CardSlotWidget(_, Tier.Two))
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.Three))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Three))
|
||||
componentBusSlots = addSlotWidgets(new ComponentBusSlotWidget(_, Tier.Three), new ComponentBusSlotWidget(_, Tier.Three))
|
||||
memorySlots = addSlotWidgets(new MemorySlotWidget(_, Tier.Three), new MemorySlotWidget(_, Tier.Three), new MemorySlotWidget(_, Tier.Three))
|
||||
diskSlots = addSlotWidgets(new HddSlotWidget(_, Tier.Three), new HddSlotWidget(_, Tier.Three))
|
||||
@ -70,7 +70,7 @@ class ServerItem(val server: Server)
|
||||
)
|
||||
}
|
||||
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.Three))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Three))
|
||||
|
||||
componentBusSlots = addSlotWidgets(
|
||||
new ComponentBusSlotWidget(_, Tier.Three),
|
||||
|
||||
@ -66,7 +66,7 @@ class ComputerNode(val computerCase: Case)
|
||||
memorySlots = addSlotWidgets(new MemorySlotWidget(_, Tier.One))
|
||||
diskSlots = addSlotWidgets(new HddSlotWidget(_, Tier.One))
|
||||
floppySlot = None
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.One))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.One))
|
||||
// no idea why on earth the memory slots are split in two here
|
||||
memorySlots :+= addSlotWidget(new MemorySlotWidget(_, Tier.One))
|
||||
eepromSlot = addSlotWidget(new EepromSlotWidget(_))
|
||||
@ -76,7 +76,7 @@ class ComputerNode(val computerCase: Case)
|
||||
memorySlots = addSlotWidgets(new MemorySlotWidget(_, Tier.Two), new MemorySlotWidget(_, Tier.Two))
|
||||
diskSlots = addSlotWidgets(new HddSlotWidget(_, Tier.Two), new HddSlotWidget(_, Tier.One))
|
||||
floppySlot = None
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.Two))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Two))
|
||||
eepromSlot = addSlotWidget(new EepromSlotWidget(_))
|
||||
|
||||
case _ =>
|
||||
@ -107,7 +107,7 @@ class ComputerNode(val computerCase: Case)
|
||||
}
|
||||
|
||||
floppySlot = Some(addSlotWidget(new FloppySlotWidget(_)))
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.Three))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Three))
|
||||
eepromSlot = addSlotWidget(new EepromSlotWidget(_))
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ class MicrocontrollerNode(val microcontroller: Microcontroller)
|
||||
new CardSlotWidget(_, Tier.One)
|
||||
)
|
||||
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.One))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.One))
|
||||
|
||||
memorySlots = addSlotWidgets(
|
||||
new MemorySlotWidget(_, Tier.One),
|
||||
@ -89,7 +89,7 @@ class MicrocontrollerNode(val microcontroller: Microcontroller)
|
||||
new CardSlotWidget(_, Tier.One)
|
||||
)
|
||||
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.One))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.One))
|
||||
|
||||
memorySlots = addSlotWidgets(
|
||||
new MemorySlotWidget(_, Tier.One),
|
||||
@ -105,7 +105,7 @@ class MicrocontrollerNode(val microcontroller: Microcontroller)
|
||||
new CardSlotWidget(_, Tier.Three)
|
||||
)
|
||||
|
||||
cpuSlot = addSlotWidget(new CpuSlotWidget(_, this, Tier.Three))
|
||||
cpuSlot = addSlotWidget(new ComputerCpuSlotWidget(_, this, Tier.Three))
|
||||
|
||||
memorySlots = addSlotWidgets(
|
||||
new MemorySlotWidget(_, Tier.Three),
|
||||
|
||||
@ -1,12 +1,19 @@
|
||||
package ocelot.desktop.node.nodes
|
||||
|
||||
import ocelot.desktop.graphics.IconSource
|
||||
import ocelot.desktop.node.{EntityNode, NodePort}
|
||||
import ocelot.desktop.inventory.SyncedInventory
|
||||
import ocelot.desktop.node.{EntityNode, LabeledNode, NodePort, WindowedNode}
|
||||
import ocelot.desktop.windows.RelayWindow
|
||||
import totoro.ocelot.brain.entity.Relay
|
||||
import totoro.ocelot.brain.network
|
||||
import totoro.ocelot.brain.util.Direction
|
||||
|
||||
class RelayNode(val relay: Relay) extends EntityNode(relay) {
|
||||
class RelayNode(val relay: Relay)
|
||||
extends EntityNode(relay)
|
||||
with SyncedInventory
|
||||
with LabeledNode
|
||||
with WindowedNode[RelayWindow] {
|
||||
|
||||
override val iconSource: IconSource = IconSource.Nodes.Relay
|
||||
|
||||
override def ports: Array[NodePort] = Array(
|
||||
@ -24,4 +31,8 @@ class RelayNode(val relay: Relay) extends EntityNode(relay) {
|
||||
override def shouldReceiveEventsFor(address: String): Boolean = {
|
||||
ports.exists(port => getNodeByPort(port).address == address)
|
||||
}
|
||||
|
||||
override def brainInventory: Relay = relay
|
||||
|
||||
override protected def createWindow(): RelayWindow = new RelayWindow(this)
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package ocelot.desktop.ui.widget.slot
|
||||
|
||||
import ocelot.desktop.inventory.traits.CpuLikeItem
|
||||
import ocelot.desktop.inventory.{Inventory, Item}
|
||||
import ocelot.desktop.util.ComputerAware
|
||||
import totoro.ocelot.brain.util.Tier.Tier
|
||||
|
||||
class ComputerCpuSlotWidget(slot: Inventory#Slot, computer: ComputerAware, _tier: Tier)
|
||||
extends CpuSlotWidget(slot, _tier) {
|
||||
|
||||
protected override def onItemNotification(notification: Item.Notification): Unit = {
|
||||
super.onItemNotification(notification)
|
||||
|
||||
notification match {
|
||||
case CpuLikeItem.CpuArchitectureChangedNotification =>
|
||||
computer.turnOn()
|
||||
computer.turnOff()
|
||||
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,24 +1,11 @@
|
||||
package ocelot.desktop.ui.widget.slot
|
||||
|
||||
import ocelot.desktop.graphics.IconSource
|
||||
import ocelot.desktop.inventory.Inventory
|
||||
import ocelot.desktop.inventory.traits.CpuLikeItem
|
||||
import ocelot.desktop.inventory.{Inventory, Item}
|
||||
import ocelot.desktop.util.ComputerAware
|
||||
import totoro.ocelot.brain.util.Tier.Tier
|
||||
|
||||
class CpuSlotWidget(slot: Inventory#Slot, computer: ComputerAware, _tier: Tier) extends SlotWidget[CpuLikeItem](slot) {
|
||||
class CpuSlotWidget(slot: Inventory#Slot, _tier: Tier) extends SlotWidget[CpuLikeItem](slot) {
|
||||
override def ghostIcon: Option[IconSource] = Some(IconSource.CpuIcon)
|
||||
override def slotTier: Option[Tier] = Some(_tier)
|
||||
|
||||
protected override def onItemNotification(notification: Item.Notification): Unit = {
|
||||
super.onItemNotification(notification)
|
||||
|
||||
notification match {
|
||||
case CpuLikeItem.CpuArchitectureChangedNotification =>
|
||||
computer.turnOn()
|
||||
computer.turnOff()
|
||||
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ trait ComputerAware
|
||||
}
|
||||
|
||||
var eepromSlot: EepromSlotWidget = _
|
||||
var cpuSlot: CpuSlotWidget = _
|
||||
var cpuSlot: ComputerCpuSlotWidget = _
|
||||
var componentBusSlots: Array[ComponentBusSlotWidget] = Array.empty
|
||||
var memorySlots: Array[MemorySlotWidget] = Array.empty
|
||||
var cardSlots: Array[CardSlotWidget] = Array.empty
|
||||
|
||||
143
src/main/scala/ocelot/desktop/windows/RelayWindow.scala
Normal file
143
src/main/scala/ocelot/desktop/windows/RelayWindow.scala
Normal file
@ -0,0 +1,143 @@
|
||||
package ocelot.desktop.windows
|
||||
|
||||
import ocelot.desktop.ColorScheme
|
||||
import ocelot.desktop.color.Color
|
||||
import ocelot.desktop.geometry.Size2D
|
||||
import ocelot.desktop.inventory.ItemFactory
|
||||
import ocelot.desktop.inventory.item.{LinkedCardItem, WirelessNetworkCardItem}
|
||||
import ocelot.desktop.node.nodes.RelayNode
|
||||
import ocelot.desktop.ui.layout.{AlignItems, JustifyContent, Layout, LinearLayout}
|
||||
import ocelot.desktop.ui.widget.slot.{CardSlotWidget, CpuSlotWidget, HddSlotWidget, MemorySlotWidget}
|
||||
import ocelot.desktop.ui.widget.window.PanelWindow
|
||||
import ocelot.desktop.ui.widget.{Label, Widget}
|
||||
import ocelot.desktop.util.Orientation
|
||||
import ocelot.desktop.windows.RelayWindow.{LabelWidth, TransferRateFormat}
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
import totoro.ocelot.brain.util.Tier.Tier
|
||||
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class RelayWindow(val node: RelayNode) extends PanelWindow {
|
||||
override protected def title: String = "Relay"
|
||||
|
||||
private def makeLabel(_text: => String): Label = new Label {
|
||||
override def text: String = _text
|
||||
|
||||
override def minimumSize: Size2D = super.minimumSize.copy(width = LabelWidth)
|
||||
|
||||
override def maximumSize: Size2D = minimumSize
|
||||
}
|
||||
|
||||
setInner(new Widget {
|
||||
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical, gap = 4f)
|
||||
|
||||
// CPU
|
||||
children :+= new Widget {
|
||||
override protected val layout: Layout = new LinearLayout(
|
||||
this,
|
||||
orientation = Orientation.Horizontal,
|
||||
alignItems = AlignItems.Center,
|
||||
gap = 8f,
|
||||
)
|
||||
|
||||
children :+= makeLabel("Cycle rate")
|
||||
|
||||
children :+= new Label {
|
||||
override def text: String = s"${TransferRateFormat.format(20f / node.relay.relayDelay)}"
|
||||
}
|
||||
|
||||
children :+= new CpuSlotWidget(node.Slot(node.relay.cpuSlot.index), Tier.Three) {
|
||||
override def slotTier: Option[Tier] = None
|
||||
}
|
||||
}
|
||||
|
||||
// Memory
|
||||
children :+= new Widget {
|
||||
override protected val layout: Layout = new LinearLayout(
|
||||
this,
|
||||
orientation = Orientation.Horizontal,
|
||||
alignItems = AlignItems.Center,
|
||||
gap = 8f,
|
||||
)
|
||||
|
||||
children :+= makeLabel("Packets / cycle")
|
||||
|
||||
children :+= new Label {
|
||||
override def text: String = s"${node.relay.packetsPerCycleAvg()} / ${node.relay.relayAmount}"
|
||||
|
||||
override def color: Color = thresholdBasedColor(
|
||||
node.relay.packetsPerCycleAvg(),
|
||||
(node.relay.relayAmount / 2f).ceil.toInt,
|
||||
node.relay.relayAmount,
|
||||
)
|
||||
}
|
||||
|
||||
children :+= new MemorySlotWidget(node.Slot(node.relay.memorySlot.index), Tier.Three) {
|
||||
override def slotTier: Option[Tier] = None
|
||||
}
|
||||
}
|
||||
|
||||
// HDD
|
||||
children :+= new Widget {
|
||||
override protected val layout: Layout = new LinearLayout(
|
||||
this,
|
||||
orientation = Orientation.Horizontal,
|
||||
alignItems = AlignItems.Center,
|
||||
gap = 8f,
|
||||
)
|
||||
|
||||
children :+= makeLabel("Queue size")
|
||||
|
||||
children :+= new Label {
|
||||
override def text: String = s"${node.relay.queue.size} / ${node.relay.maxQueueSize}"
|
||||
|
||||
override def color: Color = thresholdBasedColor(
|
||||
node.relay.queue.size,
|
||||
node.relay.maxQueueSize / 2,
|
||||
node.relay.maxQueueSize,
|
||||
)
|
||||
}
|
||||
|
||||
children :+= new HddSlotWidget(node.Slot(node.relay.hddSlot.index), Tier.Three) {
|
||||
override def slotTier: Option[Tier] = None
|
||||
}
|
||||
}
|
||||
|
||||
// Network card
|
||||
children :+= new Widget {
|
||||
override protected val layout: Layout = new LinearLayout(
|
||||
this,
|
||||
orientation = Orientation.Horizontal,
|
||||
justifyContent = JustifyContent.End,
|
||||
gap = 8f,
|
||||
)
|
||||
|
||||
override def maximumSize: Size2D = super.maximumSize.copy(width = Float.PositiveInfinity)
|
||||
|
||||
children :+= new CardSlotWidget(node.Slot(node.relay.networkCardSlot.index), Tier.Three) {
|
||||
override def slotTier: Option[Tier] = None
|
||||
|
||||
override def isItemAccepted(factory: ItemFactory): Boolean = {
|
||||
super.isItemAccepted(factory) &&
|
||||
Array(classOf[WirelessNetworkCardItem], classOf[LinkedCardItem])
|
||||
.exists(_.isAssignableFrom(factory.itemClass))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
private def thresholdBasedColor(value: Int, mid: Int, high: Int): Color = {
|
||||
if (value < mid) {
|
||||
ColorScheme("RelayTextLow")
|
||||
} else if (value < high) {
|
||||
ColorScheme("RelayTextMid")
|
||||
} else {
|
||||
ColorScheme("RelayTextHigh")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object RelayWindow {
|
||||
private val TransferRateFormat = new DecimalFormat("#.##hz")
|
||||
private val LabelWidth = 130
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user