mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-24 13:02:48 +01:00
Restore the commits mistakenly deleted
The develop branch history was forcefully overwritten when merging in the sound card support. This commit restores the commits that were deleted due to this. See also !31. Closes #64.
This commit is contained in:
commit
dc6a8d00a2
@ -24,6 +24,7 @@ import java.util.concurrent.locks.{Lock, ReentrantLock}
|
||||
import javax.swing.JFileChooser
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.concurrent.duration.Duration
|
||||
import scala.io.Source
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.util.{Failure, Success, Try}
|
||||
@ -36,9 +37,9 @@ object OcelotDesktop extends Logging {
|
||||
val ticker = new Ticker
|
||||
|
||||
private val TickerIntervalHistorySize = 5
|
||||
val tickerIntervalHistory = new mutable.Queue[Long](TickerIntervalHistorySize)
|
||||
val tickerIntervalHistory = new mutable.Queue[Duration](TickerIntervalHistorySize)
|
||||
|
||||
def pushToTickerIntervalHistory(interval: Long): Unit = {
|
||||
def pushToTickerIntervalHistory(interval: Duration): Unit = {
|
||||
if (tickerIntervalHistory.size >= TickerIntervalHistorySize) tickerIntervalHistory.dequeue()
|
||||
tickerIntervalHistory.enqueue(interval)
|
||||
}
|
||||
|
||||
@ -19,4 +19,8 @@ class RelayNode(val relay: Relay) extends Node(relay) {
|
||||
override def getNodeByPort(port: NodePort): network.Node = relay.sidedNode(port.direction.get)
|
||||
|
||||
override protected val exposeAddress = false
|
||||
|
||||
override def shouldReceiveEventsFor(address: String): Boolean = {
|
||||
ports.exists(port => getNodeByPort(port).address == address)
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import java.nio.channels.Channels
|
||||
import java.nio.file.{Files, Paths}
|
||||
import javax.imageio.ImageIO
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration.DurationInt
|
||||
|
||||
object UiHandler extends Logging {
|
||||
var root: RootWidget = _
|
||||
@ -34,7 +35,7 @@ object UiHandler extends Logging {
|
||||
private val fpsCalculator = new FPSCalculator
|
||||
private val ticker = new Ticker
|
||||
|
||||
ticker.tickInterval = 1000f / 60f
|
||||
ticker.tickInterval = 1.second / 60
|
||||
|
||||
def getHierarchy: Array[Widget] = hierarchy.toArray
|
||||
|
||||
|
||||
@ -4,11 +4,14 @@ import ocelot.desktop.OcelotDesktop
|
||||
import ocelot.desktop.audio.{SoundSource, SoundSources}
|
||||
import ocelot.desktop.geometry.Padding2D
|
||||
import ocelot.desktop.ui.layout.LinearLayout
|
||||
import ocelot.desktop.ui.widget.ChangeSimulationSpeedDialog.validateIntervalUs
|
||||
import ocelot.desktop.ui.widget.modal.ModalDialog
|
||||
import ocelot.desktop.util.Orientation
|
||||
|
||||
import scala.concurrent.duration.{Duration, DurationLong}
|
||||
|
||||
class ChangeSimulationSpeedDialog() extends ModalDialog {
|
||||
private var tickInterval: Option[Long] = Some(OcelotDesktop.ticker.tickInterval)
|
||||
private var tickInterval: Option[Duration] = Some(OcelotDesktop.ticker.tickInterval)
|
||||
|
||||
private def confirm(): Unit = {
|
||||
if (tickInterval.isDefined) {
|
||||
@ -27,53 +30,45 @@ class ChangeSimulationSpeedDialog() extends ModalDialog {
|
||||
|
||||
private var inputTPS: TextInput = _
|
||||
private var inputMSPT: TextInput = _
|
||||
private def formatMSPT(v: Long) = (v.toFloat / 1000).toString
|
||||
private def formatTPS(v: Long) = (1000000 / v.toFloat).toString
|
||||
private def formatMSPT(interval: Duration): String = (interval.toMicros / 1000f).toString
|
||||
private def formatTPS(interval: Duration): String = (1_000_000f / interval.toMicros).toString
|
||||
|
||||
inputMSPT = new TextInput(formatMSPT(OcelotDesktop.ticker.tickInterval)) {
|
||||
focus()
|
||||
|
||||
private def parseInput(text: String): Option[Duration] = try {
|
||||
validateIntervalUs((text.toFloat * 1000).toLong)
|
||||
} catch {
|
||||
case _: NumberFormatException => None
|
||||
}
|
||||
|
||||
override def onInput(text: String): Unit = {
|
||||
tickInterval = try {
|
||||
val v = (text.toFloat * 1000).toLong
|
||||
inputTPS.setInput(formatTPS(v))
|
||||
Some(v)
|
||||
} catch {
|
||||
case _: NumberFormatException => None
|
||||
tickInterval = parseInput(text).map { interval =>
|
||||
inputTPS.setInput(formatTPS(interval))
|
||||
interval
|
||||
}
|
||||
}
|
||||
|
||||
override def validator(text: String): Boolean = {
|
||||
try {
|
||||
text.toFloat
|
||||
true
|
||||
} catch {
|
||||
case _: NumberFormatException => false
|
||||
}
|
||||
}
|
||||
override def validator(text: String): Boolean = parseInput(text).isDefined
|
||||
|
||||
override def onConfirm(): Unit = confirm()
|
||||
}
|
||||
|
||||
inputTPS = new TextInput(formatTPS(OcelotDesktop.ticker.tickInterval)) {
|
||||
private def parseInput(text: String): Option[Duration] = try {
|
||||
validateIntervalUs((1_000_000 / text.toFloat).toLong)
|
||||
} catch {
|
||||
case _: NumberFormatException => None
|
||||
}
|
||||
|
||||
override def onInput(text: String): Unit = {
|
||||
tickInterval = try {
|
||||
val v = ((1 / text.toFloat) * 1000000).toLong
|
||||
inputMSPT.setInput(formatMSPT(v))
|
||||
Some(v)
|
||||
} catch {
|
||||
case _: NumberFormatException => None
|
||||
tickInterval = parseInput(text).map { interval =>
|
||||
inputMSPT.setInput(formatMSPT(interval))
|
||||
interval
|
||||
}
|
||||
}
|
||||
|
||||
override def validator(text: String): Boolean = {
|
||||
try {
|
||||
text.toFloat
|
||||
true
|
||||
} catch {
|
||||
case _: NumberFormatException => false
|
||||
}
|
||||
}
|
||||
override def validator(text: String): Boolean = parseInput(text).isDefined
|
||||
|
||||
override def onConfirm(): Unit = confirm()
|
||||
}
|
||||
@ -96,6 +91,7 @@ class ChangeSimulationSpeedDialog() extends ModalDialog {
|
||||
override def onClick(): Unit = close()
|
||||
}, Padding2D(right = 8))
|
||||
|
||||
// TODO: disable the button if tickInterval.isEmpty
|
||||
children :+= new Button {
|
||||
override def text: String = "Apply"
|
||||
override def onClick(): Unit = confirm()
|
||||
@ -103,3 +99,16 @@ class ChangeSimulationSpeedDialog() extends ModalDialog {
|
||||
}
|
||||
}, Padding2D.equal(16))
|
||||
}
|
||||
|
||||
object ChangeSimulationSpeedDialog {
|
||||
private val MaxUpdateInterval = 1.minute
|
||||
private val MinUpdateInterval = 1.micro
|
||||
|
||||
private def validateIntervalUs(us: Long): Option[Duration] = try {
|
||||
val interval = us.micros
|
||||
|
||||
Option.when(interval >= MinUpdateInterval && interval <= MaxUpdateInterval)(interval)
|
||||
} catch {
|
||||
case _: IllegalArgumentException => None
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package ocelot.desktop.ui.widget.statusbar
|
||||
|
||||
import ocelot.desktop.audio.Audio
|
||||
import ocelot.desktop.color.Color
|
||||
import ocelot.desktop.geometry.{Padding2D, Size2D}
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
@ -13,6 +12,8 @@ import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry}
|
||||
import ocelot.desktop.{ColorScheme, OcelotDesktop}
|
||||
import org.lwjgl.input.Keyboard
|
||||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
|
||||
class StatusBar extends Widget {
|
||||
override protected val layout: LinearLayout = new LinearLayout(this, contentAlignment = Alignment.Center) {
|
||||
contentAlignment = Alignment.Center
|
||||
@ -59,12 +60,12 @@ class StatusBar extends Widget {
|
||||
new ChangeSimulationSpeedDialog().show()
|
||||
}))
|
||||
menu.addEntry(new ContextMenuEntry("Reset simulation speed", () => {
|
||||
OcelotDesktop.ticker.tickInterval = 50000
|
||||
OcelotDesktop.ticker.tickInterval = 50.millis
|
||||
}))
|
||||
if (OcelotDesktop.tickerIntervalHistory.nonEmpty)
|
||||
menu.addSeparator()
|
||||
for (elem <- OcelotDesktop.tickerIntervalHistory.reverseIterator) {
|
||||
menu.addEntry(new ContextMenuEntry((1000000 / elem.toFloat).toString, () => {
|
||||
menu.addEntry(new ContextMenuEntry((1_000_000f / elem.toMicros).toString, () => {
|
||||
OcelotDesktop.ticker.tickInterval = elem
|
||||
}))
|
||||
}
|
||||
|
||||
@ -1,24 +1,26 @@
|
||||
package ocelot.desktop.util
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scala.concurrent.duration.{Duration, DurationInt}
|
||||
|
||||
class Ticker extends Logging {
|
||||
var lastTick: Long = System.nanoTime()
|
||||
var tick: Long = 0
|
||||
|
||||
private[this] var _tickInterval: Long = _
|
||||
private var _tickIntervalNs: Long = _
|
||||
|
||||
def tickInterval: Long = _tickInterval / 1000
|
||||
def tickInterval: Duration = Duration.fromNanos(_tickIntervalNs)
|
||||
|
||||
def tickInterval_=(us: Float): Unit = {
|
||||
logger.info(f"Setting tick interval to $us us (${1000000f / us} s^-1)")
|
||||
_tickInterval = (us * 1000).toLong
|
||||
def tickInterval_=(interval: Duration): Unit = {
|
||||
val us = interval.toMicros
|
||||
logger.info(f"Setting tick interval to $us μs (${1_000_000f / us} s^-1)")
|
||||
_tickIntervalNs = interval.toNanos
|
||||
}
|
||||
|
||||
tickInterval = 50000
|
||||
tickInterval = 1.second / 20
|
||||
|
||||
def waitNext(): Unit = {
|
||||
val deadline = lastTick + _tickInterval
|
||||
val deadline = lastTick + _tickIntervalNs
|
||||
var time = System.nanoTime()
|
||||
while (time < deadline) {
|
||||
val rem = deadline - time
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user