diff --git a/src/main/scala/ocelot/desktop/inventory/Inventory.scala b/src/main/scala/ocelot/desktop/inventory/Inventory.scala index babcf1b..48ed459 100644 --- a/src/main/scala/ocelot/desktop/inventory/Inventory.scala +++ b/src/main/scala/ocelot/desktop/inventory/Inventory.scala @@ -7,12 +7,16 @@ import totoro.ocelot.brain.event.NodeEvent import scala.collection.mutable -/** Provides an inventory — a collection of [[Item]]s indexed by slots. */ +/** + * Provides an inventory — a collection of [[Item]]s indexed by slots. + */ trait Inventory extends EventAware with Disposable { // parallels totoro.ocelot.brain.entity.traits.Inventory // this is intentional - /** The type of items stored in this inventory. */ + /** + * The type of items stored in this inventory. + */ type I <: Item private type WeakHashSet[A] = mutable.WeakHashMap[A, Unit] @@ -23,21 +27,18 @@ trait Inventory extends EventAware with Disposable { override def dispose(): Unit = { super.dispose() - - for (slot <- inventoryIterator) { - val item = slot.get - slot.remove() - item.foreach(_.dispose()) - } + inventoryIterator.foreach(_.removeAndDispose()) } - /** Called after a new item is added to the inventory. + /** + * Called after a new item is added to the inventory. * * @param slot the slot the item was added to */ def onItemAdded(slot: Slot): Unit - /** Called after an item is removed from the inventory. + /** + * Called after an item is removed from the inventory. * * When the item is replaced by another one, the event are sequenced in the following order: * @@ -52,7 +53,9 @@ trait Inventory extends EventAware with Disposable { */ def onItemRemoved(slot: Slot, removedItem: I, replacedBy: Option[I]): Unit - /** An iterator over all slots occupied in this inventory. */ + /** + * An iterator over all slots occupied in this inventory. + */ def inventoryIterator: Iterator[Slot] = slotItems.keysIterator.map(Slot(_)) def clearInventory(): Unit = { @@ -89,7 +92,9 @@ trait Inventory extends EventAware with Disposable { } } - /** A proxy to access a slot of the inventory. */ + /** + * A proxy to access a slot of the inventory. + */ final class Slot private[Inventory] (val index: Int) { require(index >= 0) @@ -97,27 +102,46 @@ trait Inventory extends EventAware with Disposable { def nonEmpty: Boolean = !isEmpty - /** Inserts the `item` into this slot (replacing the previous item if any). */ + /** + * Inserts the `item` into this slot (replacing the previous item if any). + */ def put(item: inventory.I): Unit = { setSlot(index, Some(item)) } - /** Allows inserting/removing the item in this slot. */ + /** + * Allows inserting/removing the item in this slot. + */ def set(item: Option[inventory.I]): Unit = { setSlot(index, item) } - /** Removes the item contained in this slot if there is one. */ + /** + * Removes the item contained in this slot if there is one. + */ def remove(): Unit = { setSlot(index, None) } - /** The [[Item]] contained in this slot. */ + /** + * Removes the item contained in this slot if there is one, calling the item's [[dispose]] method. + */ + def removeAndDispose(): Unit = { + for (item <- get) { + remove() + item.dispose() + } + } + + /** + * The [[Item]] contained in this slot. + */ def get: Option[inventory.I] = slotItems.get(index) val inventory: Inventory.this.type = Inventory.this - /** Registers an observer to receive item added/removed events. + /** + * Registers an observer to receive item added/removed events. * * @note The inventory keeps a '''weak''' reference to the `observer`. */ @@ -159,7 +183,9 @@ trait Inventory extends EventAware with Disposable { } final object Slot { - /** Creates a proxy to an inventory slot. */ + /** + * Creates a proxy to an inventory slot. + */ def apply(index: Int) = new Slot(index) } @@ -216,13 +242,15 @@ trait Inventory extends EventAware with Disposable { object Inventory { trait SlotObserver { - /** Called after an item was inserted into this slot. + /** + * Called after an item was inserted into this slot. * * @note [[Inventory.onItemAdded]] is called before this method. */ def onItemAdded(): Unit - /** Called after an item was removed from this slot. + /** + * Called after an item was removed from this slot. * * In particular, the slot no longer contains the removed item. * @@ -230,7 +258,9 @@ object Inventory { */ def onItemRemoved(removedItem: Item, replacedBy: Option[Item]): Unit - /** Called when an item contained in this slot sends a notification via [[Item.notifySlot]]. */ + /** + * Called when an item contained in this slot sends a notification via [[Item.notifySlot]]. + */ def onItemNotification(notification: Item.Notification): Unit } } diff --git a/src/main/scala/ocelot/desktop/inventory/PersistedInventory.scala b/src/main/scala/ocelot/desktop/inventory/PersistedInventory.scala index cea5551..68687bc 100644 --- a/src/main/scala/ocelot/desktop/inventory/PersistedInventory.scala +++ b/src/main/scala/ocelot/desktop/inventory/PersistedInventory.scala @@ -104,7 +104,7 @@ trait PersistedInventory extends Inventory with Logging with Persistable { } protected def onSlotLoadFailed(slotIndex: Int): Unit = { - Slot(slotIndex).remove() + Slot(slotIndex).removeAndDispose() } protected def saveEntityItem(slotNbt: NBTTagCompound, item: EntityItem): Unit = { diff --git a/src/main/scala/ocelot/desktop/inventory/SyncedInventory.scala b/src/main/scala/ocelot/desktop/inventory/SyncedInventory.scala index d593725..c6dc3e4 100644 --- a/src/main/scala/ocelot/desktop/inventory/SyncedInventory.scala +++ b/src/main/scala/ocelot/desktop/inventory/SyncedInventory.scala @@ -178,7 +178,7 @@ trait SyncedInventory extends PersistedInventory with EventAware with Logging { ) logger.error("Breaking the loop forcefully by removing the items.") - Slot(slotIndex).remove() + Slot(slotIndex).removeAndDispose() brainInventory.inventory(slotIndex).remove() } else { direction match { diff --git a/src/main/scala/ocelot/desktop/ui/widget/slot/SlotWidget.scala b/src/main/scala/ocelot/desktop/ui/widget/slot/SlotWidget.scala index 88f316f..658e1c1 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/slot/SlotWidget.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/slot/SlotWidget.scala @@ -110,7 +110,7 @@ class SlotWidget[I <: Item](private val slot: Inventory#Slot)(implicit slotItemT item.fillRmbMenu(menu) menu.addEntry( ContextMenuEntry("Remove", IconSource.Delete, SoundSource.InterfaceClickLow) { - slot.remove() + slot.removeAndDispose() } ) } diff --git a/src/main/scala/ocelot/desktop/util/ComputerAware.scala b/src/main/scala/ocelot/desktop/util/ComputerAware.scala index 82698c9..90d9e83 100644 --- a/src/main/scala/ocelot/desktop/util/ComputerAware.scala +++ b/src/main/scala/ocelot/desktop/util/ComputerAware.scala @@ -117,8 +117,11 @@ trait ComputerAware .minByOption(_.slotTier) } - for (item <- items; newSlot <- findBestSlot(item, slots)) { - newSlot.item = item + for (item <- items) { + findBestSlot(item, slots) match{ + case Some(newSlot) => newSlot.item = item + case None => item.dispose() + } } }