blob: ce9a282e357ff3465660d7fde3cb68ad15ee5467 [file] [log] [blame] [raw]
package li.cil.oc.integration.nei
import codechicken.nei.recipe.IUsageHandler
import com.google.common.base.Strings
import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentAware
import li.cil.oc.api.prefab
import li.cil.oc.server.driver.Registry
import li.cil.oc.server.machine.Callbacks
import net.minecraft.item.ItemStack
import net.minecraft.util.EnumChatFormatting
import scala.collection.convert.WrapAsScala._
class CallbackDocHandler(pages: Option[Array[String]]) extends PagedUsageHandler(pages) {
def this() = this(None)
private val DocPattern = """(?s)^function(\(.*?\).*?) -- (.*)$""".r
private val VexPattern = """(?s)^function(\(.*?\).*?); (.*)$""".r
override def getRecipeName = "OpenComputers API"
override def getUsageHandler(input: String, ingredients: AnyRef*): IUsageHandler = {
if (input == "item") {
ingredients.collect {
case stack: ItemStack if stack.getItem != null =>
val callbacks = getCallbacks(api.Driver.environmentFor(stack)).toBuffer
// TODO remove in OC 1.7
if (callbacks.isEmpty) {
callbacks ++= (Option(Registry.driverFor(stack)) match {
case Some(driver: EnvironmentAware) =>
getCallbacks(driver.providedEnvironment(stack))
case _ => Registry.blocks.collect {
case driver: prefab.DriverTileEntity with EnvironmentAware =>
if (driver.getTileEntityClass != null && !driver.getTileEntityClass.isInterface)
driver.providedEnvironment(stack)
else null
case driver: EnvironmentAware => driver.providedEnvironment(stack)
}.filter(_ != null).flatMap(getCallbacks)
})
}
if (callbacks.nonEmpty) {
val fullDocumentation = callbacks.toArray.sorted.mkString("\n\n")
val pages = fullDocumentation.lines.grouped(12).map(_.mkString("\n")).toArray
Option(new CallbackDocHandler(Option(pages)))
}
else None
}.collectFirst {
case Some(handler) => handler
}.getOrElse(this)
}
else this
}
private def getCallbacks(env: Class[_]) = if (env != null) {
Callbacks.fromClass(env).map {
case (name, callback) =>
val doc = callback.annotation.doc
if (Strings.isNullOrEmpty(doc)) name
else {
val (signature, documentation) = doc match {
case DocPattern(head, tail) => (name + head, tail)
case VexPattern(head, tail) => (name + head, tail)
case _ => (name, doc)
}
wrap(signature, 160).map(EnumChatFormatting.BLACK.toString + _).mkString("\n") +
EnumChatFormatting.RESET + "\n" +
wrap(documentation, 152).map(" " + _).mkString("\n")
}
}
}
else Seq.empty
}