blob: c0ed5cad3553f372e3d641e37538626357a6e3c8 [file] [log] [blame] [raw]
package li.cil.oc.api.power
import li.cil.oc.api.network.{Message, Node}
import net.minecraft.nbt.NBTTagCompound
import scala.collection.mutable
trait Receiver extends Node {
def demand = _demand
def demand_=(value: Double) = if (value != _demand) {
providers.foreach(_.updateDemand(this, value))
_demand = value
}
def provider: Option[Provider] = providers.find(_.isActive)
/**
* Called when the receiver has enough power to operate.
*/
def onPowerAvailable() {
println("received energy")
}
/**
* Called when the receiver has no power to operate. This can happen at a later time
* then unConnect was called, because of the internal capacity
*/
def onPowerUnavailable() {
println("no more energy")
}
// ----------------------------------------------------------------------- //
override def receive(message: Message) = super.receive(message) orElse {
message.name match {
case "system.connect" => {
message.source match {
case p: Provider => {
if (providers.add(p)) {
p.connectNode(this, _demand)
}
}
case _ =>
}
}
case "system.disconnect" => {
message.source match {
case p: Provider => {
if (providers.remove(p)) {
p.disconnectNode(this)
}
}
case _ =>
}
}
case _ =>
}
None
}
override protected def onDisconnect() {
super.onDisconnect()
providers.foreach(_.disconnectNode(this))
}
// ----------------------------------------------------------------------- //
override abstract def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
buffer = nbt.getDouble("buffer")
}
override abstract def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
nbt.setDouble("buffer", buffer)
}
// ----------------------------------------------------------------------- //
private var _demand = 2.0
private val providers = mutable.Set.empty[Provider]
private var buffer = 0.0
private val maxBuffer = 100.0
private var isPowerAvailable = false
/** Set from the provider whenever its power state changes. */
private[power] var isReceivingPower = false
override def update() {
super.update()
//if has enough energy to operate
if (isReceivingPower) {
//increase buffer
// TODO maybe make the speed of the "cooldown" dependent on the demand?
// TODO another possibility: increase the demand dynamically while charging?
if (maxBuffer > buffer + 1)
buffer += 1
//notify if energy wasn't available before
if (!isPowerAvailable) {
isPowerAvailable = true
onPowerAvailable()
}
}
//continue running until we are out of energy
else if (buffer >= demand) {
buffer -= demand
}
else if (isPowerAvailable) {
isPowerAvailable = false
onPowerUnavailable()
}
}
}