Skip to content

Commit 2ea725d

Browse files
committed
internal refactor Inventory
1 parent 17bc460 commit 2ea725d

File tree

2 files changed

+56
-44
lines changed

2 files changed

+56
-44
lines changed

fxgl-gameplay/src/main/kotlin/com/almasb/fxgl/inventory/Inventory.kt

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class Inventory<T>(
9696
* Add [item] to inventory, dynamically creating stacks based on [config].
9797
* If [item] (as checked by hashCode()) is already present, then its quantity is increased by [quantity].
9898
*
99-
* @return false if could not add item, otherwise true
99+
* @return false if could not add item and no modifications were made, otherwise true
100100
*/
101101
@JvmOverloads fun add(
102102
item: T,
@@ -105,13 +105,14 @@ class Inventory<T>(
105105
): Boolean {
106106

107107
// already in inventory, just increment quantity
108-
if (item in itemsData)
108+
if (hasItem(item))
109109
return incrementQuantity(item, quantity)
110110

111111
// can't add because inventory is full
112112
if (isFull)
113113
return false
114114

115+
// TODO: if == 0?
115116
// adding a new item, so check if quantity > 0
116117
if (quantity < 0) {
117118
log.warning("Attempted to add a new item with negative quantity. Ignoring")
@@ -124,14 +125,15 @@ class Inventory<T>(
124125
if (numStacksNeeded > numFreeStacks)
125126
return false
126127

127-
// capacity-wise we are good, add new item
128+
// capacity-wise we are good, add new item will succeed
128129

129130
val data = ItemData(item).also {
130131
it.name = config.name
131132
it.description = config.description
132133
it.view = config.view
133134
it.maxStackQuantity = config.maxStackQuantity
134135

136+
// TODO: should we delegate to incrementQuantity(item, amount)
135137
it.incrementQuantity(quantity)
136138
}
137139

@@ -153,10 +155,14 @@ class Inventory<T>(
153155
}
154156

155157
/**
156-
* @return true if operation was successful
158+
* @return true if operation was successful, if returns false then no modifications were made
157159
*/
158160
fun incrementQuantity(item: T, amount: Int): Boolean {
159-
if (item !in itemsData) {
161+
// meaningless call
162+
if (amount == 0)
163+
return false
164+
165+
if (!hasItem(item)) {
160166
log.warning("Attempted to increment qty of item that is not in inventory. Ignoring")
161167
return false
162168
}
@@ -172,47 +178,50 @@ class Inventory<T>(
172178
}
173179
}
174180

175-
val isOK = data.incrementQuantity(amount)
181+
// if decrementing, check that we have enough
182+
if (amount < 0 && -amount > data.quantity)
183+
return false
176184

177-
// if all good, update stacks
178-
if (isOK) {
179-
// remove non-existent stacks
180-
items.removeIf { it.userItem == item && it !in data.stacks }
185+
// all checks passed, we will modify this inventory
186+
data.incrementQuantity(amount)
181187

182-
// add newly created stacks
183-
data.stacks.forEach {
184-
if (it !in items) {
185-
items += it
186-
}
187-
}
188+
// remove non-existent stacks
189+
items.removeIf { it.userItem == item && it !in data.stacks }
188190

189-
if (data.quantity == 0) {
190-
itemsData -= item
191+
// add newly created stacks
192+
data.stacks.forEach {
193+
if (it !in items) {
194+
items += it
191195
}
192196
}
193197

194-
return isOK
198+
// if we reached 0, remove item from inventory
199+
if (data.quantity == 0) {
200+
itemsData -= item
201+
}
202+
203+
return true
195204
}
196205

197206
/**
198207
* Transfer [item] with [quantity] amount from [other] to this inventory.
199208
*
200-
* @return true if operation was successful
209+
* @return true if operation was successful, if returns false then no modifications were made to either inventory objects
201210
*/
202211
@JvmOverloads fun transferFrom(other: Inventory<T>, item: T, quantity: Int = 1): Boolean {
203-
if (isFull)
204-
return false
205-
206212
if (!other.hasItem(item))
207213
return false
208214

209215
if (other.getItemQuantity(item) < quantity)
210216
return false
211217

212-
add(item, quantity = quantity)
213-
other.incrementQuantity(item, -quantity)
218+
val isOK = add(item, quantity = quantity)
214219

215-
return true
220+
if (isOK) {
221+
return other.incrementQuantity(item, -quantity)
222+
}
223+
224+
return false
216225
}
217226
}
218227

@@ -249,20 +258,20 @@ class ItemData<T> internal constructor(var userItem: T) {
249258
val quantity: Int
250259
get() = quantityProperty.value
251260

252-
fun incrementQuantity(amount: Int): Boolean {
261+
/**
262+
* This operation is meant to always succeed since checks should be done before the call.
263+
*/
264+
internal fun incrementQuantity(amount: Int) {
253265
if (amount > 0)
254-
return fill(amount)
255-
256-
if (amount < 0)
257-
return deplete(-amount)
258-
259-
return true
266+
fill(amount)
267+
else if (amount < 0)
268+
deplete(-amount)
260269
}
261270

262271
/**
263272
* @param amount - a positive value to increment
264273
*/
265-
private fun fill(amount: Int): Boolean {
274+
private fun fill(amount: Int) {
266275
var left = amount
267276

268277
// fill existing stacks
@@ -300,18 +309,12 @@ class ItemData<T> internal constructor(var userItem: T) {
300309
quantityProperty.value += remainder
301310
}
302311
}
303-
304-
return true
305312
}
306313

307314
/**
308315
* @param amount - a positive value to decrement
309316
*/
310-
private fun deplete(amount: Int): Boolean {
311-
// tried to decrease by more than we have
312-
if (amount > quantityProperty.value)
313-
return false
314-
317+
private fun deplete(amount: Int) {
315318
var left = amount
316319

317320
while (left > 0) {
@@ -330,8 +333,6 @@ class ItemData<T> internal constructor(var userItem: T) {
330333
left = 0
331334
}
332335
}
333-
334-
return true
335336
}
336337
}
337338

fxgl-gameplay/src/test/kotlin/com/almasb/fxgl/inventory/InventoryTest.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ class InventoryTest {
245245

246246
inventory.add("Hello", quantity = 5)
247247

248-
val other = Inventory<String>(6)
248+
val other = Inventory<String>(2)
249249

250250
var result = other.transferFrom(inventory, "Hello", 4)
251251

@@ -257,5 +257,16 @@ class InventoryTest {
257257
result = other.transferFrom(inventory, "Hello", 4)
258258

259259
assertFalse(result)
260+
261+
// fill the inventory
262+
other.add("Hi")
263+
264+
assertTrue(other.isFull)
265+
266+
// but we can still transfer from other since "Hello" stack exists and not limited
267+
result = other.transferFrom(inventory, "Hello", 1)
268+
269+
assertTrue(result)
270+
assertTrue(!inventory.hasItem("Hello"))
260271
}
261272
}

0 commit comments

Comments
 (0)