Skip to content

Commit

Permalink
Add methods to load and save component data
Browse files Browse the repository at this point in the history
  • Loading branch information
nahkd123 committed Feb 17, 2024
1 parent 1dcf490 commit e8ae040
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ public static UserDefinedId getId(ItemMeta meta) {
: null;
}

/**
* <p>
* Check if the created item contains display flag. Items for displaying have
* different display text comparing to normal items, such as showing the actual
* stats range instead of computed stats.
* </p>
*
* @param meta The item meta to check.
* @return {@code true} if the item was created with display mode.
*/
public static boolean isDisplayMode(ItemMeta meta) {
if (meta == null) return false;
PersistentDataContainer poc = meta.getPersistentDataContainer();
return poc.getOrDefault(keys().displayMode, PersistentDataType.BOOLEAN, false);
}

/**
* <p>
* Get the {@link PojoItem} by getting ID from {@link ItemMeta}.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package io.github.nahkd123.pojo.api.item.standard;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bukkit.Material;
import org.bukkit.NamespacedKey;
Expand Down Expand Up @@ -86,26 +84,24 @@ public boolean saveToConfig(ConfigurationSection config) {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public ItemStack createNew(boolean displayMode) {
Map<Component<?>, Object> dataMap = new HashMap<>();
ComponentDataHolder dataHolder = ComponentDataHolder.newHolder();

// 1. Initialize
for (Component component : components) {
Object obj = component.createNewData();
dataMap.put(component, obj);
dataHolder.addRaw(component.getClass(), obj);
Object data = component.createNewData();
dataHolder.addRaw(component, data);
}

// 2. Manipulate
for (Component component : components) component.applyToOtherComponent(dataMap.get(component), dataHolder);
for (Component component : components) component.applyToOtherComponent(dataHolder.get(component), dataHolder);

// 3. Display
Material mat = Material.STONE;
String name = null;
LoreSorter lore = new LoreSorter(loreSections);

for (Component component : components) {
Object obj = dataMap.get(component);
Object obj = dataHolder.get(component);
mat = component.applyMaterial(obj, mat, displayMode);
name = component.applyName(obj, name, displayMode);
component.applyLore(obj, lore, displayMode);
Expand All @@ -120,10 +116,10 @@ public ItemStack createNew(boolean displayMode) {
if (loreList.size() > 0) meta.setLore(loreList);

// 4. Post display & store data
for (Component component : components) component.applyPostDisplay(dataMap.get(component), meta, displayMode);
for (Component component : components) component.applyPostDisplay(dataHolder.get(component), meta, displayMode);

for (Component component : components) {
Object obj = dataMap.get(component);
Object obj = dataHolder.get(component);
component.storeDataTo(meta.getPersistentDataContainer(), obj);
}

Expand All @@ -135,50 +131,77 @@ public ItemStack createNew(boolean displayMode) {
@Override
public ItemMeta updateMeta(ItemMeta source, boolean displayMode) {
source = PojoItem.super.updateMeta(source, displayMode);
Map<Component<?>, Object> dataMap = new HashMap<>();
ComponentDataHolder dataHolder = ComponentDataHolder.newHolder();

// 1. Load
for (Component component : components) {
Object obj = component.loadDataFrom(source.getPersistentDataContainer());
dataMap.put(component, obj);
dataHolder.addRaw(component.getClass(), obj);
}

// 2. Manipulate
for (Component component : components) component.applyToOtherComponent(dataMap.get(component), dataHolder);
// 1. Load and manipulate
ComponentDataHolder dataHolder = loadDataFrom(source, true);

// 3. Display
// 2. Display
String name = null;
LoreSorter lore = new LoreSorter(loreSections);

for (Component component : components) {
Object obj = dataMap.get(component);
name = component.applyName(obj, name, displayMode);
component.applyLore(obj, lore, displayMode);
Object data = dataHolder.get(component);
name = component.applyName(data, name, displayMode);
component.applyLore(data, lore, displayMode);
}

List<String> loreList = lore.build();
if (name != null) source.setLocalizedName(name);
if (loreList.size() > 0) source.setLore(loreList);

// 4. Post display (storing data is not included atm)
for (Component component : components) component.applyPostDisplay(dataMap.get(component), source, displayMode);
// 3. Post display (storing data is not included atm)
for (Component component : components)
component.applyPostDisplay(dataHolder.get(component), source, displayMode);
return source;
}

/**
* <p>
* Load all component data from {@link ItemMeta}.
* </p>
*
* @param meta The meta to load.
* @param manipulate {@code true} will allows components to manipulate others,
* like applying to computed stats for example.
* @return Loaded component data.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public ComponentDataHolder loadDataFrom(ItemMeta meta) {
public ComponentDataHolder loadDataFrom(ItemMeta meta, boolean manipulate) {
ComponentDataHolder dataHolder = ComponentDataHolder.newHolder();
Map<Component<?>, Object> dataMap = new HashMap<>();

for (Component component : components) {
Object obj = component.loadDataFrom(meta.getPersistentDataContainer());
dataMap.put(component, obj);
dataHolder.addRaw(component.getClass(), obj);
Object data = component.loadDataFrom(meta.getPersistentDataContainer());
dataHolder.addRaw(component, data);
}

for (Component component : components) component.applyToOtherComponent(dataMap.get(component), dataHolder);
for (Component component : components) component.applyToOtherComponent(dataHolder.get(component), dataHolder);
return dataHolder;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public void saveDataTo(ItemMeta meta, ComponentDataHolder dataHolder) {
// 1. Display
String name = null;
LoreSorter lore = new LoreSorter(loreSections);
boolean displayMode = PojoItem.isDisplayMode(meta);

for (Component component : components) {
Object data = dataHolder.get(component);
name = component.applyName(data, name, displayMode);
component.applyLore(data, lore, displayMode);
}

List<String> loreList = lore.build();
if (name != null) meta.setLocalizedName(name);
if (loreList.size() > 0) meta.setLore(loreList);

// 2. Post display & store data
for (Component component : components)
component.applyPostDisplay(dataHolder.get(component), meta, displayMode);

for (Component component : components) {
Object obj = dataHolder.get(component);
component.storeDataTo(meta.getPersistentDataContainer(), obj);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,48 @@
* </p>
*/
public interface ComponentDataHolder {
public <C extends Component<T>, T> List<T> get(Class<C> component);
public <C extends Component<T>, T> List<T> getList(Class<C> component);

public <C extends Component<T>, T> void add(Class<C> type, T data);
public <C extends Component<T>, T> T get(C component);

public <C extends Component<T>, T> void add(C component, T data);

public Map<Component<?>, ?> getMap();

@SuppressWarnings({ "unchecked", "rawtypes" })
default void addRaw(Class type, Object data) {
add(type, data);
default void addRaw(Component component, Object data) {
add(component, data);
}

@SuppressWarnings("rawtypes")
public static ComponentDataHolder newHolder() {
Map<Class<?>, List> map = new HashMap<>();
Map<Class<?>, List> mapOfLists = new HashMap<>();
Map<Component<?>, Object> mapOfData = new HashMap<>();

return new ComponentDataHolder() {
@SuppressWarnings("unchecked")
@Override
public <C extends Component<T>, T> void add(Class<C> type, T data) {
List list = map.get(type);
if (list == null) map.put(type, list = new ArrayList());
public <C extends Component<T>, T> void add(C component, T data) {
List list = mapOfLists.get(component.getClass());
if (list == null) mapOfLists.put(component.getClass(), list = new ArrayList());
list.add(data);
mapOfData.put(component, mapOfData);
}

@SuppressWarnings("unchecked")
@Override
public <C extends Component<T>, T> List<T> getList(Class<C> type) {
return (List<T>) mapOfLists.get(type);
}

@SuppressWarnings("unchecked")
@Override
public <C extends Component<T>, T> List<T> get(Class<C> type) {
return (List<T>) map.get(type);
public <C extends Component<T>, T> T get(C component) {
return (T) mapOfData.get(component);
}

@Override
public Map<Component<?>, ?> getMap() { return mapOfData; }
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ public static List<ComputedStats> computeItemStats(ItemMeta meta) {
PojoItem item = PojoItem.getFrom(meta);
if (!(item instanceof StandardPojoItem std)) return Collections.emptyList();

ComponentDataHolder dataHolder = std.loadDataFrom(meta);
return Collections.unmodifiableList(dataHolder.get(StatsComponent.class));
ComponentDataHolder dataHolder = std.loadDataFrom(meta, true);
return Collections.unmodifiableList(dataHolder.getList(StatsComponent.class));
}

/**
Expand Down

0 comments on commit e8ae040

Please sign in to comment.