mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2026-01-08 04:02:39 +01:00
Fix brain event snapshotting; remove obsolete synchronization
This commit is contained in:
parent
fd6400f39a
commit
094ac8cb48
@ -26,6 +26,7 @@ import javax.imageio.ImageIO
|
||||
import javax.swing.JFileChooser
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.concurrent.duration.DurationInt
|
||||
import scala.util.Try
|
||||
|
||||
@ -437,24 +438,24 @@ object UiHandler extends Logging {
|
||||
}
|
||||
|
||||
private def dispatchBrainEvents(): Unit = {
|
||||
import totoro.ocelot.brain
|
||||
|
||||
val cutoff = BrainEvents.events.peekLast()
|
||||
|
||||
if (cutoff == null) {
|
||||
return
|
||||
}
|
||||
|
||||
// we're effectively taking a snapshot of all events we have received at the point of the call.
|
||||
// we're taking a snapshot of all events we have received at the point of the call.
|
||||
// new events may still be added to the queue, but we'll defer everything after the cutoff until the next update.
|
||||
val events = LazyList.continually(BrainEvents.events.poll()).takeWhile({
|
||||
var inSnapshot = true
|
||||
var cutoffReached = false
|
||||
val events = ArrayBuffer.empty[brain.event.Event]
|
||||
|
||||
{ event =>
|
||||
val pass = inSnapshot
|
||||
inSnapshot = !(event eq cutoff)
|
||||
|
||||
pass
|
||||
}
|
||||
})
|
||||
while (!cutoffReached) {
|
||||
val event = BrainEvents.events.poll()
|
||||
cutoffReached = event eq cutoff
|
||||
events += event
|
||||
}
|
||||
|
||||
for (event <- events) {
|
||||
root.workspaceView.dispatchBrainEvent(event)
|
||||
|
||||
@ -9,7 +9,7 @@ import ocelot.desktop.ui.widget.LogWidget.{BorderThickness, EntryMargin, EntryPa
|
||||
import ocelot.desktop.util.{DrawUtils, Orientation}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.collection.mutable
|
||||
|
||||
abstract class LogWidget extends Widget {
|
||||
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
||||
@ -17,18 +17,17 @@ abstract class LogWidget extends Widget {
|
||||
private object MessageListWidget extends Widget { messageList =>
|
||||
override protected val layout: Layout = new Layout(this)
|
||||
|
||||
// NOTE: access to entries must be synchronized!
|
||||
private val entries = ArrayBuffer.empty[Entry]
|
||||
private val entries = mutable.ArrayDeque.empty[Entry]
|
||||
|
||||
val dummyEntry: Entry = new RxEntry("", nextMessageY)
|
||||
|
||||
override def minimumSize: Size2D = Size2D(dummyEntry.minimumSize.width + 2 * EntryMargin, nextMessageY)
|
||||
|
||||
private def nextMessageY: Float = entries.synchronized {
|
||||
private def nextMessageY: Float = {
|
||||
entries.lastOption.map(_.maxY).getOrElse(0f) + EntryMargin
|
||||
}
|
||||
|
||||
def addEntry(entry: LogEntry): Unit = entries.synchronized {
|
||||
def addEntry(entry: LogEntry): Unit = {
|
||||
entries += (entry match {
|
||||
case LogEntry.Rx(message) => new RxEntry(message, nextMessageY)
|
||||
case LogEntry.Tx(message) => new TxEntry(message, nextMessageY)
|
||||
@ -37,7 +36,7 @@ abstract class LogWidget extends Widget {
|
||||
parent.get.recalculateBoundsAndRelayout()
|
||||
}
|
||||
|
||||
def removeFirst(count: Int): Unit = entries.synchronized {
|
||||
def removeFirst(count: Int): Unit = {
|
||||
if (count >= entries.length) {
|
||||
entries.clear()
|
||||
} else {
|
||||
@ -68,7 +67,7 @@ abstract class LogWidget extends Widget {
|
||||
}
|
||||
}
|
||||
|
||||
override def draw(g: Graphics): Unit = entries.synchronized {
|
||||
override def draw(g: Graphics): Unit = {
|
||||
val firstVisibleIdx = firstVisibleIdxSearch(parent.get.asInstanceOf[ScrollView].offset.y)
|
||||
|
||||
for (entry <- entries.iterator.drop(firstVisibleIdx).takeWhile(_.absoluteBounds.y <= clippedBounds.max.y)) {
|
||||
|
||||
@ -22,8 +22,6 @@ trait OcelotInterfaceLogStorage extends EventAware with Persistable with Windowe
|
||||
|
||||
private var _messageLimit: Int = 1000
|
||||
|
||||
// NOTE: access must be synchronized!
|
||||
// ocelot.log() is a direct method, so it may push events even if the tick lock is not acquired
|
||||
private val _entries = mutable.ArrayDeque.empty[LogEntry]
|
||||
|
||||
eventHandlers += {
|
||||
@ -98,7 +96,7 @@ trait OcelotInterfaceLogStorage extends EventAware with Persistable with Windowe
|
||||
addEntries(entries.toSeq)
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound): Unit = _entries.synchronized {
|
||||
override def save(nbt: NBTTagCompound): Unit = {
|
||||
super.save(nbt)
|
||||
|
||||
nbt.setTagList(EntriesTag, _entries.map(saveEntry(_).asInstanceOf[NBTBase]).asJava)
|
||||
@ -107,36 +105,36 @@ trait OcelotInterfaceLogStorage extends EventAware with Persistable with Windowe
|
||||
|
||||
def messageLimit: Int = _messageLimit
|
||||
|
||||
def messageLimit_=(limit: Int): Unit = _entries.synchronized {
|
||||
def messageLimit_=(limit: Int): Unit = {
|
||||
require(limit > 0)
|
||||
ensureFreeSpace(_entries.length - limit)
|
||||
_messageLimit = limit
|
||||
}
|
||||
|
||||
def entryCount: Int = _entries.synchronized {
|
||||
def entryCount: Int = {
|
||||
_entries.length
|
||||
}
|
||||
|
||||
def clear(): Unit = _entries.synchronized {
|
||||
def clear(): Unit = {
|
||||
val count = _entries.length
|
||||
_entries.clear()
|
||||
window.onMessagesRemoved(count)
|
||||
}
|
||||
|
||||
private def addEntry(entry: LogEntry): Unit = _entries.synchronized {
|
||||
private def addEntry(entry: LogEntry): Unit = {
|
||||
ensureFreeSpace(1)
|
||||
_entries += entry
|
||||
onMessagesAdded(Some(entry))
|
||||
}
|
||||
|
||||
private def addEntries(entries: Seq[LogEntry]): Unit = _entries.synchronized {
|
||||
private def addEntries(entries: Seq[LogEntry]): Unit = {
|
||||
ensureFreeSpace(entries.length)
|
||||
val prevCount = _entries.length
|
||||
_entries ++= entries.view.takeRight(messageLimit)
|
||||
onMessagesAdded(_entries.view.takeRight(_entries.length - prevCount))
|
||||
}
|
||||
|
||||
private def ensureFreeSpace(n: Int): Unit = _entries.synchronized {
|
||||
private def ensureFreeSpace(n: Int): Unit = {
|
||||
val prevCount = _entries.length
|
||||
_entries.takeRightInPlace(messageLimit - n)
|
||||
val removedCount = prevCount - _entries.length
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user