cleaned up redstone logic a bit and enforcing a short delay after synchronized calls to avoid tick times for computers going through the roof due to spammy synchronized calls (e.g. redstone.setOutput every frame). this is more of a workaround, i'll have to see if i can find a cleaner solution for this.

This commit is contained in:
Florian Nücke 2014-03-18 19:00:57 +01:00
parent 3b5bb9487b
commit 4e7bc78836
9 changed files with 72 additions and 79 deletions

View File

@ -57,31 +57,38 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledEmitter with IBund
def bundledOutput(side: ForgeDirection, color: Int, value: Int): Unit = if (value != bundledOutput(side, color)) { def bundledOutput(side: ForgeDirection, color: Int, value: Int): Unit = if (value != bundledOutput(side, color)) {
_bundledOutput(toLocal(side).ordinal())(color) = value _bundledOutput(toLocal(side).ordinal())(color) = value
onRedstoneOutputChanged(side)
if (Loader.isModLoaded("MineFactoryReloaded")) {
val nx = x + side.offsetX
val ny = y + side.offsetY
val nz = z + side.offsetZ
Block.blocksList(world.getBlockId(nx, ny, nz)) match {
case block: IRedNetNetworkContainer => block.updateNetwork(world, nx, ny, nz)
case _ =>
}
}
onRedstoneOutputChanged()
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def updateRedstoneInput() { override protected def updateRedstoneInput(side: ForgeDirection) {
if (shouldUpdateInput) { super.updateRedstoneInput(side)
for (side <- ForgeDirection.VALID_DIRECTIONS) { val oldBundledInput = _bundledInput(side.ordinal())
val oldBundledInput = _bundledInput(side.ordinal()) val newBundledInput = computeBundledInput(side)
val newBundledInput = computeBundledInput(side) var changed = false
var changed = false if (newBundledInput != null) for (color <- 0 until 16) {
if (newBundledInput != null) for (color <- 0 until 16) { changed = changed || (oldBundledInput(color) >= 0 && oldBundledInput(color) != newBundledInput(color))
changed = changed || (oldBundledInput(color) >= 0 && oldBundledInput(color) != newBundledInput(color)) oldBundledInput(color) = newBundledInput(color)
oldBundledInput(color) = newBundledInput(color) }
} else for (color <- 0 until 16) {
else for (color <- 0 until 16) { changed = changed || oldBundledInput(color) > 0
changed = changed || oldBundledInput(color) > 0 oldBundledInput(color) = 0
oldBundledInput(color) = 0 }
} if (changed) {
if (changed) { onRedstoneInputChanged(side)
onRedstoneInputChanged(side)
}
}
} }
super.updateRedstoneInput()
} }
override def readFromNBT(nbt: NBTTagCompound) { override def readFromNBT(nbt: NBTTagCompound) {
@ -149,32 +156,19 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledEmitter with IBund
} }
} }
override protected def onRedstoneOutputChanged(side: ForgeDirection) { override protected def onRedstoneOutputEnabledChanged() {
if (side == ForgeDirection.UNKNOWN) { if (Loader.isModLoaded("MineFactoryReloaded")) {
if (Loader.isModLoaded("MineFactoryReloaded")) { for (side <- ForgeDirection.VALID_DIRECTIONS) {
for (side <- ForgeDirection.VALID_DIRECTIONS) { val nx = x + side.offsetX
val nx = x + side.offsetX val ny = y + side.offsetY
val ny = y + side.offsetY val nz = z + side.offsetZ
val nz = z + side.offsetZ
Block.blocksList(world.getBlockId(nx, ny, nz)) match {
case block: IRedNetNetworkContainer => block.updateNetwork(world, x, y, z)
case _ =>
}
}
}
}
else {
val nx = x + side.offsetX
val ny = y + side.offsetY
val nz = z + side.offsetZ
if (Loader.isModLoaded("MineFactoryReloaded")) {
Block.blocksList(world.getBlockId(nx, ny, nz)) match { Block.blocksList(world.getBlockId(nx, ny, nz)) match {
case block: IRedNetNetworkContainer => block.updateNetwork(world, x, y, z) case block: IRedNetNetworkContainer => block.updateNetwork(world, x, y, z)
case _ => case _ =>
} }
} }
} }
super.onRedstoneOutputChanged(side) super.onRedstoneOutputEnabledChanged()
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //

View File

@ -30,8 +30,6 @@ class Charger extends Environment with RedstoneAware with Analyzable {
override def updateEntity() { override def updateEntity() {
super.updateEntity() super.updateEntity()
if (isServer) { if (isServer) {
updateRedstoneInput()
val charge = Settings.get.chargeRate * chargeSpeed val charge = Settings.get.chargeRate * chargeSpeed
robots.collect { robots.collect {
case Some(proxy) => node.changeBuffer(proxy.robot.bot.node.changeBuffer(charge + node.changeBuffer(-charge))) case Some(proxy) => node.changeBuffer(proxy.robot.bot.node.changeBuffer(charge + node.changeBuffer(-charge)))

View File

@ -124,7 +124,6 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
ServerPacketSender.sendComputerState(this) ServerPacketSender.sendComputerState(this)
} }
updateRedstoneInput()
updateComponents() updateComponents()
} }
} }

View File

@ -217,7 +217,6 @@ class Rack extends PowerAcceptor with Hub with PowerBalancer with Inventory with
isOutputEnabled = hasRedstoneCard isOutputEnabled = hasRedstoneCard
isAbstractBusAvailable = hasAbstractBusCard isAbstractBusAvailable = hasAbstractBusCard
updateRedstoneInput()
servers collect { servers collect {
case Some(server) => server.inventory.updateComponents() case Some(server) => server.inventory.updateComponents()
} }

View File

@ -16,13 +16,6 @@ class Redstone extends Environment with BundledRedstoneAware {
_isOutputEnabled = true _isOutputEnabled = true
} }
override def updateEntity() {
super.updateEntity()
if (isServer) {
updateRedstoneInput()
}
}
override def readFromNBT(nbt: NBTTagCompound) { override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt) super.readFromNBT(nbt)
instance.load(nbt.getCompoundTag(Settings.namespace + "redstone")) instance.load(nbt.getCompoundTag(Settings.namespace + "redstone"))

View File

@ -33,7 +33,7 @@ trait RedstoneAware extends RotationAware with IConnectable with IRedstoneEmitte
_output(i) = 0 _output(i) = 0
} }
} }
onRedstoneOutputChanged(ForgeDirection.UNKNOWN) onRedstoneOutputEnabledChanged()
} }
this this
} }
@ -44,9 +44,16 @@ trait RedstoneAware extends RotationAware with IConnectable with IRedstoneEmitte
def output(side: ForgeDirection) = _output(toLocal(side).ordinal()) def output(side: ForgeDirection) = _output(toLocal(side).ordinal())
def output(side: ForgeDirection, value: Int): Unit = if (value != output(side)) { def output(side: ForgeDirection, value: Int): Unit = if (value != output(side)) this.synchronized {
_output(toLocal(side).ordinal()) = value _output(toLocal(side).ordinal()) = value
onRedstoneOutputChanged(side)
val nx = x + side.offsetX
val ny = y + side.offsetY
val nz = z + side.offsetZ
world.notifyBlockOfNeighborChange(nx, ny, nz, block.blockID)
world.notifyBlocksOfNeighborChange(nx, ny, nz, world.getBlockId(nx, ny, nz), side.getOpposite.ordinal)
onRedstoneOutputChanged()
} }
def checkRedstoneInputChanged() { def checkRedstoneInputChanged() {
@ -55,20 +62,27 @@ trait RedstoneAware extends RotationAware with IConnectable with IRedstoneEmitte
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def updateRedstoneInput() { override def updateEntity() {
if (shouldUpdateInput) { super.updateEntity()
shouldUpdateInput = false if (isServer) {
for (side <- ForgeDirection.VALID_DIRECTIONS) { if (shouldUpdateInput) {
val oldInput = _input(side.ordinal()) shouldUpdateInput = false
val newInput = computeInput(side) for (side <- ForgeDirection.VALID_DIRECTIONS) {
_input(side.ordinal()) = newInput updateRedstoneInput(side)
if (oldInput >= 0 && input(side) != oldInput) {
onRedstoneInputChanged(side)
} }
} }
} }
} }
protected def updateRedstoneInput(side: ForgeDirection) {
val oldInput = _input(side.ordinal())
val newInput = computeInput(side)
_input(side.ordinal()) = newInput
if (oldInput >= 0 && input(side) != oldInput) {
onRedstoneInputChanged(side)
}
}
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) = { override def readFromNBT(nbt: NBTTagCompound) = {
@ -124,17 +138,13 @@ trait RedstoneAware extends RotationAware with IConnectable with IRedstoneEmitte
protected def onRedstoneInputChanged(side: ForgeDirection) {} protected def onRedstoneInputChanged(side: ForgeDirection) {}
protected def onRedstoneOutputChanged(side: ForgeDirection) { protected def onRedstoneOutputEnabledChanged() = this.synchronized {
if (side == ForgeDirection.UNKNOWN) { world.notifyBlocksOfNeighborChange(x, y, z, block.blockID)
world.notifyBlocksOfNeighborChange(x, y, z, block.blockID) if (isServer) ServerPacketSender.sendRedstoneState(this)
} else world.markBlockForRenderUpdate(x, y, z)
else { }
val nx = x + side.offsetX
val ny = y + side.offsetY protected def onRedstoneOutputChanged() {
val nz = z + side.offsetZ
world.notifyBlockOfNeighborChange(nx, ny, nz, block.blockID)
world.notifyBlocksOfNeighborChange(nx, ny, nz, world.getBlockId(nx, ny, nz))
}
if (isServer) ServerPacketSender.sendRedstoneState(this) if (isServer) ServerPacketSender.sendRedstoneState(this)
else world.markBlockForRenderUpdate(x, y, z) else world.markBlockForRenderUpdate(x, y, z)
} }

View File

@ -154,8 +154,6 @@ class RobotProxy(val robot: Robot) extends Computer with ISidedInventory with Bu
override def checkRedstoneInputChanged() = robot.checkRedstoneInputChanged() override def checkRedstoneInputChanged() = robot.checkRedstoneInputChanged()
override def updateRedstoneInput() = robot.updateRedstoneInput()
@Optional.Method(modid = "RedLogic") @Optional.Method(modid = "RedLogic")
override def connects(wire: IWire, blockFace: Int, fromDirection: Int) = robot.connects(wire, blockFace, fromDirection) override def connects(wire: IWire, blockFace: Int, fromDirection: Int) = robot.connects(wire, blockFace, fromDirection)

View File

@ -201,9 +201,6 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
override def updateEntity() { override def updateEntity() {
super.updateEntity() super.updateEntity()
if (isServer) {
updateRedstoneInput()
}
if (isServer && isOn && isOrigin && world.getWorldTime % Settings.get.tickFrequency == 0) { if (isServer && isOn && isOrigin && world.getWorldTime % Settings.get.tickFrequency == 0) {
if (relativeLitArea < 0) { if (relativeLitArea < 0) {
// The relative lit area is the number of pixels that are not blank // The relative lit area is the number of pixels that are not blank

View File

@ -380,6 +380,11 @@ class Machine(val owner: Owner, val rom: Option[ManagedEnvironment], constructor
switchTo(Machine.State.Running) switchTo(Machine.State.Running)
try { try {
architecture.runSynchronized() architecture.runSynchronized()
// This sleep is used to avoid spammy synchronized calls to increase
// the tick time the computer eats unduly. This is a very... rough
// workaround for that problem, and may have to be addressed with
// more care at some point... aka when I have more time.
pause(0.1)
// Check if the callback called pause() or stop(). // Check if the callback called pause() or stop().
state.top match { state.top match {
case Machine.State.Running => case Machine.State.Running =>