InventoryService class

Generic slot-based inventory (consumables + equipment) — item stack rules and rarity live in the caller-supplied itemCatalog; this service only knows about slots/quantities/equipped flags and the invariants around them. grant/consume follow the same idempotent-ledger pattern as EconomyWallet (FEAT-31)/RewardTransactionPipeline (FEAT-42): a transactionId repeated (even across a restart) is a no-op, and every mutating call runs under AsyncActionGuard.runExclusive so concurrent calls serialize instead of racing.

A grant/consume call taking several InventoryLines applies them atomically — if any line would fail (capacity exceeded on grant, insufficient quantity on consume), none of the lines mutate the inventory, not just the failing one.

Inheritance
  • Object
  • GetLifeCycle
  • DisposableInterface
  • GetxService
  • InventoryService

Constructors

InventoryService({required StorageService storage, required Map<String, ItemDefinition> itemCatalog, int capacity = 40, AsyncActionGuard? guard, String? storageKey, int transactionCapacity = 200})

Properties

capacity → int
final
hashCode → int
The hash code for this object.
no setterinherited
initialized → bool
Checks whether the controller has already been initialized.
no setterinherited
isClosed → bool
Checks whether the controller has already been closed.
no setterinherited
onDelete → InternalFinalCallback<void>
Internal callback that starts the cycle of this controller.
finalinherited
onStart → InternalFinalCallback<void>
Called at the exact moment the widget is allocated in memory. It uses an internal "callable" type, to avoid any @overrides in subclases. This method should be internal and is required to define the lifetime cycle of the subclass.
finalinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
snapshot → Rx<InventorySnapshot>
final
storage → StorageService
final
transactionCapacity → int
final

Methods

$configureLifeCycle() → void
inherited
consume({required List<InventoryLine> lines, required String transactionId}) → Future<SdkResult<InventorySnapshot>>
Consumes lines under transactionId. Every line's quantity is checked against the current total before any mutation — if any line is short, nothing is consumed (atomic). Consumes from the lowest-slotId stack of a matching item first; a stack emptied by this is removed.
grant({required List<InventoryLine> lines, required String transactionId}) → Future<SdkResult<InventorySnapshot>>
Grants lines under transactionId. Fills existing under-capacity stacks of the same item first, then creates new slots (up to capacity) for the remainder — if there isn't room for every line, the whole call is rejected and nothing is mutated (atomic).
moveSlot({required int fromSlotId, required int toSlotId}) → Future<SdkResult<InventorySnapshot>>
Swaps the display-order position of the slots fromSlotId/toSlotId — a pure reorder, no effect on quantity/equipped state.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onClose() → void
Called before onDelete method. onClose might be used to dispose resources used by the controller. Like closing events, or streams before the controller is destroyed. Or dispose objects that can potentially create some memory leaks, like TextEditingControllers, AnimationControllers. Might be useful as well to persist some data on disk.
inherited
onInit() → void
Called immediately after the widget is allocated in memory. You might use this to initialize something for the controller.
override
onReady() → void
Called 1 frame after onInit(). It is the perfect place to enter navigation events, like snackbar, dialogs, or a new route, or async request.
inherited
previewGrant({required List<InventoryLine> lines}) → SdkResult<InventorySnapshot>
Computes what grant WOULD do for lines against the CURRENT inventory state, without mutating or persisting anything (FEAT-96). Does not consult the idempotency ledger — a preview isn't tied to any transactionId yet, so "already applied" isn't a meaningful concept here; grant itself still checks it when the plan is actually executed.
setEquipped({required int slotId, required bool equipped}) → Future<SdkResult<InventorySnapshot>>
Sets InventorySlot.equipped on slotId — rejected if the slot doesn't exist or its item isn't ItemDefinition.equippable. Naturally idempotent (no transaction id needed): calling this twice with the same equipped value is a no-op the second time.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Properties

maybe → InventoryService?
no setter