mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-08-03 19:17:27 -04:00
94 lines
3.1 KiB
Scala
94 lines
3.1 KiB
Scala
package li.cil.oc.server.driver
|
|
|
|
import java.nio.charset.Charset
|
|
|
|
import com.google.common.hash.Hashing
|
|
import li.cil.oc.OpenComputers
|
|
import li.cil.oc.api
|
|
import li.cil.oc.api.network._
|
|
import net.minecraft.nbt.NBTTagCompound
|
|
|
|
class CompoundBlockNodeContainer(val name: String, val environments: (String, NodeContainerItem)*) extends NodeContainerItem {
|
|
// Block drivers with visibility < network usually won't make much sense,
|
|
// but let's play it safe and use the least possible visibility based on
|
|
// the drivers we encapsulate.
|
|
val getNode: ComponentNode = api.Network.newNode(this, (environments.filter(_._2.getNode != null).map(_._2.getNode.getReachability) ++ Seq(Visibility.NONE)).max).
|
|
withComponent(name).
|
|
create()
|
|
|
|
val updatingEnvironments = environments.map(_._2).filter(_.canUpdate)
|
|
|
|
// Force all wrapped components to be neighbor visible, since we as their
|
|
// only neighbor will take care of all component-related interaction.
|
|
for ((_, environment) <- environments) environment.getNode match {
|
|
case component: ComponentNode => component.setVisibility(Visibility.NEIGHBORS)
|
|
case _ =>
|
|
}
|
|
|
|
override def canUpdate: Boolean = environments.exists(_._2.canUpdate)
|
|
|
|
override def update() {
|
|
for (environment <- updatingEnvironments) {
|
|
environment.update()
|
|
}
|
|
}
|
|
|
|
override def onMessage(message: Message) {}
|
|
|
|
override def onConnect(node: Node) {
|
|
if (node == this.getNode) {
|
|
for ((_, environment) <- environments if environment.getNode != null) {
|
|
node.connect(environment.getNode)
|
|
}
|
|
}
|
|
}
|
|
|
|
override def onDisconnect(node: Node) {
|
|
if (node == this.getNode) {
|
|
for ((_, environment) <- environments if environment.getNode != null) {
|
|
environment.getNode.remove()
|
|
}
|
|
}
|
|
}
|
|
|
|
private final val TypeHashTag = "typeHash"
|
|
|
|
|
|
override def serializeNBT(): NBTTagCompound = {
|
|
val nbt = new NBTTagCompound()
|
|
nbt.setLong(TypeHashTag, typeHash)
|
|
getNode.save(nbt)
|
|
for ((driver, environment) <- environments) {
|
|
try {
|
|
nbt.setTag(driver, environment.serializeNBT())
|
|
} catch {
|
|
case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while saving.", e)
|
|
}
|
|
}
|
|
nbt
|
|
}
|
|
|
|
override def deserializeNBT(nbt: NBTTagCompound): Unit = {
|
|
// Ignore existing data if the underlying type is different.
|
|
if (nbt.hasKey(TypeHashTag) && nbt.getLong(TypeHashTag) != typeHash) return
|
|
getNode.load(nbt)
|
|
for ((driver, environment) <- environments) {
|
|
if (nbt.hasKey(driver)) {
|
|
try {
|
|
environment.deserializeNBT(nbt.getCompoundTag(driver))
|
|
} catch {
|
|
case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while loading.", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override def save(nbt: NBTTagCompound) {
|
|
}
|
|
|
|
private def typeHash = {
|
|
val hash = Hashing.sha256().newHasher()
|
|
environments.map(_._2.getClass.getName).sorted.foreach(hash.putString(_, Charset.defaultCharset()))
|
|
hash.hash().asLong()
|
|
}
|
|
} |