diff --git a/li/cil/oc/Items.scala b/li/cil/oc/Items.scala index 2cc0331e0..44a10a032 100644 --- a/li/cil/oc/Items.scala +++ b/li/cil/oc/Items.scala @@ -1,11 +1,18 @@ package li.cil.oc import li.cil.oc.common.items.ItemHDD +import li.cil.oc.common.items.ItemGraphicsCard +import li.cil.oc.common.util.ItemComponentCache +import li.cil.oc.server.components.GraphicsCard object Items { + var gpu: ItemGraphicsCard = null var hdd: ItemHDD = null def init() { - hdd = new ItemHDD() + gpu = new ItemGraphicsCard + hdd = new ItemHDD + + ItemComponentCache.register(Config.itemGPUId, nbt => new GraphicsCard(nbt)) } } \ No newline at end of file diff --git a/li/cil/oc/api/IComputerContext.scala b/li/cil/oc/api/IComputerContext.scala index 175c4dc17..e0acd5050 100644 --- a/li/cil/oc/api/IComputerContext.scala +++ b/li/cil/oc/api/IComputerContext.scala @@ -46,5 +46,5 @@ trait IComputerContext { * * @param id the id of the component to get. */ - def component[T: TypeTag](id: Int): T + def component[T](id: Int): T } \ No newline at end of file diff --git a/li/cil/oc/client/computer/Computer.scala b/li/cil/oc/client/computer/Computer.scala index fca627758..b03bc994c 100644 --- a/li/cil/oc/client/computer/Computer.scala +++ b/li/cil/oc/client/computer/Computer.scala @@ -21,7 +21,7 @@ class Computer(val owner: AnyRef) extends IComputerContext with IComputer { def signal(name: String, args: Any*) = throw new NotImplementedError - def component[T: TypeTag](id: Int) = throw new NotImplementedError + def component[T](id: Int) = throw new NotImplementedError // ----------------------------------------------------------------------- // // IComputer diff --git a/li/cil/oc/common/CommonProxy.scala b/li/cil/oc/common/CommonProxy.scala index 34231fc49..56242a3e9 100644 --- a/li/cil/oc/common/CommonProxy.scala +++ b/li/cil/oc/common/CommonProxy.scala @@ -1,13 +1,11 @@ package li.cil.oc.common import cpw.mods.fml.common.event._ -import cpw.mods.fml.common.network.Player import cpw.mods.fml.common.registry.LanguageRegistry import li.cil.oc._ import li.cil.oc.api.OpenComputersAPI import li.cil.oc.server.computer.Drivers import li.cil.oc.server.drivers._ -import net.minecraft.world.World class CommonProxy { def preInit(e: FMLPreInitializationEvent): Unit = { diff --git a/li/cil/oc/common/items/ItemGraphicsCard.scala b/li/cil/oc/common/items/ItemGraphicsCard.scala index 07ee262cb..e3d86724b 100644 --- a/li/cil/oc/common/items/ItemGraphicsCard.scala +++ b/li/cil/oc/common/items/ItemGraphicsCard.scala @@ -4,29 +4,6 @@ import li.cil.oc.Config import li.cil.oc.CreativeTab import net.minecraft.item.Item import net.minecraft.world.World -import scala.collection.mutable.WeakHashMap -import net.minecraft.nbt.NBTTagCompound -import li.cil.oc.server.components.Disk -import net.minecraft.item.ItemStack -import li.cil.oc.server.components.GraphicsCard - -object ItemGraphicsCard { - private val instances = WeakHashMap.empty[NBTTagCompound, GraphicsCard] - - def getComponent(item: ItemStack): Option[GraphicsCard] = - if (item.itemID == Config.itemGPUId) { - val tag = item.getTagCompound match { - case null => new NBTTagCompound - case tag => tag - } - instances.get(tag).orElse { - val component = new GraphicsCard(tag) - instances += tag -> component - Some(component) - } - } - else throw new IllegalArgumentException("Invalid item type.") -} class ItemGraphicsCard extends Item(Config.itemGPUId) { setMaxStackSize(1) diff --git a/li/cil/oc/common/util/ItemComponentCache.scala b/li/cil/oc/common/util/ItemComponentCache.scala new file mode 100644 index 000000000..76832754c --- /dev/null +++ b/li/cil/oc/common/util/ItemComponentCache.scala @@ -0,0 +1,42 @@ +package li.cil.oc.common.util + +import scala.collection.mutable._ +import scala.reflect.runtime.universe._ + +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound + +/** + * This singleton is responsible for caching actual item component instances, + * that is the "component" object belonging to an ItemStack, based on its NBT + * data. + */ +object ItemComponentCache { + private val caches = Map.empty[Int, Cache[_]] + + def get[T](item: ItemStack) = caches.get(item.itemID) match { + case None => None + case Some(cache) => cache.asInstanceOf[Cache[T]].getComponent(item) + } + + def register[T](id: Int, ctor: (NBTTagCompound) => T): Unit = + caches += id -> new Cache[T](id, ctor) + + private class Cache[T](val id: Int, val ctor: (NBTTagCompound) => T) { + private val instances = WeakHashMap.empty[NBTTagCompound, T] + + def getComponent(item: ItemStack): Option[T] = + if (item.itemID == id) { + val nbt = item.getTagCompound match { + case null => new NBTTagCompound + case tag => tag + } + instances.get(nbt).orElse { + val component = ctor(nbt) + instances += nbt -> component + Some(component) + } + } + else throw new IllegalArgumentException("Invalid item type.") + } +} \ No newline at end of file diff --git a/li/cil/oc/server/components/IComponent.scala b/li/cil/oc/server/components/IComponent.scala index 4c3a19c44..09e41a8b1 100644 --- a/li/cil/oc/server/components/IComponent.scala +++ b/li/cil/oc/server/components/IComponent.scala @@ -1,5 +1,7 @@ package li.cil.oc.server.components +import li.cil.oc.common.util.INBTSerializable + trait IComponent { private var _id = 0 diff --git a/li/cil/oc/server/computer/Computer.scala b/li/cil/oc/server/computer/Computer.scala index 9f96ef775..7ca1fb3b4 100644 --- a/li/cil/oc/server/computer/Computer.scala +++ b/li/cil/oc/server/computer/Computer.scala @@ -147,12 +147,9 @@ class Computer(val owner: IComputerEnvironment) extends IComputerContext with IC }) } - def component[T: TypeTag](id: Int) = components.get(id) match { + def component[T](id: Int) = components.get(id) match { case None => throw new IllegalArgumentException("no such component") - case Some(component) => - // TODO is this right? - if (component.getClass() == typeOf[T]) component.asInstanceOf[T] - else throw new IllegalArgumentException("bad component type") + case Some(component) => component.asInstanceOf[T] } // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/server/drivers/GraphicsCardDriver.scala b/li/cil/oc/server/drivers/GraphicsCardDriver.scala index 3979be641..c35497a62 100644 --- a/li/cil/oc/server/drivers/GraphicsCardDriver.scala +++ b/li/cil/oc/server/drivers/GraphicsCardDriver.scala @@ -5,7 +5,7 @@ import li.cil.oc.api.Callback import li.cil.oc.api.ComponentType import li.cil.oc.api.IComputerContext import li.cil.oc.api.IItemDriver -import li.cil.oc.common.items.ItemGraphicsCard +import li.cil.oc.common.util.ItemComponentCache import li.cil.oc.server.components.GraphicsCard import li.cil.oc.server.components.Screen import net.minecraft.item.ItemStack @@ -78,5 +78,5 @@ object GraphicsCardDriver extends IItemDriver { def componentType(item: ItemStack) = ComponentType.PCI - def component(item: ItemStack) = ItemGraphicsCard.getComponent(item) + def component(item: ItemStack) = ItemComponentCache.get[GraphicsCard](item) } \ No newline at end of file