mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2026-03-25 17:02:46 +01:00
Unify item factory and recoverer registries
This commit is contained in:
@@ -2,6 +2,7 @@ package ocelot.desktop
|
||||
|
||||
import buildinfo.BuildInfo
|
||||
import li.flor.nativejfilechooser.NativeJFileChooser
|
||||
import ocelot.desktop.inventory.Items
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.swing.SplashScreen
|
||||
import ocelot.desktop.ui.widget._
|
||||
@@ -64,6 +65,8 @@ object OcelotDesktop extends Logging {
|
||||
Messages.load(Source.fromURL(getClass.getResource("/ocelot/desktop/messages.txt")))
|
||||
ColorScheme.load(Source.fromURL(getClass.getResource("/ocelot/desktop/colorscheme.txt")))
|
||||
|
||||
Items.init()
|
||||
|
||||
splashScreen.setStatus("Initializing GUI...", 0.30f)
|
||||
createWorkspace()
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ trait Item {
|
||||
*
|
||||
* @example {{{
|
||||
* override protected def fillTooltipBody(body: Widget): Unit = {
|
||||
* super.fillTooltipBody(body)
|
||||
* body.children :+= new Label {
|
||||
* override def text: String = "Hello world"
|
||||
* override def color: Color = Color.Grey
|
||||
|
||||
@@ -51,4 +51,9 @@ trait ItemFactory {
|
||||
* Constructs a new item instance.
|
||||
*/
|
||||
def build(): I
|
||||
|
||||
/**
|
||||
* Returns a list of recoverers provided by the factory,
|
||||
*/
|
||||
def recoverers: Iterable[ItemRecoverer[_, _]]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package ocelot.desktop.inventory
|
||||
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
/**
|
||||
* Allows recovering an [[Item]] from [[S]] (typically an [[totoro.ocelot.brain.entity.traits.Entity Entity]]).
|
||||
*
|
||||
* This is used for migration from old saves before the inventory system was introduced to Ocelot Desktop.
|
||||
*/
|
||||
trait ItemRecoverer[S] {
|
||||
type I <: Item
|
||||
final class ItemRecoverer[S: ClassTag, I <: Item](f: S => I) {
|
||||
val sourceClass: Class[_] = classTag[S].runtimeClass
|
||||
|
||||
def recover(source: S): I
|
||||
def recover(source: S): I = f(source)
|
||||
}
|
||||
|
||||
object ItemRecoverer {
|
||||
def apply[S: ClassTag, I <: Item](f: S => I): ItemRecoverer[S, I] = new ItemRecoverer(f)
|
||||
}
|
||||
|
||||
140
src/main/scala/ocelot/desktop/inventory/Items.scala
Normal file
140
src/main/scala/ocelot/desktop/inventory/Items.scala
Normal file
@@ -0,0 +1,140 @@
|
||||
package ocelot.desktop.inventory
|
||||
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.inventory.item._
|
||||
import ocelot.desktop.util.Logging
|
||||
import ocelot.desktop.util.ReflectionUtils.linearizationOrder
|
||||
import totoro.ocelot.brain.loot.Loot
|
||||
import totoro.ocelot.brain.util.ExtendedTier.ExtendedTier
|
||||
import totoro.ocelot.brain.util.Tier.Tier
|
||||
import totoro.ocelot.brain.util.{ExtendedTier, Tier}
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
object Items extends Logging {
|
||||
private val _groups = ArrayBuffer.empty[ItemGroup]
|
||||
private val _recoverers = mutable.Map.empty[Class[_], ItemRecoverer[_, _]]
|
||||
|
||||
// this is just to force load the class during initialization
|
||||
def init(): Unit = {}
|
||||
|
||||
/** Registers a recoverer for [[ItemRecoverer.sourceClass]].
|
||||
*/
|
||||
def registerRecoverer(recoverer: ItemRecoverer[_, _]): Unit = {
|
||||
if (!_recoverers.contains(recoverer.sourceClass)) {
|
||||
_recoverers(recoverer.sourceClass) = recoverer
|
||||
logger.info(s"Registered a recoverer for ${recoverer.sourceClass.getName}")
|
||||
}
|
||||
}
|
||||
|
||||
private def registerItemFactoryRecoverers(factory: ItemFactory): Unit = {
|
||||
for (recoverer <- factory.recoverers) {
|
||||
registerRecoverer(recoverer)
|
||||
}
|
||||
}
|
||||
|
||||
def registerSingleton(factory: ItemFactory): Unit = {
|
||||
_groups += SingletonItemGroup(factory.name, factory)
|
||||
registerItemFactoryRecoverers(factory)
|
||||
}
|
||||
|
||||
def registerTiered(name: String, tiers: IterableOnce[Tier])(factory: Tier => ItemFactory): Unit = {
|
||||
val group = TieredItemGroup(name, tiers.iterator.map(tier => (tier, factory(tier))).toSeq)
|
||||
_groups += group
|
||||
|
||||
for ((_, factory) <- group.factories) {
|
||||
registerItemFactoryRecoverers(factory)
|
||||
}
|
||||
}
|
||||
|
||||
def registerExtendedTiered(name: String, tiers: IterableOnce[ExtendedTier])(
|
||||
factory: ExtendedTier => ItemFactory
|
||||
): Unit = {
|
||||
val group = ExtendedTieredItemGroup(name, tiers.iterator.map(tier => (tier, factory(tier))).toSeq)
|
||||
_groups += group
|
||||
|
||||
for ((_, factory) <- group.factories) {
|
||||
registerItemFactoryRecoverers(factory)
|
||||
}
|
||||
}
|
||||
|
||||
def registerArbitrary(name: String, icon: IconDef, factories: IterableOnce[(String, ItemFactory)]): Unit = {
|
||||
val group = ArbitraryItemGroup(name, icon, factories.iterator.toSeq)
|
||||
_groups += group
|
||||
|
||||
for ((_, factory) <- group.factories) {
|
||||
registerItemFactoryRecoverers(factory)
|
||||
}
|
||||
}
|
||||
|
||||
def groups: Iterable[ItemGroup] = _groups
|
||||
|
||||
/** Attempts to recover an [[Item]] from `source`.
|
||||
*
|
||||
* Checks superclasses and traits while looking for a recoverer.
|
||||
*/
|
||||
def recover[A](source: A): Option[Item] = {
|
||||
linearizationOrder(source.getClass.asInstanceOf[Class[_]])
|
||||
.flatMap(_recoverers.get)
|
||||
.map(_.asInstanceOf[ItemRecoverer[_ >: A, _ <: Item]].recover(source))
|
||||
.nextOption()
|
||||
}
|
||||
|
||||
sealed trait ItemGroup {
|
||||
def name: String
|
||||
}
|
||||
|
||||
case class SingletonItemGroup(name: String, factory: ItemFactory) extends ItemGroup
|
||||
|
||||
case class TieredItemGroup(name: String, factories: Seq[(Tier, ItemFactory)]) extends ItemGroup
|
||||
|
||||
case class ExtendedTieredItemGroup(name: String, factories: Seq[(ExtendedTier, ItemFactory)]) extends ItemGroup
|
||||
|
||||
case class ArbitraryItemGroup(name: String, icon: IconDef, factories: Seq[(String, ItemFactory)]) extends ItemGroup
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
registerTiered("CPU", Tier.One to Tier.Three)(new CpuItem.Factory(_))
|
||||
registerTiered("APU", Tier.Two to Tier.Creative)(tier => new ApuItem.Factory(tier.saturatingSub(1)))
|
||||
|
||||
registerExtendedTiered("Memory", ExtendedTier.One to ExtendedTier.ThreeHalf)(new MemoryItem.Factory(_))
|
||||
|
||||
registerTiered("HDD", Tier.One to Tier.Three)(new HddItem.Factory(managed = true, _))
|
||||
|
||||
registerArbitrary(
|
||||
"Floppy",
|
||||
FloppyItem.Factory.Empty.icon,
|
||||
Loot.Floppies.iterator
|
||||
.map(new FloppyItem.Factory.Loot(_))
|
||||
.map(factory => (factory.name, factory)) ++ Some(("Empty", FloppyItem.Factory.Empty))
|
||||
)
|
||||
|
||||
registerArbitrary(
|
||||
"EEPROM",
|
||||
EepromItem.Factory.Empty.icon,
|
||||
Loot.Eeproms.iterator
|
||||
.map(new EepromItem.Factory.Loot(_))
|
||||
.map(factory => (factory.name, factory)) ++ Some(("Empty", EepromItem.Factory.Empty))
|
||||
)
|
||||
|
||||
registerTiered("Graphics Card", Tier.One to Tier.Three)(new GraphicsCardItem.Factory(_))
|
||||
registerSingleton(NetworkCardItem.Factory)
|
||||
registerTiered("Wireless Net. Card", Tier.One to Tier.Two) {
|
||||
case Tier.One => WirelessNetworkCardItem.Tier1.Factory
|
||||
case Tier.Two => WirelessNetworkCardItem.Tier2.Factory
|
||||
}
|
||||
registerSingleton(LinkedCardItem.Factory)
|
||||
registerSingleton(InternetCardItem.Factory)
|
||||
registerTiered("Redstone Card", Tier.One to Tier.Two) {
|
||||
case Tier.One => RedstoneCardItem.Tier1.Factory
|
||||
case Tier.Two => RedstoneCardItem.Tier2.Factory
|
||||
}
|
||||
registerTiered("Data Card", Tier.One to Tier.Three) {
|
||||
case Tier.One => DataCardItem.Tier1.Factory
|
||||
case Tier.Two => DataCardItem.Tier2.Factory
|
||||
case Tier.Three => DataCardItem.Tier3.Factory
|
||||
}
|
||||
registerSingleton(SoundCardItem.Factory)
|
||||
registerSingleton(SelfDestructingCardItem.Factory)
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package ocelot.desktop.inventory
|
||||
|
||||
import ocelot.desktop.inventory.item._
|
||||
import ocelot.desktop.util.ReflectionUtils.linearizationOrder
|
||||
import totoro.ocelot.brain.entity
|
||||
import totoro.ocelot.brain.entity.sound_card.SoundCard
|
||||
import totoro.ocelot.brain.entity.traits.Floppy
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.reflect.{ClassTag, classTag}
|
||||
|
||||
/**
|
||||
* A registry of all available [[ItemRecoverer item recoverers]].
|
||||
*/
|
||||
object Recoverers {
|
||||
private val recoverers = mutable.HashMap.empty[Class[_], ItemRecoverer[_]]
|
||||
|
||||
/**
|
||||
* Registers a recoverer for [[S]].
|
||||
*/
|
||||
def register[S: ClassTag](recoverer: ItemRecoverer[S]): Unit = {
|
||||
recoverers(classTag[S].runtimeClass) = recoverer
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to recover an [[Item]] from `source`.
|
||||
*
|
||||
* Checks superclasses and traits while looking for a recoverer.
|
||||
*/
|
||||
def recover[A](source: A): Option[Item] = {
|
||||
linearizationOrder(source.getClass.asInstanceOf[Class[_]])
|
||||
.flatMap(recoverers.get)
|
||||
.map(_.asInstanceOf[ItemRecoverer[A]].recover(source))
|
||||
.nextOption()
|
||||
}
|
||||
|
||||
register[entity.APU](ApuItem.Factory)
|
||||
register[entity.CPU](CpuItem.Factory)
|
||||
register[entity.DataCard.Tier1](DataCardItem.Tier1.Factory)
|
||||
register[entity.DataCard.Tier2](DataCardItem.Tier2.Factory)
|
||||
register[entity.DataCard.Tier3](DataCardItem.Tier3.Factory)
|
||||
register[entity.EEPROM](EepromItem.Factory)
|
||||
register[Floppy](FloppyItem.Factory)
|
||||
register[entity.GraphicsCard](GraphicsCardItem.Factory)
|
||||
register[entity.HDDManaged](HddItem.Factory.ManagedRecoverer)
|
||||
register[entity.HDDUnmanaged](HddItem.Factory.UnmangedRecoverer)
|
||||
register[entity.InternetCard](InternetCardItem.Factory)
|
||||
register[entity.LinkedCard](LinkedCardItem.Factory)
|
||||
register[entity.Memory](MemoryItem.Factory)
|
||||
register[entity.NetworkCard](NetworkCardItem.Factory)
|
||||
register[entity.Redstone.Tier1](RedstoneCardItem.Tier1.Factory)
|
||||
register[entity.Redstone.Tier2](RedstoneCardItem.Tier2.Factory)
|
||||
register[entity.SelfDestructingCard](SelfDestructingCardItem.Factory)
|
||||
register[SoundCard](SoundCardItem.Factory)
|
||||
register[entity.WirelessNetworkCard.Tier1](WirelessNetworkCardItem.Tier1.Factory)
|
||||
register[entity.WirelessNetworkCard.Tier2](WirelessNetworkCardItem.Tier2.Factory)
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import scala.annotation.tailrec
|
||||
*
|
||||
* When a new [[Item]] is added to the Desktop inventory, its [[ComponentItem.component]] is added to
|
||||
* the [[brainInventory]]. When a new [[Entity]] is added to the [[brainInventory]], an [[Item]] is recovered from it
|
||||
* by using an appropriate [[ItemRecoverer]] from [[Recoverers the registry]].
|
||||
* by using an appropriate [[ItemRecoverer]] from [[Items the registry]].
|
||||
*
|
||||
* While synchronizing, relies on the convergence of changes, but guards against stack overflows
|
||||
* by limiting the recursion depth.
|
||||
@@ -170,7 +170,7 @@ trait SyncedInventory extends PersistedInventory with Logging {
|
||||
|
||||
case SyncDirection.BrainToDesktop =>
|
||||
val item = brainInventory.inventory(slotIndex).get match {
|
||||
case Some(entity) => Recoverers.recover(entity) match {
|
||||
case Some(entity) => Items.recover(entity) match {
|
||||
case Some(item) => Some(item.asInstanceOf[I])
|
||||
|
||||
case None =>
|
||||
|
||||
@@ -26,11 +26,7 @@ object ApuItem {
|
||||
override def icon: IconDef = Icons.Apu(_tier)
|
||||
|
||||
override def build(): ApuItem = new ApuItem(new APU(_tier))
|
||||
}
|
||||
|
||||
object Factory extends ItemRecoverer[APU] {
|
||||
override type I = ApuItem
|
||||
|
||||
override def recover(source: APU): ApuItem = new ApuItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new ApuItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,7 @@ object CpuItem {
|
||||
override def icon: IconDef = Icons.Cpu(_tier)
|
||||
|
||||
override def build(): CpuItem = new CpuItem(new CPU(_tier))
|
||||
}
|
||||
|
||||
object Factory extends ItemRecoverer[CPU] {
|
||||
override type I = CpuItem
|
||||
|
||||
override def recover(source: CPU): CpuItem = new CpuItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new CpuItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ object DataCardItem {
|
||||
}
|
||||
|
||||
object Tier1 {
|
||||
object Factory extends Factory with ItemRecoverer[DataCard.Tier1] {
|
||||
object Factory extends Factory {
|
||||
override type I = DataCardItem.Tier1
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -33,7 +33,7 @@ object DataCardItem {
|
||||
|
||||
override def build(): DataCardItem.Tier1 = new DataCardItem.Tier1(new DataCard.Tier1)
|
||||
|
||||
override def recover(source: DataCard.Tier1): DataCardItem.Tier1 = new DataCardItem.Tier1(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new DataCardItem.Tier1(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ object DataCardItem {
|
||||
}
|
||||
|
||||
object Tier2 {
|
||||
object Factory extends Factory with ItemRecoverer[DataCard.Tier2] {
|
||||
object Factory extends Factory {
|
||||
override type I = DataCardItem.Tier2
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -53,7 +53,7 @@ object DataCardItem {
|
||||
|
||||
override def build(): DataCardItem.Tier2 = new DataCardItem.Tier2(new DataCard.Tier2)
|
||||
|
||||
override def recover(source: DataCard.Tier2): DataCardItem.Tier2 = new DataCardItem.Tier2(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new DataCardItem.Tier2(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ object DataCardItem {
|
||||
}
|
||||
|
||||
object Tier3 {
|
||||
object Factory extends Factory with ItemRecoverer[DataCard.Tier3] {
|
||||
object Factory extends Factory {
|
||||
override type I = DataCardItem.Tier3
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -73,7 +73,7 @@ object DataCardItem {
|
||||
|
||||
override def build(): DataCardItem.Tier3 = new DataCardItem.Tier3(new DataCard.Tier3)
|
||||
|
||||
override def recover(source: DataCard.Tier3): DataCardItem.Tier3 = new DataCardItem.Tier3(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new DataCardItem.Tier3(_)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,13 +95,11 @@ object EepromItem {
|
||||
override def tier: Option[Tier] = None
|
||||
|
||||
override def icon: IconDef = Icons.Eeprom
|
||||
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new EepromItem(_)))
|
||||
}
|
||||
|
||||
object Factory extends ItemRecoverer[EEPROM] {
|
||||
override type I = EepromItem
|
||||
|
||||
override def recover(source: EEPROM): EepromItem = new EepromItem(source)
|
||||
|
||||
object Factory {
|
||||
class Loot(factory: EEPROMFactory) extends Factory {
|
||||
override def name: String = factory.label
|
||||
|
||||
|
||||
@@ -73,13 +73,11 @@ object FloppyItem {
|
||||
override def tier: Option[Tier] = None
|
||||
|
||||
override def icon: IconDef = Icons.FloppyDisk(color)
|
||||
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new FloppyItem(_)))
|
||||
}
|
||||
|
||||
object Factory extends ItemRecoverer[Floppy] {
|
||||
override type I = FloppyItem
|
||||
|
||||
override def recover(source: Floppy): FloppyItem = new FloppyItem(source)
|
||||
|
||||
object Factory {
|
||||
class Loot(factory: FloppyFactory) extends Factory(Some(factory.name), factory.color, managed = true) {
|
||||
override def name: String = factory.name
|
||||
|
||||
|
||||
@@ -24,11 +24,7 @@ object GraphicsCardItem {
|
||||
override val icon: IconDef = Icons.GraphicsCard(_tier)
|
||||
|
||||
override def build(): GraphicsCardItem = new GraphicsCardItem(new GraphicsCard(_tier))
|
||||
}
|
||||
|
||||
object Factory extends ItemRecoverer[GraphicsCard] {
|
||||
override type I = GraphicsCardItem
|
||||
|
||||
override def recover(source: GraphicsCard): GraphicsCardItem = new GraphicsCardItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new GraphicsCardItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,19 +74,10 @@ object HddItem {
|
||||
if (managed) Hdd.Managed(new HDDManaged(_tier))
|
||||
else Hdd.Unmanaged(new HDDUnmanaged(_tier)),
|
||||
)
|
||||
}
|
||||
|
||||
object Factory {
|
||||
object ManagedRecoverer extends ItemRecoverer[HDDManaged] {
|
||||
override type I = HddItem
|
||||
|
||||
override def recover(source: HDDManaged): HddItem = new HddItem(Hdd.Managed(source))
|
||||
}
|
||||
|
||||
object UnmangedRecoverer extends ItemRecoverer[HDDUnmanaged] {
|
||||
override type I = HddItem
|
||||
|
||||
override def recover(source: HDDUnmanaged): HddItem = new HddItem(Hdd.Unmanaged(source))
|
||||
}
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Seq(
|
||||
ItemRecoverer((hdd: HDDManaged) => new HddItem(Hdd.Managed(hdd))),
|
||||
ItemRecoverer((hdd: HDDUnmanaged) => new HddItem(Hdd.Unmanaged(hdd))),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class InternetCardItem(val card: InternetCard) extends Item with ComponentItem w
|
||||
}
|
||||
|
||||
object InternetCardItem {
|
||||
object Factory extends ItemFactory with ItemRecoverer[InternetCard] {
|
||||
object Factory extends ItemFactory {
|
||||
override type I = InternetCardItem
|
||||
|
||||
override def itemClass: Class[InternetCardItem] = classOf
|
||||
@@ -28,6 +28,6 @@ object InternetCardItem {
|
||||
|
||||
override def build(): InternetCardItem = new InternetCardItem(new InternetCard)
|
||||
|
||||
override def recover(source: InternetCard): InternetCardItem = new InternetCardItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new InternetCardItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class LinkedCardItem(val linkedCard: LinkedCard) extends Item with ComponentItem
|
||||
}
|
||||
|
||||
object LinkedCardItem {
|
||||
object Factory extends ItemFactory with ItemRecoverer[LinkedCard] {
|
||||
object Factory extends ItemFactory {
|
||||
override type I = LinkedCardItem
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -53,6 +53,6 @@ object LinkedCardItem {
|
||||
|
||||
override def build(): LinkedCardItem = new LinkedCardItem(new LinkedCard)
|
||||
|
||||
override def recover(source: LinkedCard): LinkedCardItem = new LinkedCardItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new LinkedCardItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,7 @@ object MemoryItem {
|
||||
override def icon: IconDef = Icons.Memory(memoryTier)
|
||||
|
||||
override def build(): MemoryItem = new MemoryItem(new Memory(memoryTier))
|
||||
}
|
||||
|
||||
object Factory extends ItemRecoverer[Memory] {
|
||||
override type I = MemoryItem
|
||||
|
||||
override def recover(source: Memory): MemoryItem = new MemoryItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new MemoryItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class NetworkCardItem(val networkCard: NetworkCard) extends Item with ComponentI
|
||||
}
|
||||
|
||||
object NetworkCardItem {
|
||||
object Factory extends ItemFactory with ItemRecoverer[NetworkCard] {
|
||||
object Factory extends ItemFactory {
|
||||
override type I = NetworkCardItem
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -26,6 +26,6 @@ object NetworkCardItem {
|
||||
|
||||
override def build(): NetworkCardItem = new NetworkCardItem(new NetworkCard)
|
||||
|
||||
override def recover(source: NetworkCard): NetworkCardItem = new NetworkCardItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new NetworkCardItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ object RedstoneCardItem {
|
||||
}
|
||||
|
||||
class Tier1(val redstoneCard: Redstone.Tier1) extends RedstoneCardItem {
|
||||
protected val redstoneIoWindow: WindowProvider = new WindowProvider {
|
||||
private val redstoneIoWindow: WindowProvider = new WindowProvider {
|
||||
override val windowEntryLabel: String = "Redstone I/O"
|
||||
|
||||
override def makeWindow(): Window = new Redstone1Window(redstoneCard)
|
||||
@@ -42,7 +42,7 @@ object RedstoneCardItem {
|
||||
}
|
||||
|
||||
object Tier1 {
|
||||
object Factory extends Factory with ItemRecoverer[Redstone.Tier1] {
|
||||
object Factory extends Factory {
|
||||
override type I = RedstoneCardItem.Tier1
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -51,7 +51,7 @@ object RedstoneCardItem {
|
||||
|
||||
override def build(): RedstoneCardItem.Tier1 = new RedstoneCardItem.Tier1(new Redstone.Tier1)
|
||||
|
||||
override def recover(source: Redstone.Tier1): RedstoneCardItem.Tier1 = new RedstoneCardItem.Tier1(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new RedstoneCardItem.Tier1(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ object RedstoneCardItem {
|
||||
}
|
||||
|
||||
object Tier2 {
|
||||
object Factory extends Factory with ItemRecoverer[Redstone.Tier2] {
|
||||
object Factory extends Factory {
|
||||
override type I = RedstoneCardItem.Tier2
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -82,7 +82,7 @@ object RedstoneCardItem {
|
||||
|
||||
override def build(): RedstoneCardItem.Tier2 = new RedstoneCardItem.Tier2(new Redstone.Tier2)
|
||||
|
||||
override def recover(source: Redstone.Tier2): RedstoneCardItem.Tier2 = new RedstoneCardItem.Tier2(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new RedstoneCardItem.Tier2(_)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class SelfDestructingCardItem(val card: SelfDestructingCard)
|
||||
}
|
||||
|
||||
object SelfDestructingCardItem {
|
||||
object Factory extends ItemFactory with ItemRecoverer[SelfDestructingCard] {
|
||||
object Factory extends ItemFactory {
|
||||
override type I = SelfDestructingCardItem
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -33,6 +33,6 @@ object SelfDestructingCardItem {
|
||||
|
||||
override def build(): SelfDestructingCardItem = new SelfDestructingCardItem(new SelfDestructingCard)
|
||||
|
||||
override def recover(source: SelfDestructingCard): SelfDestructingCardItem = new SelfDestructingCardItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new SelfDestructingCardItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class SoundCardItem(val soundCard: SoundCard) extends Item with ComponentItem wi
|
||||
}
|
||||
|
||||
object SoundCardItem {
|
||||
object Factory extends ItemFactory with ItemRecoverer[SoundCard] {
|
||||
object Factory extends ItemFactory {
|
||||
override type I = SoundCardItem
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -42,6 +42,6 @@ object SoundCardItem {
|
||||
|
||||
override def build(): SoundCardItem = new SoundCardItem(new SoundCard)
|
||||
|
||||
override def recover(source: SoundCard): SoundCardItem = new SoundCardItem(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new SoundCardItem(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ object WirelessNetworkCardItem {
|
||||
}
|
||||
|
||||
object Tier1 {
|
||||
object Factory extends Factory with ItemRecoverer[WirelessNetworkCard.Tier1] {
|
||||
object Factory extends Factory {
|
||||
override type I = WirelessNetworkCardItem.Tier1
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -39,8 +39,7 @@ object WirelessNetworkCardItem {
|
||||
override def build(): WirelessNetworkCardItem.Tier1 =
|
||||
new WirelessNetworkCardItem.Tier1(new WirelessNetworkCard.Tier1)
|
||||
|
||||
override def recover(source: WirelessNetworkCard.Tier1): WirelessNetworkCardItem.Tier1 =
|
||||
new WirelessNetworkCardItem.Tier1(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new WirelessNetworkCardItem.Tier1(_)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +48,7 @@ object WirelessNetworkCardItem {
|
||||
}
|
||||
|
||||
object Tier2 {
|
||||
object Factory extends Factory with ItemRecoverer[WirelessNetworkCard.Tier2] {
|
||||
object Factory extends Factory {
|
||||
override type I = WirelessNetworkCardItem.Tier2
|
||||
|
||||
override val itemClass: Class[I] = classOf
|
||||
@@ -59,8 +58,7 @@ object WirelessNetworkCardItem {
|
||||
override def build(): WirelessNetworkCardItem.Tier2 =
|
||||
new WirelessNetworkCardItem.Tier2(new WirelessNetworkCard.Tier2)
|
||||
|
||||
override def recover(source: WirelessNetworkCard.Tier2): WirelessNetworkCardItem.Tier2 =
|
||||
new WirelessNetworkCardItem.Tier2(source)
|
||||
override def recoverers: Iterable[ItemRecoverer[_, _]] = Some(ItemRecoverer(new WirelessNetworkCardItem.Tier2(_)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,145 +1,63 @@
|
||||
package ocelot.desktop.ui.widget.slot
|
||||
|
||||
import ocelot.desktop.inventory.item._
|
||||
import ocelot.desktop.inventory.{Item, ItemFactory}
|
||||
import ocelot.desktop.graphics.IconDef
|
||||
import ocelot.desktop.inventory.Items.{ArbitraryItemGroup, ExtendedTieredItemGroup, SingletonItemGroup, TieredItemGroup}
|
||||
import ocelot.desktop.inventory._
|
||||
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry, ContextMenuSubmenu}
|
||||
import totoro.ocelot.brain.loot.Loot
|
||||
import totoro.ocelot.brain.util.ExtendedTier.ExtendedTier
|
||||
import totoro.ocelot.brain.util.{ExtendedTier, Tier}
|
||||
import totoro.ocelot.brain.util.Tier.Tier
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
class ItemChooser[I <: Item](slot: SlotWidget[I]) extends ContextMenu {
|
||||
for (entryFactory <- ItemChooser.Factories; entry <- entryFactory.make(slot)) {
|
||||
addEntry(entry)
|
||||
import ItemChooser._
|
||||
|
||||
private def makeMenuEntry(factory: ItemFactory, label: String): ContextMenuEntry = {
|
||||
ContextMenuEntry(label, icon = Some(factory.icon)) {
|
||||
slot.item = factory.build().asInstanceOf[I]
|
||||
}
|
||||
}
|
||||
|
||||
private def addSubmenu[T: HasLabel](
|
||||
name: String,
|
||||
factories: Seq[(T, ItemFactory)],
|
||||
icon: Option[IconDef] = None
|
||||
): Unit = {
|
||||
val tierLabel = implicitly[HasLabel[T]].label _
|
||||
|
||||
val acceptedFactories = factories.iterator.filter(p => slot.isItemAccepted(p._2)).toSeq
|
||||
|
||||
if (acceptedFactories.nonEmpty) {
|
||||
addEntry(
|
||||
new ContextMenuSubmenu(name, icon = Some(icon.getOrElse(acceptedFactories.last._2.icon))) {
|
||||
for ((tier, factory) <- acceptedFactories) {
|
||||
addEntry(makeMenuEntry(factory, tierLabel(tier)))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for (group <- Items.groups) {
|
||||
group match {
|
||||
case SingletonItemGroup(name, factory) =>
|
||||
if (slot.isItemAccepted(factory)) {
|
||||
addEntry(makeMenuEntry(factory, name))
|
||||
}
|
||||
|
||||
case TieredItemGroup(name, factories) => addSubmenu(name, factories)
|
||||
|
||||
case ExtendedTieredItemGroup(name, factories) => addSubmenu(name, factories)
|
||||
|
||||
case ArbitraryItemGroup(name, icon, factories) => addSubmenu(name, factories, Some(icon))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object ItemChooser {
|
||||
private trait EntryFactory {
|
||||
def make[I <: Item](slot: SlotWidget[I]): Option[ContextMenuEntry]
|
||||
private trait HasLabel[A] {
|
||||
def label(value: A): String
|
||||
}
|
||||
|
||||
private def makeMenuEntry[I <: Item](slot: SlotWidget[I], factory: ItemFactory, label: String): ContextMenuEntry =
|
||||
ContextMenuEntry(label, icon = Some(factory.icon)) {
|
||||
slot.item = factory.build().asInstanceOf[I]
|
||||
}
|
||||
|
||||
private case class SingletonEntryFactory(factory: ItemFactory) extends EntryFactory {
|
||||
override def make[I <: Item](slot: SlotWidget[I]): Option[ContextMenuEntry] = {
|
||||
Option.when(slot.isItemAccepted(factory)) {
|
||||
makeMenuEntry(slot, factory, factory.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private case class TieredEntryFactory[T: TierLike](
|
||||
name: String,
|
||||
tiers: Iterable[T],
|
||||
)(
|
||||
factoryMaker: T => ItemFactory,
|
||||
) extends EntryFactory {
|
||||
|
||||
override def make[I <: Item](slot: SlotWidget[I]): Option[ContextMenuEntry] = {
|
||||
val tierLabel = implicitly[TierLike[T]].label _
|
||||
|
||||
val factories = tiers
|
||||
.map(tier => (tier, factoryMaker(tier)))
|
||||
.filter(p => slot.isItemAccepted(p._2))
|
||||
.toArray
|
||||
|
||||
Option.unless(factories.isEmpty) {
|
||||
new ContextMenuSubmenu(name, icon = Some(factories.last._2.icon)) {
|
||||
for ((tier, factory) <- factories) {
|
||||
addEntry(makeMenuEntry(slot, factory, tierLabel(tier)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private trait TierLike[A] {
|
||||
def label(tier: A): String
|
||||
}
|
||||
|
||||
private implicit val TierIsTierLike: TierLike[Tier] = _.label
|
||||
private implicit val ExtendedTierIsTierLike: TierLike[ExtendedTier] = _.label
|
||||
|
||||
private object FloppyEntryFactory extends EntryFactory {
|
||||
override def make[I <: Item](slot: SlotWidget[I]): Option[ContextMenuEntry] = {
|
||||
Option.when(slot.isItemAccepted(FloppyItem.Factory.Empty)) {
|
||||
new ContextMenuSubmenu("Floppy", icon = Some(FloppyItem.Factory.Empty.icon)) {
|
||||
def addEntry(factory: FloppyItem.Factory, label: String): Unit = {
|
||||
addEntry(makeMenuEntry(slot, factory, label))
|
||||
}
|
||||
|
||||
def addEntry(factory: FloppyItem.Factory): Unit = {
|
||||
addEntry(factory, factory.name)
|
||||
}
|
||||
|
||||
for (lootFactory <- Loot.Floppies) {
|
||||
addEntry(new FloppyItem.Factory.Loot(lootFactory))
|
||||
}
|
||||
|
||||
addEntry(FloppyItem.Factory.Empty, "Empty")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object EepromEntryFactory extends EntryFactory {
|
||||
override def make[I <: Item](slot: SlotWidget[I]): Option[ContextMenuEntry] = {
|
||||
Option.when(slot.isItemAccepted(EepromItem.Factory.Empty)) {
|
||||
new ContextMenuSubmenu("EEPROM", icon = Some(EepromItem.Factory.Empty.icon)) {
|
||||
def addEntry(factory: EepromItem.Factory, label: String): Unit = {
|
||||
addEntry(makeMenuEntry(slot, factory, label))
|
||||
}
|
||||
|
||||
def addEntry(factory: EepromItem.Factory): Unit = {
|
||||
addEntry(factory, factory.name)
|
||||
}
|
||||
|
||||
for (lootFactory <- Loot.Eeproms) {
|
||||
addEntry(new EepromItem.Factory.Loot(lootFactory))
|
||||
}
|
||||
|
||||
addEntry(EepromItem.Factory.Empty, "Empty")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Entry factories //
|
||||
private val Factories = ArrayBuffer.empty[EntryFactory]
|
||||
|
||||
Factories += TieredEntryFactory("CPU", Tier.One to Tier.Three)(new CpuItem.Factory(_))
|
||||
Factories += TieredEntryFactory("APU", Tier.One to Tier.Three)(new ApuItem.Factory(_))(_.saturatingAdd(1).label)
|
||||
|
||||
Factories += TieredEntryFactory("Memory", ExtendedTier.One to ExtendedTier.ThreeHalf)(new MemoryItem.Factory(_))
|
||||
|
||||
// TODO: unmanaged
|
||||
Factories += TieredEntryFactory("HDD", Tier.One to Tier.Three)(new HddItem.Factory(managed = true, _))
|
||||
Factories += FloppyEntryFactory
|
||||
Factories += EepromEntryFactory
|
||||
|
||||
Factories += TieredEntryFactory("Graphics Card", Tier.One to Tier.Three)(new GraphicsCardItem.Factory(_))
|
||||
Factories += SingletonEntryFactory(NetworkCardItem.Factory)
|
||||
Factories += TieredEntryFactory("Wireless Net. Card", Tier.One to Tier.Two) {
|
||||
case Tier.One => WirelessNetworkCardItem.Tier1.Factory
|
||||
case Tier.Two => WirelessNetworkCardItem.Tier2.Factory
|
||||
}
|
||||
Factories += SingletonEntryFactory(LinkedCardItem.Factory)
|
||||
Factories += SingletonEntryFactory(InternetCardItem.Factory)
|
||||
Factories += TieredEntryFactory("Redstone Card", Tier.One to Tier.Two) {
|
||||
case Tier.One => RedstoneCardItem.Tier1.Factory
|
||||
case Tier.Two => RedstoneCardItem.Tier2.Factory
|
||||
}
|
||||
Factories += TieredEntryFactory("Data Card", Tier.One to Tier.Three) {
|
||||
case Tier.One => DataCardItem.Tier1.Factory
|
||||
case Tier.Two => DataCardItem.Tier2.Factory
|
||||
case Tier.Three => DataCardItem.Tier3.Factory
|
||||
}
|
||||
Factories += SingletonEntryFactory(SoundCardItem.Factory)
|
||||
Factories += SingletonEntryFactory(SelfDestructingCardItem.Factory)
|
||||
private implicit val TierHasLabel: HasLabel[Tier] = _.label
|
||||
private implicit val ExtendedTierHasLabel: HasLabel[ExtendedTier] = _.label
|
||||
private implicit val StringHasLabel: HasLabel[String] = identity
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user