1
1
package me .flame .menus .menu ;
2
2
3
+ import com .google .common .base .Preconditions ;
3
4
import com .google .common .collect .ImmutableSet ;
5
+
4
6
import lombok .Setter ;
7
+
5
8
import me .flame .menus .items .MenuItem ;
6
9
import me .flame .menus .menu .iterator .PageIterator ;
7
10
@@ -20,21 +23,21 @@ public final class Page implements Iterable<MenuItem> {
20
23
@ NotNull
21
24
private final PaginatedMenu holder ;
22
25
23
- @ NotNull
24
- private final Map <Integer , MenuItem > itemMap ;
25
-
26
26
@ NotNull
27
27
private final PageIterator iterator = new PageIterator (IterationDirection .HORIZONTAL , this );
28
-
29
- private final int size , rows ;
30
28
31
- private @ Setter boolean dynamicSizing ;
29
+ @ Setter
30
+ private boolean dynamicSizing ;
31
+
32
+ int size , rows ;
33
+
34
+ MenuItem [] itemMap ;
32
35
33
36
private Page (final @ NotNull PaginatedMenu holder ) {
34
37
this .holder = holder ;
35
38
this .size = holder .size ;
36
39
this .rows = holder .rows ;
37
- this .itemMap = new HashMap <>( size ) ;
40
+ this .itemMap = new MenuItem [ size ] ;
38
41
this .dynamicSizing = holder .isDynamicSizing ();
39
42
}
40
43
@@ -51,26 +54,29 @@ private Page(final @NotNull PaginatedMenu holder) {
51
54
*/
52
55
public boolean addItem (@ NotNull final ItemStack ... items ) {
53
56
final List <ItemStack > notAddedItems = new ArrayList <>();
54
- final Set < Integer > occupiedSlots = itemMap . keySet ();
57
+
55
58
56
59
int slot = 0 ;
57
60
for (final ItemStack guiItem : items ) {
58
61
if (slot >= size ) {
62
+ if (rows == 6 ) break ; // save some performance
59
63
notAddedItems .add (guiItem );
60
64
continue ;
61
65
}
62
66
63
- while (occupiedSlots .contains (slot )) {
64
- slot ++;
65
- }
67
+ slot = getSlot (itemMap , slot );
66
68
67
- itemMap .put (slot , MenuItem .of (guiItem ));
69
+ try {
70
+ itemMap [slot ] = MenuItem .of (guiItem );
71
+ } catch (IndexOutOfBoundsException e ) { // slot will only get bigger when too high so exit
72
+ break ;
73
+ }
68
74
slot ++;
69
75
}
70
76
71
- if (dynamicSizing && !notAddedItems .isEmpty () && (this .rows < 6 && holder .getType () == MenuType .CHEST )) {
72
- holder .recreateInventory ();
73
- holder .update ();
77
+ if (this . dynamicSizing && !notAddedItems .isEmpty () && (this .rows < 6 && this . holder .getType () == MenuType .CHEST )) {
78
+ this . holder .recreateInventory ();
79
+ this . holder .update ();
74
80
return this .addItem (notAddedItems .toArray (new ItemStack [0 ]));
75
81
}
76
82
return true ;
@@ -83,20 +89,22 @@ public boolean addItem(@NotNull final ItemStack... items) {
83
89
*/
84
90
public boolean addItem (@ NotNull final MenuItem ... items ) {
85
91
final List <MenuItem > notAddedItems = new ArrayList <>();
86
- final Set <Integer > occupiedSlots = itemMap .keySet ();
87
92
88
93
int slot = 0 ;
89
94
for (final MenuItem guiItem : items ) {
90
95
if (slot >= size ) {
96
+ if (rows == 6 ) break ; // save some performance
91
97
notAddedItems .add (guiItem );
92
98
continue ;
93
99
}
94
100
95
- while (occupiedSlots .contains (slot )) {
96
- slot ++;
97
- }
101
+ slot = getSlot (itemMap , slot );
98
102
99
- itemMap .put (slot , guiItem );
103
+ try {
104
+ itemMap [slot ] = guiItem ;
105
+ } catch (IndexOutOfBoundsException e ) { // slot will only get bigger when too high so exit
106
+ break ;
107
+ }
100
108
slot ++;
101
109
}
102
110
@@ -108,13 +116,33 @@ public boolean addItem(@NotNull final MenuItem... items) {
108
116
return true ;
109
117
}
110
118
119
+ private static boolean isSlotGreater (Collection <MenuItem > notAddedItems , int slot , int size , MenuItem guiItem ) {
120
+ if (slot < size ) return false ;
121
+ notAddedItems .add (guiItem );
122
+ return true ;
123
+ }
124
+
125
+
126
+ private static boolean isSlotGreater (Collection <ItemStack > notAddedItems , int slot , int size , ItemStack guiItem ) {
127
+ if (slot < size ) return false ;
128
+ notAddedItems .add (guiItem );
129
+ return true ;
130
+ }
131
+
132
+ private static int getSlot (MenuItem [] occupiedSlots , int slot ) {
133
+ while (occupiedSlots [slot ] != null ) {
134
+ slot ++;
135
+ }
136
+ return slot ;
137
+ }
138
+
111
139
/**
112
140
* Set the item at the specified slot in the page.
113
141
* @param slot the slot to set
114
142
* @param item the item to set
115
143
*/
116
144
public void setItem (int slot , MenuItem item ) {
117
- itemMap . put ( slot , item ) ;
145
+ this . itemMap [ slot ] = item ;
118
146
}
119
147
120
148
/**
@@ -123,7 +151,7 @@ public void setItem(int slot, MenuItem item) {
123
151
* @param item the item to set
124
152
*/
125
153
public void setItem (int slot , ItemStack item ) {
126
- itemMap . put ( slot , MenuItem .of (item ) );
154
+ this . itemMap [ slot ] = MenuItem .of (item );
127
155
}
128
156
129
157
/**
@@ -133,7 +161,7 @@ public void setItem(int slot, ItemStack item) {
133
161
*/
134
162
public void setItem (Slot slot , MenuItem item ) {
135
163
if (!slot .isSlot ()) return ;
136
- itemMap . put ( slot .slot , item ) ;
164
+ this . itemMap [ slot .slot ] = item ;
137
165
}
138
166
139
167
/**
@@ -143,7 +171,7 @@ public void setItem(Slot slot, MenuItem item) {
143
171
*/
144
172
public void setItem (Slot slot , ItemStack item ) {
145
173
if (!slot .isSlot ()) return ;
146
- itemMap . put ( slot .slot , MenuItem .of (item ) );
174
+ this . itemMap [ slot .slot ] = MenuItem .of (item );
147
175
}
148
176
149
177
/**
@@ -153,15 +181,15 @@ public void setItem(Slot slot, ItemStack item) {
153
181
public void removeItem (MenuItem ... items ) {
154
182
Set <MenuItem > slots = ImmutableSet .copyOf (items );
155
183
156
- int size = itemMap .size () ;
184
+ int size = itemMap .length ;
157
185
Inventory inventory = holder .getInventory ();
158
186
for (int i = 0 ; i < size ; i ++) {
159
- MenuItem item = itemMap . get ( i ) ;
187
+ MenuItem item = itemMap [ i ] ;
160
188
if (item == null ) continue ;
161
189
162
190
ItemStack itemStack = item .getItemStack ();
163
191
if (slots .contains (item )) {
164
- itemMap . remove (i );
192
+ remove (i );
165
193
inventory .remove (itemStack );
166
194
}
167
195
}
@@ -174,15 +202,15 @@ public void removeItem(MenuItem... items) {
174
202
public void removeItem (ItemStack ... items ) {
175
203
Set <ItemStack > slots = ImmutableSet .copyOf (items );
176
204
177
- int size = itemMap .size () ;
205
+ int size = itemMap .length ;
178
206
Inventory inventory = holder .getInventory ();
179
207
for (int i = 0 ; i < size ; i ++) {
180
- MenuItem item = itemMap . get ( i ) ;
208
+ MenuItem item = itemMap [ i ] ;
181
209
if (item == null ) continue ;
182
210
183
211
ItemStack itemStack = item .getItemStack ();
184
212
if (slots .contains (itemStack )) {
185
- itemMap . remove (i );
213
+ remove (i );
186
214
inventory .remove (itemStack );
187
215
}
188
216
}
@@ -193,10 +221,10 @@ public void removeItem(ItemStack... items) {
193
221
* @param itemDescription the predicate to check
194
222
*/
195
223
public void removeItem (Predicate <MenuItem > itemDescription ) {
196
- int size = itemMap .size () ;
224
+ int size = itemMap .length ;
197
225
for (int i = 0 ; i < size ; i ++) {
198
- MenuItem item = itemMap . get ( i ) ;
199
- if (item != null && itemDescription .test (item )) itemMap . remove (i );
226
+ MenuItem item = itemMap [ i ] ;
227
+ if (item != null && itemDescription .test (item )) remove (i );
200
228
}
201
229
}
202
230
@@ -207,7 +235,7 @@ public void removeItem(Predicate<MenuItem> itemDescription) {
207
235
* @return the removed item
208
236
*/
209
237
public MenuItem removeItem (Slot slot ) {
210
- return itemMap . remove (slot .slot );
238
+ return remove (slot .slot );
211
239
}
212
240
213
241
/**
@@ -217,7 +245,7 @@ public MenuItem removeItem(Slot slot) {
217
245
* @return the removed item
218
246
*/
219
247
public MenuItem removeItem (int slot ) {
220
- return itemMap . remove (slot );
248
+ return remove (slot );
221
249
}
222
250
223
251
/**
@@ -226,8 +254,13 @@ public MenuItem removeItem(int slot) {
226
254
* @param slot the slot to check
227
255
* @return the item or null
228
256
*/
229
- public MenuItem getItem (Slot slot ) {
230
- return itemMap .get (slot .slot );
257
+ public @ Nullable MenuItem getItem (Slot slot ) {
258
+ if (!slot .isSlot ()) return null ;
259
+ try {
260
+ return itemMap [slot .slot ];
261
+ } catch (IndexOutOfBoundsException e ) {
262
+ return null ;
263
+ }
231
264
}
232
265
233
266
/**
@@ -236,8 +269,12 @@ public MenuItem getItem(Slot slot) {
236
269
* @param slot the slot to check
237
270
* @return the item or null
238
271
*/
239
- public MenuItem getItem (int slot ) {
240
- return itemMap .get (slot );
272
+ public @ Nullable MenuItem getItem (int slot ) {
273
+ try {
274
+ return itemMap [slot ];
275
+ } catch (IndexOutOfBoundsException e ) {
276
+ return null ;
277
+ }
241
278
}
242
279
243
280
/**
@@ -246,10 +283,10 @@ public MenuItem getItem(int slot) {
246
283
* @return the item or null
247
284
*/
248
285
public @ Nullable MenuItem getItem (Predicate <MenuItem > itemDescription ) {
249
- int size = itemMap . size ();
250
- for ( int i = 0 ; i < size ; i ++ ) {
251
- MenuItem item = itemMap . get ( i ) ;
252
- if ( item != null && itemDescription . test ( item )) return item ;
286
+ for ( MenuItem item : itemMap ) {
287
+ if ( item != null && itemDescription . test ( item ) ) {
288
+ return item ;
289
+ }
253
290
}
254
291
return null ;
255
292
}
@@ -261,7 +298,12 @@ public MenuItem getItem(int slot) {
261
298
* @return the item
262
299
*/
263
300
public Optional <MenuItem > get (Slot slot ) {
264
- return Optional .ofNullable (itemMap .get (slot .slot ));
301
+ if (!slot .isSlot ()) return Optional .empty ();
302
+ try {
303
+ return Optional .ofNullable (itemMap [slot .slot ]);
304
+ } catch (IndexOutOfBoundsException e ) {
305
+ return Optional .empty ();
306
+ }
265
307
}
266
308
267
309
/**
@@ -271,7 +313,11 @@ public Optional<MenuItem> get(Slot slot) {
271
313
* @return the item
272
314
*/
273
315
public Optional <MenuItem > get (int slot ) {
274
- return Optional .ofNullable (itemMap .get (slot ));
316
+ try {
317
+ return Optional .ofNullable (itemMap [slot ]);
318
+ } catch (IndexOutOfBoundsException e ) {
319
+ return Optional .empty ();
320
+ }
275
321
}
276
322
277
323
/**
@@ -280,9 +326,8 @@ public Optional<MenuItem> get(int slot) {
280
326
* @return the item
281
327
*/
282
328
public Optional <MenuItem > get (Predicate <MenuItem > itemDescription ) {
283
- int size = itemMap .size ();
284
- for (int i = 0 ; i < size ; i ++) {
285
- MenuItem item = itemMap .get (i );
329
+ int size = itemMap .length ;
330
+ for (MenuItem item : itemMap ) {
286
331
if (item != null && itemDescription .test (item )) return Optional .of (item );
287
332
}
288
333
return Optional .empty ();
@@ -320,23 +365,23 @@ public PageIterator iterator(int startingRow, int startingCol, IterationDirectio
320
365
* Clear the entire page.
321
366
*/
322
367
public void clear () {
323
- itemMap . clear ( );
368
+ Arrays . fill ( itemMap , null );
324
369
}
325
370
326
371
/**
327
372
* Get a stream of every value in the map.
328
373
* @return the stream
329
374
*/
330
375
public Stream <MenuItem > stream () {
331
- return itemMap . values (). stream ();
376
+ return Arrays . stream ( itemMap ). parallel ();
332
377
}
333
378
334
379
/**
335
380
* Get a <strong>PARALLEL</strong> stream of every value in the map.
336
381
* @return the parallel stream
337
382
*/
338
383
public Stream <MenuItem > parallelStream () {
339
- return itemMap . values (). parallelStream ();
384
+ return Arrays . stream ( itemMap ). parallel ();
340
385
}
341
386
342
387
/**
@@ -369,16 +414,34 @@ public int rows() {
369
414
* @return true if there is an item
370
415
*/
371
416
public boolean hasItem (int slot ) {
372
- return itemMap . get ( slot ) != null ;
417
+ return itemMap [ slot ] != null ;
373
418
}
374
419
375
420
/**
376
421
* Check if the page has an item at the specified slot.
377
422
* @param slot the slot
378
423
* @return true if there is an item
379
424
*/
380
- public boolean hasItem (Slot slot ) {
425
+ public boolean hasItem (@ NotNull Slot slot ) {
381
426
if (!slot .isSlot ()) return false ;
382
- return itemMap .get (slot .slot ) != null ;
427
+ return itemMap [slot .slot ] != null ;
428
+ }
429
+
430
+ private MenuItem remove (int index ) {
431
+ int length = this .itemMap .length ;
432
+ Preconditions .checkElementIndex (index , length );
433
+
434
+ MenuItem item = this .itemMap [index ];
435
+ this .itemMap [index ] = null ;
436
+ return item ;
437
+ }
438
+
439
+ public void setContents (MenuItem ... items ) {
440
+ this .itemMap = items ;
441
+ this .holder .update ();
442
+ }
443
+
444
+ public List <MenuItem > getItems () {
445
+ return Arrays .asList (itemMap );
383
446
}
384
447
}
0 commit comments