mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2026-01-06 11:12:39 +01:00
Refactor event bus
This commit is contained in:
parent
5f257fc602
commit
f07c1201ed
@ -1 +1 @@
|
||||
Subproject commit a0eea2abcae926908a232fee827ebbd28782a326
|
||||
Subproject commit e7b477cf4d369d91132275237e72c80ad5440e40
|
||||
@ -2,8 +2,6 @@ package ocelot.desktop
|
||||
|
||||
import buildinfo.BuildInfo
|
||||
import li.flor.nativejfilechooser.NativeJFileChooser
|
||||
import ocelot.desktop.audio._
|
||||
import ocelot.desktop.node.nodes.{IronNoteBlockNode, NoteBlockNode}
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.swing.SplashScreen
|
||||
import ocelot.desktop.ui.widget._
|
||||
@ -15,8 +13,6 @@ import ocelot.desktop.util._
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import totoro.ocelot.brain.Ocelot
|
||||
import totoro.ocelot.brain.event.FileSystemActivityType.Floppy
|
||||
import totoro.ocelot.brain.event._
|
||||
import totoro.ocelot.brain.nbt.ExtendedNBT.{extendNBTTagCompound, extendNBTTagList}
|
||||
import totoro.ocelot.brain.nbt.{CompressedStreamTools, NBT, NBTTagCompound, NBTTagString}
|
||||
import totoro.ocelot.brain.user.User
|
||||
@ -30,7 +26,7 @@ import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.io.Source
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.util.{Failure, Random, Success, Try}
|
||||
import scala.util.{Failure, Success, Try}
|
||||
|
||||
object OcelotDesktop extends Logging {
|
||||
private val splashScreen = new SplashScreen()
|
||||
@ -49,8 +45,6 @@ object OcelotDesktop extends Logging {
|
||||
|
||||
private val tickLock: Lock = new ReentrantLock()
|
||||
|
||||
private val random: Random = new Random()
|
||||
|
||||
def withTickLockAcquired(f: => Unit): Unit = withLockAcquired(tickLock, f)
|
||||
|
||||
private def mainInner(args: mutable.HashMap[Argument, Option[String]]): Unit = {
|
||||
@ -80,8 +74,6 @@ object OcelotDesktop extends Logging {
|
||||
// loading resources _after_ the UiHandler was initialized, because the native libraries are not available before
|
||||
ResourceManager.initResources()
|
||||
|
||||
setupEventHandlers()
|
||||
|
||||
splashScreen.setStatus("Loading workspace...", 0.90f)
|
||||
val cmdLineWorkspaceArgument = args.get(CommandLine.WorkspacePath).flatten
|
||||
if (loadRecentWorkspace || cmdLineWorkspaceArgument.isDefined) {
|
||||
@ -368,38 +360,4 @@ object OcelotDesktop extends Logging {
|
||||
private def createWorkspace(): Unit = {
|
||||
workspace = new Workspace(tmpPath)
|
||||
}
|
||||
|
||||
private def setupEventHandlers(): Unit = {
|
||||
EventBus.subscribe[MachineCrashEvent] { event =>
|
||||
logger.info(s"[EVENT] Machine crash! (address = ${event.address}, ${event.message})")
|
||||
}
|
||||
|
||||
if (!Audio.isDisabled) {
|
||||
EventBus.subscribe[BeepEvent] { event =>
|
||||
BeepGenerator.newBeep(".", event.frequency, event.duration).play()
|
||||
}
|
||||
|
||||
EventBus.subscribe[BeepPatternEvent] { event =>
|
||||
BeepGenerator.newBeep(event.pattern, 1000, 200).play()
|
||||
}
|
||||
|
||||
EventBus.subscribe[NoteBlockTriggerEvent] { event =>
|
||||
SoundSource.fromBuffer(SoundBuffers.NoteBlock(event.instrument), SoundCategory.Beep,
|
||||
pitch = NoteBlockNode.Pitches(event.pitch), volume = event.volume.toFloat.min(1f).max(0f)).play()
|
||||
val node = UiHandler.root.workspaceView.nodes.find(_.entity.node.address == event.address).get
|
||||
node match {
|
||||
case nb: NoteBlockNode => nb.addParticle(event.pitch)
|
||||
case nb: IronNoteBlockNode => nb.addParticle(event.pitch)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
val soundFloppyAccess = SoundBuffers.MachineFloppyAccess.map(buffer => SoundSource.fromBuffer(buffer, SoundCategory.Environment))
|
||||
val soundHDDAccess = SoundBuffers.MachineHDDAccess.map(buffer => SoundSource.fromBuffer(buffer, SoundCategory.Environment))
|
||||
EventBus.subscribe[FileSystemActivityEvent] { event =>
|
||||
val sound = if (event.activityType == Floppy) soundFloppyAccess else soundHDDAccess
|
||||
sound(random.nextInt(sound.length)).play()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ abstract class Node(val entity: Entity with Environment) extends Widget with Dra
|
||||
|
||||
menu.addEntry(new ContextMenuEntry("Delete", () => {
|
||||
dispose()
|
||||
workspaceView.nodes -= this
|
||||
workspaceView.nodes = workspaceView.nodes.filter(_ != this)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -155,6 +155,8 @@ abstract class Node(val entity: Entity with Environment) extends Widget with Dra
|
||||
|
||||
def getNodeByPort(port: NodePort): network.Node = entity.node
|
||||
|
||||
def shouldReceiveEventsFor(address: String): Boolean = address == entity.node.address
|
||||
|
||||
def connections: Iterator[(NodePort, Node, NodePort)] = _connections.iterator
|
||||
|
||||
def connect(portA: NodePort, node: Node, portB: NodePort): Unit = {
|
||||
|
||||
@ -1,23 +1,26 @@
|
||||
package ocelot.desktop.node.nodes
|
||||
|
||||
import ocelot.desktop.audio.{SoundBuffers, SoundCategory, SoundSource}
|
||||
import ocelot.desktop.audio._
|
||||
import ocelot.desktop.color.Color
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
import ocelot.desktop.node.Node
|
||||
import ocelot.desktop.ui.event.sources.KeyEvents
|
||||
import ocelot.desktop.ui.event.{ClickEvent, MouseEvent}
|
||||
import ocelot.desktop.ui.event.{BrainEvent, ClickEvent, MouseEvent}
|
||||
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry, ContextMenuSubmenu}
|
||||
import ocelot.desktop.ui.widget.slot._
|
||||
import ocelot.desktop.util.TierColor
|
||||
import ocelot.desktop.util.{Logging, TierColor}
|
||||
import org.lwjgl.input.Keyboard
|
||||
import totoro.ocelot.brain.entity.traits.{Entity, Floppy, GenericCPU, Inventory}
|
||||
import totoro.ocelot.brain.entity.traits.{Entity, Environment, Floppy, GenericCPU, Inventory}
|
||||
import totoro.ocelot.brain.entity.{CPU, Case, EEPROM, GraphicsCard, HDDManaged, HDDUnmanaged, Memory}
|
||||
import totoro.ocelot.brain.event.FileSystemActivityType.Floppy
|
||||
import totoro.ocelot.brain.event.{BeepEvent, BeepPatternEvent, FileSystemActivityEvent, MachineCrashEvent}
|
||||
import totoro.ocelot.brain.loot.Loot
|
||||
import totoro.ocelot.brain.util.Tier
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.util.Random
|
||||
|
||||
class ComputerNode(val computer: Case) extends Node(computer) {
|
||||
class ComputerNode(val computer: Case) extends Node(computer) with Logging {
|
||||
var eepromSlot: EEPROMSlot = _
|
||||
var cpuSlot: CPUSlot = _
|
||||
var memorySlots: Array[MemorySlot] = _
|
||||
@ -30,6 +33,26 @@ class ComputerNode(val computer: Case) extends Node(computer) {
|
||||
setupSlots()
|
||||
refitSlots()
|
||||
|
||||
eventHandlers += {
|
||||
case BrainEvent(event: MachineCrashEvent) =>
|
||||
logger.info(s"[EVENT] Machine crash! (address = ${event.address}, ${event.message})")
|
||||
|
||||
case BrainEvent(event: BeepEvent) if !Audio.isDisabled =>
|
||||
BeepGenerator.newBeep(".", event.frequency, event.duration).play()
|
||||
|
||||
case BrainEvent(event: BeepPatternEvent) if !Audio.isDisabled =>
|
||||
BeepGenerator.newBeep(event.pattern, 1000, 200).play()
|
||||
|
||||
case BrainEvent(event: FileSystemActivityEvent) if !Audio.isDisabled =>
|
||||
val soundFloppyAccess = SoundBuffers.MachineFloppyAccess.map(buffer => SoundSource.fromBuffer(buffer, SoundCategory.Environment))
|
||||
val soundHDDAccess = SoundBuffers.MachineHDDAccess.map(buffer => SoundSource.fromBuffer(buffer, SoundCategory.Environment))
|
||||
val sound = if (event.activityType == Floppy) soundFloppyAccess else soundHDDAccess
|
||||
sound(Random.between(0, sound.length)).play()
|
||||
}
|
||||
|
||||
override def shouldReceiveEventsFor(address: String): Boolean = super.shouldReceiveEventsFor(address) ||
|
||||
computer.inventory.entities.exists { case env: Environment => env.node.address == address }
|
||||
|
||||
def setup(): ComputerNode = {
|
||||
cpuSlot.owner.put(new CPU(computer.tier.min(2)))
|
||||
memorySlots(0).owner.put(new Memory(computer.tier.min(2) * 2 + 1))
|
||||
@ -42,6 +65,7 @@ class ComputerNode(val computer: Case) extends Node(computer) {
|
||||
}
|
||||
|
||||
override val icon: String = "nodes/Computer"
|
||||
|
||||
override def iconColor: Color = TierColor.get(computer.tier)
|
||||
|
||||
override protected val canOpen = true
|
||||
|
||||
@ -1,15 +1,25 @@
|
||||
package ocelot.desktop.node.nodes
|
||||
|
||||
import ocelot.desktop.ColorScheme
|
||||
import ocelot.desktop.audio.{SoundBuffers, SoundCategory, SoundSource}
|
||||
import ocelot.desktop.geometry.{Size2D, Vector2D}
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
import ocelot.desktop.node.Node
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.event.BrainEvent
|
||||
import totoro.ocelot.brain.entity.traits.{Entity, Environment}
|
||||
import totoro.ocelot.brain.event.NoteBlockTriggerEvent
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
abstract class NoteBlockNodeBase(entity: Entity with Environment) extends Node(entity) {
|
||||
eventHandlers += {
|
||||
case BrainEvent(event: NoteBlockTriggerEvent) =>
|
||||
SoundSource.fromBuffer(SoundBuffers.NoteBlock(event.instrument), SoundCategory.Beep,
|
||||
pitch = NoteBlockNode.Pitches(event.pitch), volume = event.volume.toFloat.min(1f).max(0f)).play()
|
||||
addParticle(event.pitch)
|
||||
}
|
||||
|
||||
private val particles = mutable.ArrayBuffer[(Float, Int)]()
|
||||
|
||||
def addParticle(pitch: Int): Unit = {
|
||||
|
||||
@ -275,6 +275,7 @@ object UiHandler extends Logging {
|
||||
}
|
||||
|
||||
def terminate(): Unit = {
|
||||
root.workspaceView.dispose()
|
||||
KeyEvents.destroy()
|
||||
MouseEvents.destroy()
|
||||
Display.destroy()
|
||||
|
||||
3
src/main/scala/ocelot/desktop/ui/event/BrainEvent.scala
Normal file
3
src/main/scala/ocelot/desktop/ui/event/BrainEvent.scala
Normal file
@ -0,0 +1,3 @@
|
||||
package ocelot.desktop.ui.event
|
||||
|
||||
case class BrainEvent(event: totoro.ocelot.brain.event.Event) extends Event
|
||||
@ -15,16 +15,17 @@ import ocelot.desktop.{ColorScheme, OcelotDesktop, Settings}
|
||||
import org.lwjgl.input.Keyboard
|
||||
import totoro.ocelot.brain.entity.traits.{Entity, Environment, SidedEnvironment}
|
||||
import totoro.ocelot.brain.entity.{Case, Screen}
|
||||
import totoro.ocelot.brain.event.{EventBus, NodeEvent}
|
||||
import totoro.ocelot.brain.nbt.ExtendedNBT._
|
||||
import totoro.ocelot.brain.nbt.{NBT, NBTBase, NBTTagCompound}
|
||||
import totoro.ocelot.brain.util.{Direction, Tier}
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.collection.{immutable, mutable}
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
class WorkspaceView extends Widget with DragHandler with ClickHandler with HoverHandler {
|
||||
val nodes: ArrayBuffer[Node] = ArrayBuffer[Node]()
|
||||
@volatile
|
||||
var nodes: immutable.Seq[Node] = immutable.ArraySeq[Node]()
|
||||
var windowPool = new WindowPool
|
||||
var nodeSelector = new NodeSelector
|
||||
var profilerWindow = new ProfilerWindow
|
||||
@ -42,15 +43,26 @@ class WorkspaceView extends Widget with DragHandler with ClickHandler with Hover
|
||||
override def hierarchy: Array[Widget] = nodes.toArray
|
||||
}
|
||||
|
||||
private val eventSubscription = EventBus.subscribe { case event: NodeEvent =>
|
||||
nodes
|
||||
.filter(_.shouldReceiveEventsFor(event.address))
|
||||
.foreach(_.handleEvent(BrainEvent(event)))
|
||||
}
|
||||
|
||||
def reset(): Unit = {
|
||||
nodes.foreach(_.dispose())
|
||||
nodes.clear()
|
||||
nodes = nodes.empty
|
||||
windowPool.closeAll()
|
||||
nodeSelector = new NodeSelector
|
||||
profilerWindow = new ProfilerWindow
|
||||
cameraOffset = Vector2D(0, 0)
|
||||
}
|
||||
|
||||
def dispose(): Unit = {
|
||||
nodes.foreach(_.dispose())
|
||||
eventSubscription.cancel()
|
||||
}
|
||||
|
||||
def load(nbt: NBTTagCompound): Unit = {
|
||||
reset()
|
||||
cameraOffset = new Vector2D(nbt.getCompoundTag("cameraOffset"))
|
||||
@ -70,7 +82,7 @@ class WorkspaceView extends Widget with DragHandler with ClickHandler with Hover
|
||||
node.workspaceView = this
|
||||
node.root = _root
|
||||
node.load(nbt)
|
||||
nodes += node
|
||||
nodes = nodes.appended(node)
|
||||
})
|
||||
|
||||
nbt.getTagList("connections", NBT.TAG_COMPOUND).foreach((nbt: NBTTagCompound) => {
|
||||
@ -97,7 +109,7 @@ class WorkspaceView extends Widget with DragHandler with ClickHandler with Hover
|
||||
cameraOffset.save(cameraOffsetTag)
|
||||
nbt.setTag("cameraOffset", cameraOffsetTag)
|
||||
|
||||
nbt.setTagList("nodes", nodes.map(node => {
|
||||
nbt.setTagList("nodes", nodes.toList.map(node => {
|
||||
val nbt = new NBTTagCompound
|
||||
nbt.setString("class", node.getClass.getName)
|
||||
nbt.setString("entityClass", node.entity.getClass.getName)
|
||||
@ -146,7 +158,7 @@ class WorkspaceView extends Widget with DragHandler with ClickHandler with Hover
|
||||
node.workspaceView = this
|
||||
node.root = _root
|
||||
node.parent = Some(this)
|
||||
nodes += node
|
||||
nodes = nodes.appended(node)
|
||||
}
|
||||
|
||||
def buildNewConnection(): Unit = {
|
||||
@ -259,8 +271,7 @@ class WorkspaceView extends Widget with DragHandler with ClickHandler with Hover
|
||||
b: Array[(Vector2D, Vector2D)],
|
||||
checkCollision: Boolean,
|
||||
forceParallel: Boolean,
|
||||
clampMin: Boolean): Array[Array[Vector2D]] =
|
||||
{
|
||||
clampMin: Boolean): Array[Array[Vector2D]] = {
|
||||
val product = for (x <- a; y <- b) yield (x, y)
|
||||
var iter = product.map { case ((aSide, aCenter), (bSide, bCenter)) =>
|
||||
val (aLen, bLen) = connectorLen(aSide, aCenter, bSide, bCenter, clampMin)
|
||||
@ -289,8 +300,7 @@ class WorkspaceView extends Widget with DragHandler with ClickHandler with Hover
|
||||
|
||||
private def connectorLen(aSide: Vector2D, aCenter: Vector2D,
|
||||
bSide: Vector2D, bCenter: Vector2D,
|
||||
clampMin: Boolean): (Float, Float) =
|
||||
{
|
||||
clampMin: Boolean): (Float, Float) = {
|
||||
val aDir = aSide - aCenter
|
||||
val bDir = bSide - bCenter
|
||||
val xDist = (aSide - bSide).x.abs
|
||||
@ -395,8 +405,7 @@ class WorkspaceView extends Widget with DragHandler with ClickHandler with Hover
|
||||
|
||||
private def drawSelectorConnection(g: Graphics, aRect: Rect2D, bRect: Rect2D,
|
||||
thickness: Float = 4,
|
||||
color: Color = RGBAColor(150, 150, 150)): Unit =
|
||||
{
|
||||
color: Color = RGBAColor(150, 150, 150)): Unit = {
|
||||
if (aRect.collides(bRect)) return
|
||||
val (a, b) = if (aRect.x > bRect.x) (aRect, bRect) else (bRect, aRect)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user