initializing network connections in tile entities' update function now (i.e. we call Network.joinOrCreateNetwork from there if we have a node and that node isn't in a network yet). this is because on block added is somewhat unreliable, in particular when other mods start getting involved - say, RIM. which is what I tested with right now, and it actually works, i.e. computers can be moved by carriages and keep running without fail. huzzah; also removed weak keys from screen renderer cache, the timeout is enough

This commit is contained in:
Florian Nücke 2013-11-04 04:52:01 +01:00
parent 60447a090e
commit 59c953ec00
9 changed files with 73 additions and 25 deletions

View File

@ -24,7 +24,6 @@ object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with
/** We cache the display lists for the screens we render for performance. */
val cache = com.google.common.cache.CacheBuilder.newBuilder().
weakKeys().
expireAfterAccess(5, TimeUnit.SECONDS).
removalListener(this).
asInstanceOf[CacheBuilder[Screen, Int]].build[Screen, Int]()

View File

@ -4,8 +4,7 @@ import cpw.mods.fml.common.registry.GameRegistry
import java.util
import li.cil.oc.Config
import li.cil.oc.CreativeTab
import li.cil.oc.api.Network
import li.cil.oc.api.network.{Environment, Node}
import li.cil.oc.api.network.Environment
import li.cil.oc.common.tileentity.Rotatable
import net.minecraft.block.Block
import net.minecraft.block.material.Material
@ -290,13 +289,7 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) {
override def onBlockAdded(world: World, x: Int, y: Int, z: Int) =
subBlock(world, x, y, z) match {
case Some(subBlock) => {
world.getBlockTileEntity(x, y, z) match {
case _: Environment => Network.joinOrCreateNetwork(world, x, y, z)
case _ => // Nothing special to do.
}
subBlock.onBlockAdded(world, x, y, z)
}
case Some(subBlock) => subBlock.onBlockAdded(world, x, y, z)
case _ => // Invalid but avoid match error.
}

View File

@ -2,6 +2,7 @@ package li.cil.oc.common.tileentity
import dan200.computer.api.{ILuaContext, IComputerAccess, IPeripheral}
import li.cil.oc.api
import li.cil.oc.api.Network
import li.cil.oc.api.network._
import li.cil.oc.server
import li.cil.oc.server.driver
@ -25,6 +26,10 @@ class Adapter extends Rotatable with Environment with IPeripheral {
// ----------------------------------------------------------------------- //
override def updateEntity() {
super.updateEntity()
if (node != null && node.network == null) {
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
}
for (block <- blocks) block match {
case Some((environment, _)) => environment.update()
case _ => // Empty.

View File

@ -1,6 +1,7 @@
package li.cil.oc.common.tileentity
import java.util.concurrent.atomic.AtomicBoolean
import li.cil.oc.api.Network
import li.cil.oc.api.driver.Slot
import li.cil.oc.client.{PacketSender => ClientPacketSender}
import li.cil.oc.server.component
@ -60,7 +61,16 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit
// ----------------------------------------------------------------------- //
override def updateEntity() = if (!worldObj.isRemote) {
override def updateEntity() {
super.updateEntity()
if (node != null && node.network == null) {
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
}
else if (!worldObj.isRemote) {
// If we just joined a network we were just loaded from disk. We skip the
// update this round to allow other tile entities to join the network,
// too, avoiding issues of missing nodes (e.g. in the GPU which would
// otherwise loose track of its screen).
instance.update()
updateRedstoneInput()
if (hasChanged.get)
@ -68,6 +78,7 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit
if (isRunning != instance.isRunning)
ServerPacketSender.sendComputerState(this, instance.isRunning)
isRunning = instance.isRunning
}
for (component <- components) component match {
case Some(environment) => environment.update()
@ -75,7 +86,7 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit
}
}
override def validate() = {
override def validate() {
super.validate()
if (worldObj.isRemote) {
ClientPacketSender.sendComputerStateRequest(this)

View File

@ -1,6 +1,7 @@
package li.cil.oc.common.tileentity
import li.cil.oc.api
import li.cil.oc.api.Network
import li.cil.oc.api.driver.Slot
import li.cil.oc.api.network.{Component, Visibility}
import li.cil.oc.server.driver.Registry
@ -15,6 +16,15 @@ class DiskDrive extends Rotatable with Environment with ComponentInventory {
// ----------------------------------------------------------------------- //
override def updateEntity() {
super.updateEntity()
if (node != null && node.network == null) {
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
}
}
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
if (node != null) node.load(nbt)

View File

@ -2,6 +2,7 @@ package li.cil.oc.common.tileentity
import cpw.mods.fml.common.network.Player
import li.cil.oc.api
import li.cil.oc.api.Network
import li.cil.oc.api.network.{Visibility, Message}
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound
@ -11,6 +12,16 @@ class Keyboard extends Rotatable with Environment {
withComponent("keyboard").
create()
// ----------------------------------------------------------------------- //
override def updateEntity() {
if (node != null && node.network == null) {
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
}
}
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
node.load(nbt)
@ -21,6 +32,8 @@ class Keyboard extends Rotatable with Environment {
node.save(nbt)
}
// ----------------------------------------------------------------------- //
override def onMessage(message: Message) = {
message.data match {
case Array(p: Player, char: Character, code: Integer) if message.name == "keyboard.keyDown" =>
@ -37,6 +50,8 @@ class Keyboard extends Rotatable with Environment {
super.onMessage(message)
}
// ----------------------------------------------------------------------- //
def isUseableByPlayer(p: Player) = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this &&
p.asInstanceOf[EntityPlayer].getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64
}

View File

@ -4,6 +4,7 @@ import buildcraft.api.power.{PowerHandler, IPowerReceptor}
import ic2.api.energy.event.{EnergyTileLoadEvent, EnergyTileUnloadEvent}
import ic2.api.energy.tile.IEnergySink
import li.cil.oc.api
import li.cil.oc.api.Network
import li.cil.oc.api.network._
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
@ -37,6 +38,9 @@ class PowerConverter extends Rotatable with Environment with IEnergySink with IP
override def updateEntity() {
super.updateEntity()
if (node != null && node.network == null) {
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
}
if (!worldObj.isRemote) {
if (!addedToEnet) {
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this))
@ -62,14 +66,14 @@ class PowerConverter extends Rotatable with Environment with IEnergySink with IP
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) = {
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
node.load(nbt)
getPowerProvider.readFromNBT(nbt)
}
override def writeToNBT(nbt: NBTTagCompound) = {
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
node.save(nbt)
getPowerProvider.writeToNBT(nbt)

View File

@ -1,6 +1,7 @@
package li.cil.oc.common.tileentity
import li.cil.oc.api
import li.cil.oc.api.Network
import li.cil.oc.api.network._
import li.cil.oc.client.{PacketSender => ClientPacketSender}
import li.cil.oc.server.network.Connector
@ -23,6 +24,10 @@ class PowerDistributor extends Rotatable with Environment {
// ----------------------------------------------------------------------- //
override def updateEntity() {
super.updateEntity()
if (node != null && node.network == null) {
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
}
if (!worldObj.isRemote && connectors.exists(_.dirty) && computeAverage()) {
// Adjust buffer fill ratio for all buffers to average.
connectors.foreach(c => c.buffer = c.bufferSize * average)

View File

@ -1,10 +1,11 @@
package li.cil.oc.common.tileentity
import li.cil.oc.Config
import li.cil.oc.api.Network
import li.cil.oc.api.network.Visibility
import li.cil.oc.client.gui
import li.cil.oc.client.{PacketSender => ClientPacketSender}
import li.cil.oc.common.component
import li.cil.oc.common.component.Screen.{Environment => ScreenEnvironment}
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.AxisAlignedBB
@ -23,7 +24,7 @@ class ScreenTier3 extends Screen {
protected def maxResolution = Config.screenResolutionsByTier(2)
}
abstract class Screen extends Rotatable with component.Screen.Environment {
abstract class Screen extends Rotatable with ScreenEnvironment {
var currentGui: Option[gui.Screen] = None
/**
@ -75,7 +76,7 @@ abstract class Screen extends Rotatable with component.Screen.Environment {
super.save(nbt)
}
override def validate() = {
override def validate() {
super.validate()
if (worldObj.isRemote) ClientPacketSender.sendScreenBufferRequest(this)
}
@ -89,7 +90,11 @@ abstract class Screen extends Rotatable with component.Screen.Environment {
// ----------------------------------------------------------------------- //
override def updateEntity() =
override def updateEntity() {
super.updateEntity()
if (node != null && node.network == null) {
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
}
if (shouldCheckForMultiBlock) {
// Make sure we merge in a deterministic order, to avoid getting
// different results on server and client due to the update order
@ -142,6 +147,7 @@ abstract class Screen extends Rotatable with component.Screen.Environment {
}
)
}
}
def checkMultiBlock() {
shouldCheckForMultiBlock = true