Skip to content

Commit 7d5738e

Browse files
authored
Refactors CustomItemStack to not extend ItemStack (#275)
1 parent 35144c2 commit 7d5738e

File tree

8 files changed

+897
-95
lines changed

8 files changed

+897
-95
lines changed
Lines changed: 38 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,68 @@
11
package io.github.bakedlibs.dough.items;
22

3-
import java.util.ArrayList;
4-
import java.util.List;
5-
import java.util.function.Consumer;
6-
7-
import org.bukkit.ChatColor;
8-
import org.bukkit.Color;
93
import org.bukkit.Material;
10-
import org.bukkit.inventory.ItemFlag;
114
import org.bukkit.inventory.ItemStack;
125
import org.bukkit.inventory.meta.ItemMeta;
13-
import org.bukkit.inventory.meta.LeatherArmorMeta;
14-
import org.bukkit.inventory.meta.PotionMeta;
15-
16-
public class CustomItemStack extends ItemStack {
17-
18-
public CustomItemStack(ItemStack item) {
19-
super(item);
20-
}
21-
22-
public CustomItemStack(Material type) {
23-
super(type);
24-
}
256

26-
public CustomItemStack(ItemStack item, Consumer<ItemMeta> meta) {
27-
super(item);
28-
ItemMeta im = getItemMeta();
29-
meta.accept(im);
30-
setItemMeta(im);
31-
}
7+
import javax.annotation.Nullable;
8+
import javax.annotation.ParametersAreNonnullByDefault;
9+
import java.util.List;
10+
import java.util.function.Consumer;
3211

33-
public CustomItemStack(Material type, Consumer<ItemMeta> meta) {
34-
this(new ItemStack(type), meta);
12+
@ParametersAreNonnullByDefault
13+
public final class CustomItemStack {
3514

15+
private CustomItemStack() {
16+
throw new IllegalStateException("Cannot instantiate CustomItemStack");
3617
}
3718

38-
public CustomItemStack(ItemStack item, String name, String... lore) {
39-
this(item, im -> {
40-
if (name != null) {
41-
im.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
42-
}
43-
44-
if (lore.length > 0) {
45-
List<String> lines = new ArrayList<>();
46-
47-
for (String line : lore) {
48-
lines.add(ChatColor.translateAlternateColorCodes('&', line));
49-
}
50-
im.setLore(lines);
51-
}
52-
});
19+
public static ItemStack create(ItemStack itemStack, Consumer<ItemMeta> metaConsumer) {
20+
return new ItemStackEditor(itemStack).andMetaConsumer(metaConsumer).create();
5321
}
5422

55-
public CustomItemStack(ItemStack item, Color color, String name, String... lore) {
56-
this(item, im -> {
57-
if (name != null) {
58-
im.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
59-
}
60-
61-
if (lore.length > 0) {
62-
List<String> lines = new ArrayList<>();
63-
64-
for (String line : lore) {
65-
lines.add(ChatColor.translateAlternateColorCodes('&', line));
66-
}
67-
im.setLore(lines);
68-
}
69-
70-
if (im instanceof LeatherArmorMeta) {
71-
((LeatherArmorMeta) im).setColor(color);
72-
}
73-
if (im instanceof PotionMeta) {
74-
((PotionMeta) im).setColor(color);
75-
}
76-
});
23+
public static ItemStack create(Material material, Consumer<ItemMeta> metaConsumer) {
24+
return new ItemStackEditor(material).andMetaConsumer(metaConsumer).create();
7725
}
7826

79-
public CustomItemStack addFlags(ItemFlag... flags) {
80-
ItemMeta im = getItemMeta();
81-
im.addItemFlags(flags);
82-
setItemMeta(im);
83-
84-
return this;
27+
public static ItemStack create(ItemStack item, @Nullable String name, String... lore) {
28+
return new ItemStackEditor(item)
29+
.setDisplayName(name)
30+
.setLore(lore)
31+
.create();
8532
}
8633

87-
public CustomItemStack setCustomModel(int data) {
88-
ItemMeta im = getItemMeta();
89-
im.setCustomModelData(data == 0 ? null : data);
90-
setItemMeta(im);
91-
92-
return this;
34+
public static ItemStack create(Material material, @Nullable String name, String... lore) {
35+
return create(new ItemStack(material), name, lore);
9336
}
9437

95-
public CustomItemStack(Material type, String name, String... lore) {
96-
this(new ItemStack(type), name, lore);
38+
public static ItemStack create(Material type, @Nullable String name, List<String> lore) {
39+
return create(new ItemStack(type), name, lore.toArray(String[]::new));
9740
}
9841

99-
public CustomItemStack(Material type, String name, List<String> lore) {
100-
this(new ItemStack(type), name, lore.toArray(new String[lore.size()]));
101-
}
10242

103-
public CustomItemStack(ItemStack item, List<String> list) {
104-
this(item, list.get(0), list.subList(1, list.size()).toArray(new String[0]));
43+
public static ItemStack create(ItemStack item, List<String> list) {
44+
return create(new ItemStack(item), list.get(0), list.subList(1, list.size()).toArray(String[]::new));
10545
}
10646

107-
public CustomItemStack(Material type, List<String> list) {
108-
this(new ItemStack(type), list);
47+
public static ItemStack create(Material type, List<String> list) {
48+
return create(new ItemStack(type), list);
10949
}
11050

111-
public CustomItemStack(ItemStack item, int amount) {
112-
super(item);
113-
setAmount(amount);
51+
public static ItemStack create(ItemStack item, int amount) {
52+
return new ItemStackEditor(item).setAmount(amount).create();
11453
}
11554

116-
public CustomItemStack(ItemStack item, Material type) {
117-
super(item);
118-
setType(type);
55+
/**
56+
* Clones the item stack and sets its type
57+
*
58+
* @param itemStack The item
59+
* @param type The new type
60+
* @return Returns the item with a new type
61+
* @deprecated Setting the type via {@link ItemStack#setType(Material)} will not be supported soon.
62+
*/
63+
@Deprecated(forRemoval = true)
64+
public static ItemStack create(ItemStack itemStack, Material type) {
65+
return new ItemStackEditor(itemStack).andStackConsumer(item -> item.setType(type)).create();
11966
}
12067

12168
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package io.github.bakedlibs.dough.items;
2+
3+
import org.bukkit.Color;
4+
import org.bukkit.Material;
5+
import org.bukkit.inventory.ItemFlag;
6+
import org.bukkit.inventory.ItemStack;
7+
import org.bukkit.inventory.meta.ItemMeta;
8+
import org.bukkit.inventory.meta.LeatherArmorMeta;
9+
import org.bukkit.inventory.meta.PotionMeta;
10+
11+
import javax.annotation.Nullable;
12+
import javax.annotation.ParametersAreNonnullByDefault;
13+
import java.util.Arrays;
14+
import java.util.List;
15+
import java.util.function.Consumer;
16+
17+
/**
18+
* Fluent class to apply edits/transformations to an {@link ItemStack} and it's {@link ItemMeta} instance
19+
* <p>
20+
* This class is immutable.
21+
* The {@link ItemStack} instance which this class holds on to is never mutated.
22+
*
23+
* @see #create()
24+
* @see #applyTo(ItemStack)
25+
*/
26+
@ParametersAreNonnullByDefault
27+
public class ItemStackEditor {
28+
29+
private final ItemStack itemStack;
30+
private final Consumer<ItemMeta> metaTransform;
31+
private final Consumer<ItemStack> stackTransform;
32+
33+
private ItemStackEditor(ItemStack itemStack,
34+
@Nullable Consumer<ItemMeta> metaTransform,
35+
@Nullable Consumer<ItemStack> stackTransform) {
36+
this.itemStack = itemStack;
37+
this.metaTransform = metaTransform;
38+
this.stackTransform = stackTransform;
39+
}
40+
41+
public ItemStackEditor(ItemStack item) {
42+
this(item.clone(), null, null);
43+
}
44+
45+
public ItemStackEditor(Material type) {
46+
this(new ItemStack(type));
47+
}
48+
49+
public ItemStackEditor addFlags(ItemFlag... flags) {
50+
return andMetaConsumer(ItemStackUtil.appendItemFlags(flags));
51+
}
52+
53+
public ItemStackEditor setCustomModel(int data) {
54+
return andMetaConsumer(ItemStackUtil.editCustomModelData(data));
55+
}
56+
57+
public ItemStackEditor setCustomModel(@Nullable Integer data) {
58+
return andMetaConsumer(ItemStackUtil.editCustomModelData(data));
59+
}
60+
61+
public ItemStackEditor setAmount(int amount) {
62+
return andStackConsumer(stack -> stack.setAmount(amount));
63+
}
64+
65+
public ItemStackEditor setColor(Color color) {
66+
return andMetaConsumer(meta -> {
67+
if (meta instanceof LeatherArmorMeta) {
68+
((LeatherArmorMeta) meta).setColor(color);
69+
}
70+
if (meta instanceof PotionMeta) {
71+
((PotionMeta) meta).setColor(color);
72+
}
73+
});
74+
}
75+
76+
public ItemStackEditor setLore(String... lore) {
77+
return setLore(Arrays.asList(lore));
78+
}
79+
80+
public ItemStackEditor setLore(List<String> list) {
81+
return andMetaConsumer(ItemStackUtil.editLore(list));
82+
}
83+
84+
public ItemStackEditor setDisplayName(@Nullable String name) {
85+
return andMetaConsumer(ItemStackUtil.editDisplayName(name));
86+
}
87+
88+
public ItemStackEditor andMetaConsumer(Consumer<ItemMeta> consumer) {
89+
if (this.metaTransform == null) {
90+
return withMetaConsumer(consumer);
91+
}
92+
return withMetaConsumer(this.metaTransform.andThen(consumer));
93+
}
94+
95+
public ItemStackEditor withMetaConsumer(@Nullable Consumer<ItemMeta> consumer) {
96+
return new ItemStackEditor(this.itemStack, consumer, this.stackTransform);
97+
}
98+
99+
public ItemStackEditor withStackConsumer(@Nullable Consumer<ItemStack> consumer) {
100+
return new ItemStackEditor(this.itemStack, this.metaTransform, consumer);
101+
}
102+
103+
public ItemStackEditor andStackConsumer(Consumer<ItemStack> consumer) {
104+
if (this.stackTransform == null) {
105+
return withStackConsumer(consumer);
106+
}
107+
return withStackConsumer(this.stackTransform.andThen(consumer));
108+
}
109+
110+
public ItemStack create() {
111+
ItemStack cloned = this.itemStack.clone();
112+
applyTo(cloned);
113+
return cloned;
114+
}
115+
116+
public void applyTo(ItemStack itemStack) {
117+
if (this.stackTransform != null) {
118+
this.stackTransform.accept(itemStack);
119+
}
120+
if (this.metaTransform != null) {
121+
ItemStackUtil.editMeta(itemStack, this.metaTransform);
122+
}
123+
}
124+
125+
}

0 commit comments

Comments
 (0)