From 407d25131f321108a2ce6581bb2b41327536609f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 9 Dec 2013 01:32:31 +0100 Subject: [PATCH] working on performance, removing implicit conversions to rich number types in frequently called places (i.e. anything somehow called per tick); optimized power distribution a bit; added a tick delay for continuous power consumption stuff (screens, computer); converted some methods to lazy vals and caching multi-screen bounds --- li/cil/oc/Settings.scala | 1 + li/cil/oc/client/PacketSender.scala | 2 +- li/cil/oc/client/gui/Robot.scala | 6 +- li/cil/oc/client/gui/Screen.scala | 6 +- .../renderer/MonospaceFontRenderer.scala | 3 +- .../client/renderer/gui/BufferRenderer.scala | 5 +- .../renderer/tileentity/ScreenRenderer.scala | 8 +- li/cil/oc/common/PacketBuilder.scala | 2 +- li/cil/oc/common/block/Computer.scala | 2 +- li/cil/oc/common/block/Keyboard.scala | 4 +- li/cil/oc/common/block/RobotAfterimage.scala | 3 +- li/cil/oc/common/block/RobotProxy.scala | 2 +- li/cil/oc/common/block/Screen.scala | 3 +- li/cil/oc/common/component/Buffer.scala | 2 +- li/cil/oc/common/container/Player.scala | 8 +- li/cil/oc/common/container/Robot.scala | 2 +- .../common/tileentity/BundledRedstone.scala | 12 +- li/cil/oc/common/tileentity/Charger.scala | 2 +- li/cil/oc/common/tileentity/Computer.scala | 2 +- li/cil/oc/common/tileentity/Environment.scala | 5 +- li/cil/oc/common/tileentity/Keyboard.scala | 2 +- .../oc/common/tileentity/PowerConverter.scala | 25 ++-- li/cil/oc/common/tileentity/Redstone.scala | 8 +- li/cil/oc/common/tileentity/Robot.scala | 4 +- li/cil/oc/common/tileentity/RobotProxy.scala | 4 +- li/cil/oc/common/tileentity/Screen.scala | 37 +++--- li/cil/oc/common/tileentity/TileEntity.scala | 4 +- li/cil/oc/server/component/Computer.scala | 58 +++++---- li/cil/oc/server/component/Crafting.scala | 6 +- li/cil/oc/server/component/Filesystem.scala | 2 +- li/cil/oc/server/component/Generator.scala | 6 +- li/cil/oc/server/component/GraphicsCard.scala | 8 +- .../server/component/PowerDistributor.scala | 55 ++++---- li/cil/oc/server/component/Robot.scala | 18 +-- .../component/WirelessNetworkCard.scala | 2 +- .../oc/server/component/robot/Inventory.scala | 8 +- li/cil/oc/server/component/robot/Player.scala | 8 +- li/cil/oc/server/fs/VirtualFileSystem.scala | 9 +- .../fs/ZipFileInputStreamFileSystem.scala | 2 +- li/cil/oc/server/network/Connector.scala | 117 ++++++++---------- li/cil/oc/util/LuaStateFactory.scala | 8 +- li/cil/oc/util/RTree.scala | 8 +- li/cil/oc/util/TextBuffer.scala | 20 +-- li/cil/oc/util/WirelessNetwork.scala | 7 +- 44 files changed, 266 insertions(+), 240 deletions(-) diff --git a/li/cil/oc/Settings.scala b/li/cil/oc/Settings.scala index 01dd4c3a6..fa797e1cf 100644 --- a/li/cil/oc/Settings.scala +++ b/li/cil/oc/Settings.scala @@ -87,6 +87,7 @@ class Settings(config: Config) { val ratioUniversalElectricity = config.getDouble("power.ratioUniversalElectricity").toFloat val chargeRate = config.getDouble("power.chargerChargeRate") val generatorEfficiency = config.getDouble("power.generatorEfficiency") + val tickFrequency = 20 // power.buffer val bufferCapacitor = config.getDouble("power.buffer.capacitor") max 0 diff --git a/li/cil/oc/client/PacketSender.scala b/li/cil/oc/client/PacketSender.scala index 01f814ea8..b7c850372 100644 --- a/li/cil/oc/client/PacketSender.scala +++ b/li/cil/oc/client/PacketSender.scala @@ -41,7 +41,7 @@ object PacketSender { val pb = new PacketBuilder(PacketType.Clipboard) pb.writeTileEntity(t) - pb.writeUTF(value.substring(0, value.length min 1024)) + pb.writeUTF(value.substring(0, math.min(value.length, 1024))) pb.sendToServer() } diff --git a/li/cil/oc/client/gui/Robot.scala b/li/cil/oc/client/gui/Robot.scala index a8079923c..0a3c978a4 100644 --- a/li/cil/oc/client/gui/Robot.scala +++ b/li/cil/oc/client/gui/Robot.scala @@ -116,9 +116,9 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten protected def changeSize(w: Double, h: Double) = { val bw = w * MonospaceFontRenderer.fontWidth val bh = h * MonospaceFontRenderer.fontHeight - val scaleX = (bufferWidth / (bw + bufferMargin * 2.0)) min 1 - val scaleY = (bufferHeight / (bh + bufferMargin * 2.0)) min 1 - scaleX min scaleY + val scaleX = math.min(bufferWidth / (bw + bufferMargin * 2.0), 1) + val scaleY = math.min(bufferHeight / (bh + bufferMargin * 2.0), 1) + math.min(scaleX, scaleY) } private def drawSelection() { diff --git a/li/cil/oc/client/gui/Screen.scala b/li/cil/oc/client/gui/Screen.scala index a17124e0b..42195ac29 100644 --- a/li/cil/oc/client/gui/Screen.scala +++ b/li/cil/oc/client/gui/Screen.scala @@ -61,9 +61,9 @@ class Screen(val screen: tileentity.Screen) extends Buffer { protected def changeSize(w: Double, h: Double) = { val bw = w * MonospaceFontRenderer.fontWidth val bh = h * MonospaceFontRenderer.fontHeight - val scaleX = (width / (bw + bufferMargin * 2.0)) min 1 - val scaleY = (height / (bh + bufferMargin * 2.0)) min 1 - val scale = scaleX min scaleY + val scaleX = math.min(width / (bw + bufferMargin * 2.0), 1) + val scaleY = math.min(height / (bh + bufferMargin * 2.0), 1) + val scale = math.min(scaleX, scaleY) val innerWidth = (bw * scale).toInt val innerHeight = (bh * scale).toInt x = (width - (innerWidth + bufferMargin * 2)) / 2 diff --git a/li/cil/oc/client/renderer/MonospaceFontRenderer.scala b/li/cil/oc/client/renderer/MonospaceFontRenderer.scala index c5c697d25..fe04ea64e 100644 --- a/li/cil/oc/client/renderer/MonospaceFontRenderer.scala +++ b/li/cil/oc/client/renderer/MonospaceFontRenderer.scala @@ -19,7 +19,8 @@ object MonospaceFontRenderer { def init(textureManager: TextureManager) = this.synchronized( instance = instance.orElse(Some(new Renderer(textureManager)))) - val (fontWidth, fontHeight) = (5, 9) + val fontWidth = 5 + val fontHeight = 9 def drawString(x: Int, y: Int, value: Array[Char], color: Array[Short], depth: PackedColor.Depth.Value) = instance match { case None => OpenComputers.log.warning("Trying to render string with uninitialized MonospaceFontRenderer.") diff --git a/li/cil/oc/client/renderer/gui/BufferRenderer.scala b/li/cil/oc/client/renderer/gui/BufferRenderer.scala index 42709dc15..a9ef582d2 100644 --- a/li/cil/oc/client/renderer/gui/BufferRenderer.scala +++ b/li/cil/oc/client/renderer/gui/BufferRenderer.scala @@ -96,7 +96,10 @@ object BufferRenderer { } private def drawBorder(x: Double, y: Double, w: Double, h: Double, u1: Int, v1: Int, u2: Int, v2: Int) = { - val (u1d, u2d, v1d, v2d) = (u1 / 16.0, u2 / 16.0, v1 / 16.0, v2 / 16.0) + val u1d = u1 / 16.0 + val u2d = u2 / 16.0 + val v1d = v1 / 16.0 + val v2d = v2 / 16.0 val t = Tessellator.instance t.startDrawingQuads() t.addVertexWithUV(x, y + h, 0, u1d, v2d) diff --git a/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala b/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala index 9f9d5a85a..394636a97 100644 --- a/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala +++ b/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala @@ -64,7 +64,7 @@ object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5) if (distance > fadeDistanceSq) { - RenderState.setBlendAlpha(0f max (1 - (distance - fadeDistanceSq) * fadeRatio).toFloat) + RenderState.setBlendAlpha(math.max(0, 1 - ((distance - fadeDistanceSq) * fadeRatio).toFloat)) } MonospaceFontRenderer.init(tileEntityRenderer.renderEngine) @@ -77,8 +77,10 @@ object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with private def compileOrDraw(list: Int) = if (screen.bufferIsDirty && !RenderState.compilingDisplayList) { screen.bufferIsDirty = false - val (sx, sy) = (screen.width, screen.height) - val (tw, th) = (sx * 16f, sy * 16f) + val sx = screen.width + val sy = screen.height + val tw = sx * 16f + val th = sy * 16f GL11.glNewList(list, GL11.GL_COMPILE_AND_EXECUTE) diff --git a/li/cil/oc/common/PacketBuilder.scala b/li/cil/oc/common/PacketBuilder.scala index 8c7618832..0d09e1a66 100644 --- a/li/cil/oc/common/PacketBuilder.scala +++ b/li/cil/oc/common/PacketBuilder.scala @@ -46,7 +46,7 @@ class PacketBuilder(packetType: PacketType.Value, private val stream: ByteArrayO val manager = server.getConfigurationManager for (player <- manager.playerEntityList.map(_.asInstanceOf[EntityPlayerMP]) if player.dimension == dimension) { val playerRenderDistance = Int.MaxValue // ObfuscationReflectionHelper.getPrivateValue(classOf[EntityPlayerMP], player, "renderDistance").asInstanceOf[Integer] - val playerSpecificRange = range min ((manager.getViewDistance min playerRenderDistance) * 16) + val playerSpecificRange = math.min(range, (manager.getViewDistance min playerRenderDistance) * 16) if (player.getDistanceSq(x, y, z) < playerSpecificRange * playerSpecificRange) { sendToPlayer(player.asInstanceOf[Player]) } diff --git a/li/cil/oc/common/block/Computer.scala b/li/cil/oc/common/block/Computer.scala index 17a2df45a..d7be6b1e0 100644 --- a/li/cil/oc/common/block/Computer.scala +++ b/li/cil/oc/common/block/Computer.scala @@ -18,7 +18,7 @@ abstract class Computer extends Delegate { override def isProvidingWeakPower(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = world.getBlockTileEntity(x, y, z) match { - case computer: tileentity.Computer => computer.output(side) max 0 min 15 + case computer: tileentity.Computer => math.min(math.max(computer.output(side), 0), 15) case _ => super.isProvidingWeakPower(world, x, y, z, side) } diff --git a/li/cil/oc/common/block/Keyboard.scala b/li/cil/oc/common/block/Keyboard.scala index 59fd6bf2b..ad9c4c4a9 100644 --- a/li/cil/oc/common/block/Keyboard.scala +++ b/li/cil/oc/common/block/Keyboard.scala @@ -79,8 +79,8 @@ class Keyboard(val parent: SpecialDelegator) extends SpecialDelegate { val z0 = -up.offsetZ * sizes(1) - side.offsetZ * sizes(2) - forward.offsetZ * sizes(0) val z1 = up.offsetZ * sizes(1) + side.offsetZ * sizes(2) - forward.offsetZ * 0.5f AxisAlignedBB.getBoundingBox( - (x0 min x1) + 0.5f, (y0 min y1) + 0.5f, (z0 min z1) + 0.5f, - (x0 max x1) + 0.5f, (y0 max y1) + 0.5f, (z0 max z1) + 0.5f) + math.min(x0, x1) + 0.5f, math.min(y0, y1) + 0.5f, math.min(z0, z1) + 0.5f, + math.max(x0, x1) + 0.5f, math.max(y0, y1) + 0.5f, math.max(z0, z1) + 0.5f) } override def neighborBlockChanged(world: World, x: Int, y: Int, z: Int, blockId: Int) = diff --git a/li/cil/oc/common/block/RobotAfterimage.scala b/li/cil/oc/common/block/RobotAfterimage.scala index 5824db7fb..655434bf0 100644 --- a/li/cil/oc/common/block/RobotAfterimage.scala +++ b/li/cil/oc/common/block/RobotAfterimage.scala @@ -97,8 +97,7 @@ class RobotAfterimage(val parent: SpecialDelegator) extends SpecialDelegate { def findMovingRobot(world: IBlockAccess, x: Int, y: Int, z: Int): Option[tileentity.Robot] = { for (side <- ForgeDirection.VALID_DIRECTIONS) { - val (rx, ry, rz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ) - world.getBlockTileEntity(rx, ry, rz) match { + world.getBlockTileEntity(x + side.offsetX, y + side.offsetY, z + side.offsetZ) match { case proxy: tileentity.RobotProxy if proxy.robot.moveFromX == x && proxy.robot.moveFromY == y && proxy.robot.moveFromZ == z => return Some(proxy.robot) case _ => } diff --git a/li/cil/oc/common/block/RobotProxy.scala b/li/cil/oc/common/block/RobotProxy.scala index eb8b8b2e7..fd2bedd1f 100644 --- a/li/cil/oc/common/block/RobotProxy.scala +++ b/li/cil/oc/common/block/RobotProxy.scala @@ -32,7 +32,7 @@ class RobotProxy(val parent: SpecialDelegator) extends Computer with SpecialDele if (stack.hasTagCompound) { if (stack.getTagCompound.hasKey(Settings.namespace + "xp")) { val xp = stack.getTagCompound.getDouble(Settings.namespace + "xp") - val level = (Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt min 30 + val level = math.min((Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt, 30) if (level > 0) { tooltip.addAll(Tooltip.get(unlocalizedName + "_Level", level)) } diff --git a/li/cil/oc/common/block/Screen.scala b/li/cil/oc/common/block/Screen.scala index 3cc49bf50..a118fd8de 100644 --- a/li/cil/oc/common/block/Screen.scala +++ b/li/cil/oc/common/block/Screen.scala @@ -77,7 +77,8 @@ abstract class Screen(val parent: SimpleDelegator) extends SimpleDelegate { override def icon(world: IBlockAccess, x: Int, y: Int, z: Int, worldSide: ForgeDirection, localSide: ForgeDirection) = world.getBlockTileEntity(x, y, z) match { case screen: tileentity.Screen if screen.width > 1 || screen.height > 1 => - val (right, bottom) = (screen.width - 1, screen.height - 1) + val right = screen.width - 1 + val bottom = screen.height - 1 val (px, py) = screen.localPosition val (lx, ly) = screen.pitch match { case ForgeDirection.NORTH => (px, py) diff --git a/li/cil/oc/common/component/Buffer.scala b/li/cil/oc/common/component/Buffer.scala index 6849d685b..b06a75ca0 100644 --- a/li/cil/oc/common/component/Buffer.scala +++ b/li/cil/oc/common/component/Buffer.scala @@ -90,7 +90,7 @@ class Buffer(val owner: tileentity.Buffer) extends api.network.Environment with // avoid sending too much data to our clients. val (x, truncated) = if (col < 0) (0, s.substring(-col)) - else (col, s.substring(0, s.length min (buffer.width - col))) + else (col, s.substring(0, math.min(s.length, buffer.width - col))) if (buffer.set(x, row, truncated)) owner.onScreenSet(x, row, truncated) } diff --git a/li/cil/oc/common/container/Player.scala b/li/cil/oc/common/container/Player.scala index a643f50e7..40803bfde 100644 --- a/li/cil/oc/common/container/Player.scala +++ b/li/cil/oc/common/container/Player.scala @@ -69,10 +69,10 @@ abstract class Player(protected val playerInventory: InventoryPlayer, val otherI if (intoSlot.getHasStack) { val intoStack = intoSlot.getStack val itemsAreEqual = fromStack.isItemEqual(intoStack) && ItemStack.areItemStackTagsEqual(fromStack, intoStack) - val maxStackSize = fromStack.getMaxStackSize min intoSlot.getSlotStackLimit + val maxStackSize = math.min(fromStack.getMaxStackSize, intoSlot.getSlotStackLimit) val slotHasCapacity = intoStack.stackSize < maxStackSize if (itemsAreEqual && slotHasCapacity) { - val itemsMoved = (maxStackSize - intoStack.stackSize) min fromStack.stackSize + val itemsMoved = math.min(maxStackSize - intoStack.stackSize, fromStack.stackSize) if (itemsMoved > 0) { intoStack.stackSize += from.decrStackSize(itemsMoved).stackSize intoSlot.onSlotChanged() @@ -85,8 +85,8 @@ abstract class Player(protected val playerInventory: InventoryPlayer, val otherI for (i <- begin until end by step if from.getHasStack && from.getStack.stackSize > 0) { val intoSlot = inventorySlots.get(i).asInstanceOf[Slot] if (!intoSlot.getHasStack && intoSlot.isItemValid(fromStack)) { - val maxStackSize = fromStack.getMaxStackSize min intoSlot.getSlotStackLimit - val itemsMoved = maxStackSize min fromStack.stackSize + val maxStackSize = math.min(fromStack.getMaxStackSize, intoSlot.getSlotStackLimit) + val itemsMoved = math.min(maxStackSize, fromStack.stackSize) intoSlot.putStack(from.decrStackSize(itemsMoved)) somethingChanged = true } diff --git a/li/cil/oc/common/container/Robot.scala b/li/cil/oc/common/container/Robot.scala index c215b877f..07cdf4bdd 100644 --- a/li/cil/oc/common/container/Robot.scala +++ b/li/cil/oc/common/container/Robot.scala @@ -25,7 +25,7 @@ class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends P override def detectAndSendChanges() { super.detectAndSendChanges() - if ((robot.globalBuffer - lastSentBuffer).abs > 1) { + if (math.abs(robot.globalBuffer - lastSentBuffer) > 1) { lastSentBuffer = robot.globalBuffer ServerPacketSender.sendPowerState(robot) } diff --git a/li/cil/oc/common/tileentity/BundledRedstone.scala b/li/cil/oc/common/tileentity/BundledRedstone.scala index 779b60cf9..44d3968d1 100644 --- a/li/cil/oc/common/tileentity/BundledRedstone.scala +++ b/li/cil/oc/common/tileentity/BundledRedstone.scala @@ -39,7 +39,7 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab } def bundledInput(side: ForgeDirection, color: Int) = - _bundledInput(side.ordinal())(color) max _rednetInput(side.ordinal())(color) + math.max(_bundledInput(side.ordinal())(color), _rednetInput(side.ordinal())(color)) def rednetInput(side: ForgeDirection, color: Int, value: Int) = if (_rednetInput(side.ordinal())(color) != value) { @@ -134,7 +134,9 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab if (side == ForgeDirection.UNKNOWN) { if (Loader.isModLoaded("MineFactoryReloaded")) { for (side <- ForgeDirection.VALID_DIRECTIONS) { - val (nx, ny, nz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ) + 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, x, y, z) case _ => @@ -143,7 +145,9 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab } } else { - val (nx, ny, nz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ) + 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 { case block: IRedNetNetworkContainer => block.updateNetwork(world, x, y, z) @@ -157,7 +161,7 @@ trait BundledRedstone extends Redstone with IBundledEmitter with IBundledUpdatab // ----------------------------------------------------------------------- // @Optional.Method(modid = "RedLogic") - def getBundledCableStrength(blockFace: Int, toDirection: Int): Array[Byte] = _bundledOutput(toLocal(ForgeDirection.getOrientation(toDirection)).ordinal()).map(value => (value max 0 min 255).toByte) + def getBundledCableStrength(blockFace: Int, toDirection: Int): Array[Byte] = _bundledOutput(toLocal(ForgeDirection.getOrientation(toDirection)).ordinal()).map(value => math.min(math.max(value, 0), 255).toByte) @Optional.Method(modid = "RedLogic") def onBundledInputChanged() = checkRedstoneInputChanged() diff --git a/li/cil/oc/common/tileentity/Charger.scala b/li/cil/oc/common/tileentity/Charger.scala index 522f2a694..a6e0f3a62 100644 --- a/li/cil/oc/common/tileentity/Charger.scala +++ b/li/cil/oc/common/tileentity/Charger.scala @@ -76,7 +76,7 @@ class Charger extends Environment with Redstone with Analyzable { override protected def onRedstoneInputChanged(side: ForgeDirection) { super.onRedstoneInputChanged(side) - chargeSpeed = 0.0 max (ForgeDirection.VALID_DIRECTIONS.map(input).max min 15) / 15.0 + chargeSpeed = math.max(0, math.min(ForgeDirection.VALID_DIRECTIONS.map(input).max, 15) / 15.0) if (isServer) { ServerPacketSender.sendChargerState(this) } diff --git a/li/cil/oc/common/tileentity/Computer.scala b/li/cil/oc/common/tileentity/Computer.scala index d2091ad5c..a2ed13360 100644 --- a/li/cil/oc/common/tileentity/Computer.scala +++ b/li/cil/oc/common/tileentity/Computer.scala @@ -18,7 +18,7 @@ abstract class Computer(isRemote: Boolean) extends Environment with ComponentInv def node = if (isClient) null else computer.node - override def isClient = computer == null + override lazy val isClient = computer == null private var _isRunning = false diff --git a/li/cil/oc/common/tileentity/Environment.scala b/li/cil/oc/common/tileentity/Environment.scala index a34c6b5ad..fa1269785 100644 --- a/li/cil/oc/common/tileentity/Environment.scala +++ b/li/cil/oc/common/tileentity/Environment.scala @@ -20,11 +20,14 @@ abstract class Environment extends net.minecraft.tileentity.TileEntity with Tile def block = getBlockType + private var addedToNetwork = false + // ----------------------------------------------------------------------- // override def updateEntity() { super.updateEntity() - if (node != null && node.network == null) { + if (!addedToNetwork) { + addedToNetwork = true Network.joinOrCreateNetwork(this) } } diff --git a/li/cil/oc/common/tileentity/Keyboard.scala b/li/cil/oc/common/tileentity/Keyboard.scala index 36e0c81c5..e9f974bdb 100644 --- a/li/cil/oc/common/tileentity/Keyboard.scala +++ b/li/cil/oc/common/tileentity/Keyboard.scala @@ -15,7 +15,7 @@ class Keyboard(isRemote: Boolean) extends Environment with SidedEnvironment with def node = if (isClient) null else keyboard.node - override def isClient = keyboard == null + override lazy val isClient = keyboard == null def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = node diff --git a/li/cil/oc/common/tileentity/PowerConverter.scala b/li/cil/oc/common/tileentity/PowerConverter.scala index f2e057dfc..692f3f077 100644 --- a/li/cil/oc/common/tileentity/PowerConverter.scala +++ b/li/cil/oc/common/tileentity/PowerConverter.scala @@ -21,6 +21,10 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I withConnector(). create() + private lazy val isIndustrialCraftAvailable = Loader.isModLoaded("IC2") + + private lazy val isBuildCraftAvailable = Loader.isModLoaded("BuildCraft|Energy") + private def demand = if (Settings.get.ignorePower) 0.0 else node.globalBufferSize - node.globalBuffer def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = null @@ -30,13 +34,16 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I override def updateEntity() { super.updateEntity() if (isServer) { - if (Loader.isModLoaded("IC2")) { + if (isIndustrialCraftAvailable) { loadIC2() } - if (demand > 0 && Loader.isModLoaded("BuildCraft|Energy")) { + if (isBuildCraftAvailable && demand > 1 && world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) { val wantInMJ = demand.toFloat / Settings.get.ratioBuildCraft - val gotInMJ = getPowerProvider.useEnergy(1, wantInMJ, true) - node.changeBuffer(gotInMJ * Settings.get.ratioBuildCraft) + val powerProvider = getPowerProvider + if (wantInMJ < powerProvider.getEnergyStored) { + val gotInMJ = powerProvider.useEnergy(1, wantInMJ, true) + node.changeBuffer(gotInMJ * Settings.get.ratioBuildCraft) + } } } } @@ -74,7 +81,7 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I // ----------------------------------------------------------------------- // // IndustrialCraft - private var isIC2Loaded = false + private var addedToPowerGrid = false private var lastPacketSize = 0.0 @@ -82,17 +89,17 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I @Optional.Method(modid = "IC2") def loadIC2() { - if (!isIC2Loaded) { + if (!addedToPowerGrid) { MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this)) - isIC2Loaded = true + addedToPowerGrid = true } } @Optional.Method(modid = "IC2") def unloadIC2() { - if (isIC2Loaded) { + if (addedToPowerGrid) { MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this)) - isIC2Loaded = false + addedToPowerGrid = false } } diff --git a/li/cil/oc/common/tileentity/Redstone.scala b/li/cil/oc/common/tileentity/Redstone.scala index ef7105fcb..cd2c32d6f 100644 --- a/li/cil/oc/common/tileentity/Redstone.scala +++ b/li/cil/oc/common/tileentity/Redstone.scala @@ -114,14 +114,14 @@ trait Redstone extends RotationAware with network.Environment with Persistable w case emitter: IRedstoneEmitter => var strength = 0 for (i <- -1 to 5) { - strength = strength max emitter.getEmittedSignalStrength(i, side.getOpposite.ordinal()) + strength = math.max(strength, emitter.getEmittedSignalStrength(i, side.getOpposite.ordinal())) } strength case _ => 0 } } else 0 - vanilla max redLogic + math.max(vanilla, redLogic) } protected def onRedstoneInputChanged(side: ForgeDirection) {} @@ -131,7 +131,9 @@ trait Redstone extends RotationAware with network.Environment with Persistable w world.notifyBlocksOfNeighborChange(x, y, z, block.blockID) } else { - val (nx, ny, nz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ) + 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)) } diff --git a/li/cil/oc/common/tileentity/Robot.scala b/li/cil/oc/common/tileentity/Robot.scala index 705321cb5..5144eb95a 100644 --- a/li/cil/oc/common/tileentity/Robot.scala +++ b/li/cil/oc/common/tileentity/Robot.scala @@ -97,7 +97,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w def updateXpInfo() { // xp(level) = base + (level * const) ^ exp // pow(xp(level) - base, 1/exp) / const = level - level = (Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt min 30 + level = math.min((Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt, 30) if (battery != null) { battery.setLocalBufferSize(Settings.get.bufferRobot + Settings.get.bufferPerLevel * level) } @@ -140,7 +140,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w Blocks.robotAfterimage.setBlock(world, ox, oy, oz, 1) assert(Delegator.subBlock(world, ox, oy, oz).exists(_ == Blocks.robotAfterimage)) // Here instead of Lua callback so that it gets called on client, too. - val moveTicks = (Settings.get.moveDelay * 20).toInt max 1 + val moveTicks = math.max((Settings.get.moveDelay * 20).toInt, 1) setAnimateMove(ox, oy, oz, moveTicks) if (isServer) { world.scheduleBlockUpdate(ox, oy, oz, Blocks.robotAfterimage.parent.blockID, moveTicks - 1) diff --git a/li/cil/oc/common/tileentity/RobotProxy.scala b/li/cil/oc/common/tileentity/RobotProxy.scala index 79a47e6a3..2e2efb2d6 100644 --- a/li/cil/oc/common/tileentity/RobotProxy.scala +++ b/li/cil/oc/common/tileentity/RobotProxy.scala @@ -100,9 +100,9 @@ class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedI override def onInventoryChanged() = robot.onInventoryChanged() - override def isClient = robot.isClient + override lazy val isClient = robot.isClient - override def isServer = robot.isServer + override lazy val isServer = robot.isServer // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/common/tileentity/Screen.scala b/li/cil/oc/common/tileentity/Screen.scala index 3b60750ea..3975d06f2 100644 --- a/li/cil/oc/common/tileentity/Screen.scala +++ b/li/cil/oc/common/tileentity/Screen.scala @@ -38,6 +38,8 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable var hasPower = true + var cachedBounds: Option[AxisAlignedBB] = None + def canConnect(side: ForgeDirection) = toLocal(side) != ForgeDirection.SOUTH def sidedNode(side: ForgeDirection) = if (canConnect(side)) node else null @@ -49,8 +51,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable def localPosition = { val (lx, ly, _) = project(this) val (ox, oy, _) = project(origin) - val (px, py) = (lx - ox, ly - oy) - (px, py) + (lx - ox, ly - oy) } override def hasKeyboard = screens.exists(screen => ForgeDirection.VALID_DIRECTIONS. @@ -66,6 +67,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable origin = this screens.clear() screens += this + cachedBounds = None } def click(player: EntityPlayer, hitX: Float, hitY: Float, hitZ: Float): Boolean = { @@ -119,12 +121,15 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable override def updateEntity() { super.updateEntity() - if (isServer) { + if (isServer && world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) { if (litPixels < 0) { - litPixels = buffer.lines.foldLeft(0)((acc, line) => acc + line.count(_ != ' ')) + litPixels = 0 + for (line <- buffer.lines) for (c <- line) { + if (c != ' ') litPixels += 1 + } } val hadPower = hasPower - val neededPower = Settings.get.screenCost + pixelCost * litPixels + val neededPower = (Settings.get.screenCost + pixelCost * litPixels) * Settings.get.tickFrequency hasPower = buffer.node.tryChangeBuffer(-neededPower) if (hasPower != hadPower) { ServerPacketSender.sendScreenPowerChange(this, hasPower) @@ -213,15 +218,18 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable @SideOnly(Side.CLIENT) override def getRenderBoundingBox = if ((width == 1 && height == 1) || !isOrigin) super.getRenderBoundingBox - else { - val (sx, sy, sz) = unproject(width, height, 1) - val ox = x + (if (sx < 0) 1 else 0) - val oy = y + (if (sy < 0) 1 else 0) - val oz = z + (if (sz < 0) 1 else 0) - val b = AxisAlignedBB.getAABBPool.getAABB(ox, oy, oz, ox + sx, oy + sy, oz + sz) - b.setBounds(b.minX min b.maxX, b.minY min b.maxY, b.minZ min b.maxZ, - b.minX max b.maxX, b.minY max b.maxY, b.minZ max b.maxZ) - b + else cachedBounds match { + case Some(bounds) => bounds + case _ => + val (sx, sy, sz) = unproject(width, height, 1) + val ox = x + (if (sx < 0) 1 else 0) + val oy = y + (if (sy < 0) 1 else 0) + val oz = z + (if (sz < 0) 1 else 0) + val b = AxisAlignedBB.getBoundingBox(ox, oy, oz, ox + sx, oy + sy, oz + sz) + b.setBounds(math.min(b.minX, b.maxX), math.min(b.minY, b.maxY), math.min(b.minZ, b.maxZ), + math.max(b.minX, b.maxX), math.max(b.minY, b.maxY), math.max(b.minZ, b.maxZ)) + cachedBounds = Some(b) + b } @SideOnly(Side.CLIENT) @@ -297,6 +305,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable screen.height = newHeight screen.origin = newOrigin screen.screens ++= newScreens // It's a set, so there won't be duplicates. + screen.cachedBounds = None } true } diff --git a/li/cil/oc/common/tileentity/TileEntity.scala b/li/cil/oc/common/tileentity/TileEntity.scala index 571a732d8..d894267d1 100644 --- a/li/cil/oc/common/tileentity/TileEntity.scala +++ b/li/cil/oc/common/tileentity/TileEntity.scala @@ -16,9 +16,9 @@ trait TileEntity { def block: Block - def isClient = world.isRemote + lazy val isClient = world.isRemote - def isServer = !isClient + lazy val isServer = !isClient @SideOnly(Side.CLIENT) def readFromNBTForClient(nbt: NBTTagCompound) {} diff --git a/li/cil/oc/server/component/Computer.scala b/li/cil/oc/server/component/Computer.scala index 7529f3bc2..4014f0b76 100644 --- a/li/cil/oc/server/component/Computer.scala +++ b/li/cil/oc/server/component/Computer.scala @@ -120,7 +120,7 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con }) def pause(seconds: Double): Boolean = { - val ticksToPause = (seconds * 20).toInt max 0 + val ticksToPause = math.max((seconds * 20).toInt, 0) def shouldPause(state: Computer.State.Value) = state match { case Computer.State.Stopping | Computer.State.Stopped => false case Computer.State.Paused if ticksToPause <= remainingPause => false @@ -215,27 +215,29 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con worldTime = owner.world.getWorldTime // We can have rollbacks from '/time set'. Avoid getting negative uptimes. - timeStarted = timeStarted min worldTime + timeStarted = math.min(timeStarted, worldTime) // Reset direct call limits. - callCounts.synchronized(callCounts.clear()) + callCounts.synchronized(if (callCounts.size > 0) callCounts.clear()) // Make sure we have enough power. - val cost = if (isRobot) Settings.get.robotCost else Settings.get.computerCost - state.synchronized(state.top match { - case Computer.State.Paused | - Computer.State.Restarting | - Computer.State.Stopping | - Computer.State.Stopped => // No power consumption. - case Computer.State.Sleeping if lastUpdate < sleepUntil && signals.isEmpty => - if (!node.tryChangeBuffer(-cost * Settings.get.sleepCostFactor)) { - crash("not enough energy") - } - case _ => - if (!node.tryChangeBuffer(-cost)) { - crash("not enough energy") - } - }) + if (owner.world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) { + val cost = (if (isRobot) Settings.get.robotCost else Settings.get.computerCost) * Settings.get.tickFrequency + state.synchronized(state.top match { + case Computer.State.Paused | + Computer.State.Restarting | + Computer.State.Stopping | + Computer.State.Stopped => // No power consumption. + case Computer.State.Sleeping if lastUpdate < sleepUntil && signals.isEmpty => + if (!node.tryChangeBuffer(-cost * Settings.get.sleepCostFactor)) { + crash("not enough energy") + } + case _ => + if (!node.tryChangeBuffer(-cost)) { + crash("not enough energy") + } + }) + } // Avoid spamming user list across the network. if (worldTime % 20 == 0 && usersChanged) { @@ -396,17 +398,19 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con } private def processAddedComponents() { - for (component <- addedComponents) { - if (component.canBeSeenFrom(node)) { - components.synchronized(components += component.address -> component.name) - // Skip the signal if we're not initialized yet, since we'd generate a - // duplicate in the startup script otherwise. - if (kernelMemory > 0) { - signal("component_added", component.address, component.name) + if (addedComponents.size > 0) { + for (component <- addedComponents) { + if (component.canBeSeenFrom(node)) { + components.synchronized(components += component.address -> component.name) + // Skip the signal if we're not initialized yet, since we'd generate a + // duplicate in the startup script otherwise. + if (kernelMemory > 0) { + signal("component_added", component.address, component.name) + } } } + addedComponents.clear() } - addedComponents.clear() } private def verifyComponents() { @@ -1214,7 +1218,7 @@ class Computer(val owner: tileentity.Computer) extends ManagedComponent with Con // memory, regardless of the memory need of the underlying system // (which may change across releases). lua.gc(LuaState.GcAction.COLLECT, 0) - kernelMemory = lua.getTotalMemory - lua.getFreeMemory max 1 + kernelMemory = math.max(lua.getTotalMemory - lua.getFreeMemory, 1) recomputeMemory() // Fake zero sleep to avoid stopping if there are no signals. diff --git a/li/cil/oc/server/component/Crafting.scala b/li/cil/oc/server/component/Crafting.scala index c4fffc37f..a17fbdd4e 100644 --- a/li/cil/oc/server/component/Crafting.scala +++ b/li/cil/oc/server/component/Crafting.scala @@ -33,8 +33,8 @@ class Crafting(val owner: MCTileEntity) extends ManagedComponent { val manager = CraftingManager.getInstance val result = manager.findMatchingRecipe(CraftingInventory, owner.getWorldObj) if (result == null) return false - val targetStackSize = if (result.isStackable) wantedCount min result.getMaxStackSize else result.stackSize - val timesCrafted = (targetStackSize / result.stackSize) min amountPossible + val targetStackSize = if (result.isStackable) math.min(wantedCount, result.getMaxStackSize) else result.stackSize + val timesCrafted = math.min(targetStackSize / result.stackSize, amountPossible) if (timesCrafted <= 0) return true GameRegistry.onItemCrafted(context.player, result, this) val surplus = mutable.ArrayBuffer.empty[ItemStack] @@ -75,7 +75,7 @@ class Crafting(val owner: MCTileEntity) extends ManagedComponent { val stack = inventory.getStackInSlot(toParentSlot(slot)) setInventorySlotContents(slot, stack) if (stack != null) { - amountPossible = amountPossible min stack.stackSize + amountPossible = math.min(amountPossible, stack.stackSize) } } } diff --git a/li/cil/oc/server/component/Filesystem.scala b/li/cil/oc/server/component/Filesystem.scala index a809c8e39..735ee0ac9 100644 --- a/li/cil/oc/server/component/Filesystem.scala +++ b/li/cil/oc/server/component/Filesystem.scala @@ -133,7 +133,7 @@ class FileSystem(val fileSystem: api.fs.FileSystem, var label: Label) extends Ma Option(fileSystem.getHandle(handle)) match { case Some(file) => // Limit size of read buffer to avoid crazy allocations. - val buffer = new Array[Byte](n min Settings.get.maxReadBuffer) + val buffer = new Array[Byte](math.min(n, Settings.get.maxReadBuffer)) val read = file.read(buffer) if (read >= 0) { val bytes = diff --git a/li/cil/oc/server/component/Generator.scala b/li/cil/oc/server/component/Generator.scala index 3b25cb3d7..561cfe387 100644 --- a/li/cil/oc/server/component/Generator.scala +++ b/li/cil/oc/server/component/Generator.scala @@ -38,11 +38,11 @@ class Generator(val owner: MCTileEntity) extends ManagedComponent { if (space <= 0) { return result(false, "queue is full") } - val moveCount = stack.stackSize min space min count + val moveCount = math.min(stack.stackSize, math.min(space, count)) existingStack.stackSize += moveCount stack.stackSize -= moveCount case _ => - inventory = Some(stack.splitStack(stack.stackSize min count)) + inventory = Some(stack.splitStack(math.min(stack.stackSize, count))) } player.inventory.setInventorySlotContents(context.selectedSlot, stack) result(true) @@ -61,7 +61,7 @@ class Generator(val owner: MCTileEntity) extends ManagedComponent { val count = if (args.count > 0) args.checkInteger(0) else Int.MaxValue inventory match { case Some(stack) => - val removedStack = stack.splitStack(count min stack.stackSize) + val removedStack = stack.splitStack(math.min(count, stack.stackSize)) val success = context.player.inventory.addItemStackToInventory(removedStack) stack.stackSize += removedStack.stackSize if (success && stack.stackSize <= 0) { diff --git a/li/cil/oc/server/component/GraphicsCard.scala b/li/cil/oc/server/component/GraphicsCard.scala index 4a116730c..f5b2955dd 100644 --- a/li/cil/oc/server/component/GraphicsCard.scala +++ b/li/cil/oc/server/component/GraphicsCard.scala @@ -56,8 +56,8 @@ abstract class GraphicsCard extends ManagedComponent { screen(s => { val (gmw, gmh) = maxResolution val (smw, smh) = s.maxResolution - s.resolution = (gmw min smw, gmh min smh) - s.depth = PackedColor.Depth(maxDepth.id min s.maxDepth.id) + s.resolution = (math.min(gmw, smw), math.min(gmh, smh)) + s.depth = PackedColor.Depth(math.min(maxDepth.id, s.maxDepth.id)) s.foreground = 0xFFFFFF s.background = 0x000000 result(true) @@ -101,7 +101,7 @@ abstract class GraphicsCard extends ManagedComponent { @LuaCallback(value = "maxDepth", direct = true) def maxDepth(context: Context, args: Arguments): Array[AnyRef] = - screen(s => result(PackedColor.Depth(maxDepth.id min s.maxDepth.id) match { + screen(s => result(PackedColor.Depth(math.min(maxDepth.id, s.maxDepth.id)) match { case PackedColor.Depth.OneBit => 1 case PackedColor.Depth.FourBit => 4 case PackedColor.Depth.EightBit => 8 @@ -128,7 +128,7 @@ abstract class GraphicsCard extends ManagedComponent { screen(s => { val (gmw, gmh) = maxResolution val (smw, smh) = s.maxResolution - result(gmw min smw, gmh min smh) + result(math.min(gmw, smw), math.min(gmh, smh)) }) @LuaCallback(value = "get", direct = true) diff --git a/li/cil/oc/server/component/PowerDistributor.scala b/li/cil/oc/server/component/PowerDistributor.scala index 9bb4c320d..5def34b7d 100644 --- a/li/cil/oc/server/component/PowerDistributor.scala +++ b/li/cil/oc/server/component/PowerDistributor.scala @@ -18,13 +18,13 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { var globalBufferSize = 0.0 + var dirty = true + private var lastSentRatio = 0.0 - private val buffers = mutable.Set.empty[Connector] + private val buffers = mutable.ArrayBuffer.empty[Connector] - private val distributors = mutable.Set.empty[PowerDistributor] - - private var dirty = true + private val distributors = mutable.ArrayBuffer.empty[PowerDistributor] // ----------------------------------------------------------------------- // @@ -37,36 +37,29 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { // ----------------------------------------------------------------------- // def changeBuffer(delta: Double): Double = { - if (delta == 0) { - return 0 + if (delta == 0) 0 + else if (Settings.get.ignorePower) { + if (delta < 0) 0 + else /* if (delta > 0) */ delta } - if (Settings.get.ignorePower) { - if (delta < 0) { - return 0 - } - else /* if (delta > 0) */ { - return delta - } - } - this.synchronized { + else this.synchronized { val oldBuffer = globalBuffer - globalBuffer = (globalBuffer + delta) max 0 min globalBufferSize + globalBuffer = math.min(math.max(globalBuffer + delta, 0), globalBufferSize) if (globalBuffer == oldBuffer) { return delta } dirty = true if (delta < 0) { var remaining = -delta - for (connector <- buffers) { + for (connector <- buffers if remaining > 0 && connector.localBufferSize > 0) { if (connector.localBuffer > 0) { - connector.dirty = true if (connector.localBuffer < remaining) { remaining -= connector.localBuffer connector.localBuffer = 0 } else { connector.localBuffer -= remaining - return 0 + remaining = 0 } } } @@ -74,9 +67,8 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { } else /* if (delta > 0) */ { var remaining = delta - for (connector <- buffers) { + for (connector <- buffers if remaining > 0 && connector.localBufferSize > 0) { if (connector.localBuffer < connector.localBufferSize) { - connector.dirty = true val space = connector.localBufferSize - connector.localBuffer if (space < remaining) { remaining -= space @@ -84,7 +76,7 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { } else { connector.localBuffer += remaining - return 0 + remaining = 0 } } } @@ -96,7 +88,7 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { // ----------------------------------------------------------------------- // override def update() { - if (node != null && (dirty || buffers.exists(_.dirty))) { + if (dirty && owner.world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0 && node != null) { updateCachedValues() } } @@ -108,21 +100,25 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { if (node == this.node) { for (node <- node.reachableNodes) node match { case connector: Connector if connector.localBufferSize > 0 => this.synchronized { + assert(!buffers.contains(connector)) buffers += connector globalBuffer += connector.localBuffer globalBufferSize += connector.localBufferSize } case _ => node.host match { case distributor: PowerDistributor if distributor.node.canBeSeenFrom(this.node) => + assert(!distributors.contains(distributor)) distributors += distributor case _ => } } + assert(!distributors.contains(this)) distributors += this dirty = true } else node match { case connector: Connector if connector.localBufferSize > 0 => this.synchronized { + assert(!buffers.contains(connector)) buffers += connector globalBuffer += connector.localBuffer globalBufferSize += connector.localBufferSize @@ -130,6 +126,7 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { } case _ => node.host match { case distributor: PowerDistributor if distributor.node.canBeSeenFrom(this.node) => + assert(!distributors.contains(distributor)) distributors += distributor case _ => } @@ -162,16 +159,16 @@ class PowerDistributor(val owner: PowerInformation) extends ManagedComponent { def updateCachedValues() { // Computer average fill ratio of all buffers. - val (sumBuffer, sumBufferSize) = - buffers.foldRight((0.0, 0.0))((c, acc) => { - c.dirty = false // clear dirty flag for all connectors - (acc._1 + c.localBuffer, acc._2 + c.localBufferSize) - }) + var sumBuffer, sumBufferSize = 0.0 + for (buffer <- buffers) { + sumBuffer += buffer.localBuffer + sumBufferSize += buffer.localBufferSize + } // Only send updates if the state changed by more than 5%, more won't be // noticeable "from the outside" anyway. We send more frequent updates in // the gui/container of a block that needs it (like robots). val fillRatio = sumBuffer / sumBufferSize - val shouldSend = (lastSentRatio - fillRatio).abs > (5.0 / 100.0) + val shouldSend = math.abs(lastSentRatio - fillRatio) > (5.0 / 100.0) for (distributor <- distributors) distributor.synchronized { distributor.dirty = false distributor.globalBuffer = sumBuffer diff --git a/li/cil/oc/server/component/Robot.scala b/li/cil/oc/server/component/Robot.scala index d0b617090..1ed32a687 100644 --- a/li/cil/oc/server/component/Robot.scala +++ b/li/cil/oc/server/component/Robot.scala @@ -73,7 +73,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte if (args.count > 0 && args.checkAny(0) != null) checkSlot(args, 0) else selectedSlot result(stackInSlot(slot) match { - case Some(stack) => (robot.getInventoryStackLimit min stack.getMaxStackSize) - stack.stackSize + case Some(stack) => math.min(robot.getInventoryStackLimit, stack.getMaxStackSize) - stack.stackSize case _ => robot.getInventoryStackLimit }) } @@ -98,8 +98,8 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte else result((stackInSlot(selectedSlot), stackInSlot(slot)) match { case (Some(from), Some(to)) => if (haveSameItemType(from, to)) { - val space = (robot.getInventoryStackLimit min to.getMaxStackSize) - to.stackSize - val amount = count min space min from.stackSize + val space = math.min(robot.getInventoryStackLimit, to.getMaxStackSize) - to.stackSize + val amount = math.min(count, math.min(space, from.stackSize)) if (amount > 0) { from.stackSize -= amount to.stackSize += amount @@ -148,7 +148,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte if (dropped != null && dropped.stackSize > 0) { def tryDropIntoInventory(inventory: IInventory, filter: (Int) => Boolean) = { var success = false - val maxStackSize = inventory.getInventoryStackLimit min dropped.getMaxStackSize + val maxStackSize = math.min(inventory.getInventoryStackLimit, dropped.getMaxStackSize) val shouldTryMerge = !dropped.isItemStackDamageable && dropped.getMaxStackSize > 1 && inventory.getInventoryStackLimit > 1 if (shouldTryMerge) { for (slot <- 0 until inventory.getSizeInventory if dropped.stackSize > 0 && filter(slot)) { @@ -157,7 +157,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte existing.isItemEqual(dropped) && ItemStack.areItemStackTagsEqual(existing, dropped) if (shouldMerge) { val space = maxStackSize - existing.stackSize - val amount = space min dropped.stackSize + val amount = math.min(space, dropped.stackSize) assert(amount > 0) success = true existing.stackSize += amount @@ -168,7 +168,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte def canDropIntoSlot(slot: Int) = filter(slot) && inventory.isItemValidForSlot(slot, dropped) && inventory.getStackInSlot(slot) == null for (slot <- 0 until inventory.getSizeInventory if dropped.stackSize > 0 && canDropIntoSlot(slot)) { - val amount = maxStackSize min dropped.stackSize + val amount = math.min(maxStackSize, dropped.stackSize) inventory.setInventorySlotContents(slot, dropped.splitStack(amount)) success = true } @@ -256,8 +256,8 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte for (slot <- 0 until inventory.getSizeInventory if !success && filter(slot)) { val stack = inventory.getStackInSlot(slot) if (stack != null) { - val maxStackSize = robot.getInventoryStackLimit min stack.getMaxStackSize - val amount = maxStackSize min stack.stackSize min count + val maxStackSize = math.min(robot.getInventoryStackLimit, stack.getMaxStackSize) + val amount = math.min(maxStackSize, math.min(stack.stackSize, count)) val sucked = stack.splitStack(amount) success = player.inventory.addItemStackToInventory(sucked) stack.stackSize += sucked.stackSize @@ -600,7 +600,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) with RobotConte private def checkOptionalItemCount(args: Arguments, n: Int) = if (args.count > n && args.checkAny(n) != null) { - args.checkInteger(n) max 0 min robot.getInventoryStackLimit + math.max(args.checkInteger(n), math.min(0, robot.getInventoryStackLimit)) } else robot.getInventoryStackLimit diff --git a/li/cil/oc/server/component/WirelessNetworkCard.scala b/li/cil/oc/server/component/WirelessNetworkCard.scala index acffd2224..080ea16ee 100644 --- a/li/cil/oc/server/component/WirelessNetworkCard.scala +++ b/li/cil/oc/server/component/WirelessNetworkCard.scala @@ -30,7 +30,7 @@ class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard { @LuaCallback("setStrength") def setStrength(context: Context, args: Arguments): Array[AnyRef] = { - strength = args.checkDouble(0) max 0 min Settings.get.maxWirelessRange + strength = math.max(args.checkDouble(0), math.min(0, Settings.get.maxWirelessRange)) result(strength) } diff --git a/li/cil/oc/server/component/robot/Inventory.scala b/li/cil/oc/server/component/robot/Inventory.scala index e5ced6ef7..451e06809 100644 --- a/li/cil/oc/server/component/robot/Inventory.scala +++ b/li/cil/oc/server/component/robot/Inventory.scala @@ -80,17 +80,17 @@ class Inventory(player: Player) extends InventoryPlayer(player) { val existing = getStackInSlot(slot) existing != null && existing.isItemEqual(stack) && (!existing.getHasSubtypes || existing.getItemDamage == stack.getItemDamage) && - (existing.stackSize < (existing.getMaxStackSize min getInventoryStackLimit)) + (existing.stackSize < math.min(existing.getMaxStackSize, getInventoryStackLimit)) }).getOrElse(getFirstEmptyStackAccepting(stack)) if (slot >= firstInventorySlot) { if (getStackInSlot(slot) == null) { - val amount = stack.stackSize min (getInventoryStackLimit min stack.getMaxStackSize) + val amount = math.min(stack.stackSize, math.min(getInventoryStackLimit, stack.getMaxStackSize)) setInventorySlotContents(slot, stack.splitStack(amount)) } else { val existing = getStackInSlot(slot) - val space = (getInventoryStackLimit min existing.getMaxStackSize) - existing.stackSize - val amount = stack.stackSize min space + val space = math.min(getInventoryStackLimit, existing.getMaxStackSize) - existing.stackSize + val amount = math.min(stack.stackSize, space) existing.stackSize += amount stack.stackSize -= amount } diff --git a/li/cil/oc/server/component/robot/Player.scala b/li/cil/oc/server/component/robot/Player.scala index 19126f757..0aca472e1 100644 --- a/li/cil/oc/server/component/robot/Player.scala +++ b/li/cil/oc/server/component/robot/Player.scala @@ -153,7 +153,7 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na (!PortalGun.isPortalGun(stack) || PortalGun.isStandardPortalGun(stack)) && { val oldSize = stack.stackSize val oldDamage = if (stack != null) stack.getItemDamage else 0 - val heldTicks = 0 max stack.getMaxItemUseDuration min (duration * 20).toInt + val heldTicks = math.max(0, math.min(stack.getMaxItemUseDuration, (duration * 20).toInt)) val newStack = stack.useItemRightClick(world, this) if (isUsingItem) { getItemInUse.onPlayerStoppedUsing(world, this, getItemInUse.getMaxItemUseDuration - heldTicks) @@ -270,7 +270,7 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na if (stack != null) { robot.addXp(Settings.get.robotActionXp) } - return (breakTime * Settings.get.harvestRatio * ((1 - robot.level * Settings.get.harvestSpeedBoostPerLevel) max 0)) max 0.05 + return math.max(breakTime * Settings.get.harvestRatio * math.max(1 - robot.level * Settings.get.harvestSpeedBoostPerLevel, 0), 0.05) } 0 } @@ -280,13 +280,13 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na private def tryRepair(stack: ItemStack, oldDamage: Int) { val needsRepairing = stack.isItemStackDamageable && stack.getItemDamage > oldDamage - val damageRate = Settings.get.itemDamageRate * ((1 - robot.level * Settings.get.toolEfficiencyPerLevel) max 0) + val damageRate = Settings.get.itemDamageRate * math.max(1 - robot.level * Settings.get.toolEfficiencyPerLevel, 0) val shouldRepair = needsRepairing && getRNG.nextDouble() >= damageRate if (shouldRepair) { // If an item takes a lot of damage at once we don't necessarily want to // make *all* of that damage go away. Instead we scale it according to // our damage probability. This makes sure we don't discard massive - // damage spikes (e.g. on axes when using the treecapitator mod or such). + // damage spikes (e.g. on axes when using the TreeCapitator mod or such). val addedDamage = ((stack.getItemDamage - oldDamage) * damageRate).toInt stack.setItemDamage(oldDamage + addedDamage) } diff --git a/li/cil/oc/server/fs/VirtualFileSystem.scala b/li/cil/oc/server/fs/VirtualFileSystem.scala index 7c0137017..2cb6af129 100644 --- a/li/cil/oc/server/fs/VirtualFileSystem.scala +++ b/li/cil/oc/server/fs/VirtualFileSystem.scala @@ -277,7 +277,7 @@ trait VirtualFileSystem extends OutputStreamFileSystem { override def available() = if (isClosed) 0 - else (file.data.length - position) max 0 + else math.max(file.data.length - position, 0) override def close() = isClosed = true @@ -293,9 +293,10 @@ trait VirtualFileSystem extends OutputStreamFileSystem { override def read(b: Array[Byte], off: Int, len: Int) = if (!isClosed) { - if (available == 0) -1 + val count = available() + if (count == 0) -1 else { - val n = len min available + val n = math.min(len, count) file.data.view(position, file.data.length).copyToArray(b, off, n) position += n n @@ -311,7 +312,7 @@ trait VirtualFileSystem extends OutputStreamFileSystem { override def skip(n: Long) = if (!isClosed) { - position = ((position + n) min Int.MaxValue).toInt + position = math.min((position + n).toInt, Int.MaxValue) position } else throw new io.IOException("file is closed") diff --git a/li/cil/oc/server/fs/ZipFileInputStreamFileSystem.scala b/li/cil/oc/server/fs/ZipFileInputStreamFileSystem.scala index b21475878..7d217bc4b 100644 --- a/li/cil/oc/server/fs/ZipFileInputStreamFileSystem.scala +++ b/li/cil/oc/server/fs/ZipFileInputStreamFileSystem.scala @@ -85,7 +85,7 @@ object ZipFileInputStreamFileSystem { var root: ArchiveDirectory = null for (entry <- directories ++ files) { if (entry.path.length > 0) { - val parent = entry.path.substring(0, entry.path.lastIndexOf('/') max 0) + val parent = entry.path.substring(0, math.max(entry.path.lastIndexOf('/'), 0)) directories.find(d => d.path == parent) match { case Some(directory) => directory.children += entry case _ => diff --git a/li/cil/oc/server/network/Connector.scala b/li/cil/oc/server/network/Connector.scala index 74dece7d5..cfd3420a7 100644 --- a/li/cil/oc/server/network/Connector.scala +++ b/li/cil/oc/server/network/Connector.scala @@ -13,8 +13,6 @@ trait Connector extends Node with network.Connector with Persistable { var localBuffer = 0.0 - var dirty = true - private var distributor: Option[PowerDistributor] = None // ----------------------------------------------------------------------- // @@ -26,80 +24,76 @@ trait Connector extends Node with network.Connector with Persistable { // ----------------------------------------------------------------------- // def changeBuffer(delta: Double): Double = { - if (delta == 0) { - return 0 + if (delta == 0) 0 + else if (Settings.get.ignorePower) { + if (delta < 0) 0 + else /* if (delta > 0) */ delta } - if (Settings.get.ignorePower) { - if (delta < 0) { - return 0 - } - else /* if (delta > 0) */ { - return delta - } + else { + this.synchronized(distributor match { + case Some(d) => d.synchronized(d.changeBuffer(change(delta))) + case _ => change(delta) + }) } - def change() = { - val oldBuffer = localBuffer - localBuffer += delta - val remaining = if (localBuffer < 0) { - val remaining = localBuffer - localBuffer = 0 - remaining - } - else if (localBuffer > localBufferSize) { - val remaining = localBuffer - localBufferSize - localBuffer = localBufferSize - remaining - } - else 0 - dirty ||= (localBuffer != oldBuffer) + } + + private def change(delta: Double): Double = { + if (localBufferSize <= 0) return delta + val oldBuffer = localBuffer + localBuffer += delta + val remaining = if (localBuffer < 0) { + val remaining = localBuffer + localBuffer = 0 remaining } - this.synchronized(distributor match { - case Some(d) => d.synchronized(d.changeBuffer(change())) - case _ => change() - }) + else if (localBuffer > localBufferSize) { + val remaining = localBuffer - localBufferSize + localBuffer = localBufferSize + remaining + } + else 0 + if (localBuffer != oldBuffer) { + this.synchronized(distributor match { + case Some(d) => d.dirty = true + case _ => + }) + } + remaining } def tryChangeBuffer(delta: Double): Boolean = { - if (delta == 0) { - return true - } - if (Settings.get.ignorePower) { - if (delta < 0) { - return true - } - else /* if (delta > 0) */ { - return false - } - } - this.synchronized(distributor match { - case Some(d) => d.synchronized { - val newGlobalBuffer = globalBuffer + delta - newGlobalBuffer >= 0 && newGlobalBuffer <= globalBufferSize && d.changeBuffer(delta) == 0 - } - case _ => - val newLocalBuffer = localBuffer + delta - if (newLocalBuffer < 0 || newLocalBuffer > localBufferSize) { - false + if (delta == 0) true + else if (Settings.get.ignorePower) delta < 0 + else { + this.synchronized(distributor match { + case Some(d) => d.synchronized { + val newGlobalBuffer = globalBuffer + delta + newGlobalBuffer >= 0 && newGlobalBuffer <= globalBufferSize && d.changeBuffer(delta) == 0 } - else { - localBuffer = newLocalBuffer - true - } - }) + case _ => + val newLocalBuffer = localBuffer + delta + if (newLocalBuffer < 0 || newLocalBuffer > localBufferSize) { + false + } + else { + localBuffer = newLocalBuffer + true + } + }) + } } def setLocalBufferSize(size: Double) { this.synchronized(distributor match { case Some(d) => d.synchronized { - localBufferSize = size max 0 - val surplus = (localBuffer - localBufferSize) max 0 - localBuffer = localBuffer min localBufferSize + localBufferSize = math.max(size, 0) + val surplus = math.max(localBuffer - localBufferSize, 0) + localBuffer = math.min(localBuffer, localBufferSize) d.changeBuffer(surplus) } case _ => - localBufferSize = size max 0 - localBuffer = localBuffer min localBufferSize + localBufferSize = math.max(size, 0) + localBuffer = math.min(localBuffer, localBufferSize) }) } @@ -137,8 +131,7 @@ trait Connector extends Node with network.Connector with Persistable { override def load(nbt: NBTTagCompound) { super.load(nbt) - localBuffer = nbt.getDouble("buffer") max 0 min localBufferSize - dirty = true + localBuffer = math.max(nbt.getDouble("buffer"), math.min(0, localBufferSize)) } override def save(nbt: NBTTagCompound) { diff --git a/li/cil/oc/util/LuaStateFactory.scala b/li/cil/oc/util/LuaStateFactory.scala index a127f1088..9758a2114 100644 --- a/li/cil/oc/util/LuaStateFactory.scala +++ b/li/cil/oc/util/LuaStateFactory.scala @@ -220,15 +220,15 @@ object LuaStateFactory { state.pushScalaFunction(lua => { val string = lua.checkString(1) - val start = (lua.checkInteger(2) match { + val start = math.max(0, lua.checkInteger(2) match { case i if i < 0 => string.length + i case i => i - 1 - }) max 0 + }) val end = - if (lua.getTop > 2) (lua.checkInteger(3) match { + if (lua.getTop > 2) math.min(string.length, lua.checkInteger(3) match { case i if i < 0 => string.length + i + 1 case i => i - }) min string.length + }) else string.length if (end <= start) lua.pushString("") else lua.pushString(string.substring(start, end)) diff --git a/li/cil/oc/util/RTree.scala b/li/cil/oc/util/RTree.scala index 2fd3a3eca..50e9d003f 100644 --- a/li/cil/oc/util/RTree.scala +++ b/li/cil/oc/util/RTree.scala @@ -8,7 +8,7 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double, // Used for quick checks whether values are in the tree, e.g. for updates. private val entries = mutable.Map.empty[Data, Leaf] - private val m = (M / 2) max 1 + private val m = math.max(M / 2, 1) private var root = new NonLeaf() @@ -215,7 +215,7 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double, val newVol2 = r2.volumeIncluding(value) val growth1 = newVol1 - r1.volume val growth2 = newVol2 - r2.volume - val d = (growth2 - growth1).abs + val d = math.abs(growth2 - growth1) if (d > best) { bestValue = Some(value) r = if (growth1 < growth2 || (growth1 == growth2 && newVol1 < newVol2)) r1 else r2 @@ -263,9 +263,9 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double, private class Point(val x: Double, val y: Double, val z: Double) { def this(p: (Double, Double, Double)) = this(p._1, p._2, p._3) - def min(other: Point) = new Point(x min other.x, y min other.y, z min other.z) + def min(other: Point) = new Point(math.min(x, other.x), math.min(y, other.y), math.min(z, other.z)) - def max(other: Point) = new Point(x max other.x, y max other.y, z max other.z) + def max(other: Point) = new Point(math.max(x, other.x), math.max(y, other.y), math.max(z, other.z)) def asTuple = (x, y, z) } diff --git a/li/cil/oc/util/TextBuffer.scala b/li/cil/oc/util/TextBuffer.scala index 1fa783023..ec84f3c71 100644 --- a/li/cil/oc/util/TextBuffer.scala +++ b/li/cil/oc/util/TextBuffer.scala @@ -71,13 +71,13 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept */ def size_=(value: (Int, Int)): Boolean = { val (iw, ih) = value - val (w, h) = (iw max 1, ih max 1) + val (w, h) = (math.max(iw, 1), math.max(ih, 1)) if (width != w || height != h) { val newBuffer = Array.fill(h, w)(' ') val newColor = Array.fill(h, w)(packed) - (0 until (h min height)).foreach(y => { - Array.copy(buffer(y), 0, newBuffer(y), 0, w min width) - Array.copy(color(y), 0, newColor(y), 0, w min width) + (0 until math.min(h, height)).foreach(y => { + Array.copy(buffer(y), 0, newBuffer(y), 0, math.min(w, width)) + Array.copy(color(y), 0, newColor(y), 0, math.min(w, width)) }) buffer = newBuffer color = newColor @@ -98,7 +98,7 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept var changed = false val line = buffer(row) val lineColor = color(row) - for (x <- col until ((col + s.length) min width)) if (x >= 0) { + for (x <- col until math.min(col + s.length, width)) if (x >= 0) { val c = s(x - col) changed = changed || (line(x) != c) || (lineColor(x) != packed) line(x) = c @@ -113,10 +113,10 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept if (w <= 0 || h <= 0) return false if (col + w < 0 || row + h < 0 || col >= width || row >= height) return false var changed = false - for (y <- (row max 0) until ((row + h) min height)) { + for (y <- math.max(row, 0) until math.min(row + h, height)) { val line = buffer(y) val lineColor = color(y) - for (x <- (col max 0) until ((col + w) min width)) { + for (x <- math.max(col, 0) until math.min(col + w, width)) { changed = changed || (line(x) != c) || (lineColor(x) != packed) line(x) = c lineColor(x) = packed @@ -133,11 +133,11 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept // Loop over the target rectangle, starting from the directions away from // the source rectangle and copy the data. This way we ensure we don't // overwrite anything we still need to copy. - val (dx0, dx1) = ((col + tx + w - 1) max 0 min (width - 1), (col + tx) max 0 min width) match { + val (dx0, dx1) = (math.max(col + tx + w - 1, math.min(0, width - 1)), math.max(col + tx, math.min(0, width))) match { case dx if tx > 0 => dx case dx => dx.swap } - val (dy0, dy1) = ((row + ty + h - 1) max 0 min (height - 1), (row + ty) max 0 min height) match { + val (dy0, dy1) = (math.max(row + ty + h - 1, math.min(0, height - 1)), math.max(row + ty, math.min(0, height))) match { case dy if ty > 0 => dy case dy => dy.swap } @@ -170,7 +170,7 @@ class TextBuffer(var width: Int, var height: Int, initialDepth: PackedColor.Dept size = (w, h) val b = nbt.getTagList("buffer") - for (i <- 0 until (h min b.tagCount)) { + for (i <- 0 until math.min(h, b.tagCount)) { val line = b.tagAt(i).asInstanceOf[NBTTagString].data set(0, i, line) } diff --git a/li/cil/oc/util/WirelessNetwork.scala b/li/cil/oc/util/WirelessNetwork.scala index dc163b0b3..c76660ddc 100644 --- a/li/cil/oc/util/WirelessNetwork.scala +++ b/li/cil/oc/util/WirelessNetwork.scala @@ -33,10 +33,9 @@ object WirelessNetwork { case Some(tree) => tree(card) match { case Some((x, y, z)) => - val (dx, dy, dz) = ( - (card.owner.xCoord + 0.5 - x).abs, - (card.owner.yCoord + 0.5 - y).abs, - (card.owner.zCoord + 0.5 - z).abs) + val dx = math.abs(card.owner.xCoord + 0.5 - x) + val dy = math.abs(card.owner.yCoord + 0.5 - y) + val dz = math.abs(card.owner.zCoord + 0.5 - z) if (dx > 0.5 || dy > 0.5 || dz > 0.5) { tree.remove(card) tree.add(card)