package com.genuineflix.api.test; import java.util.ArrayList; import java.util.List; public class TestMetalImplementation implements IMetal { public static void main(String[] args) { TestMetalImplementation copper = new TestMetalImplementation("copper"); TestMetalImplementation tin = new TestMetalImplementation("tin"); TestMetalImplementation bronze = new TestMetalImplementation("bronze"); bronze.compounds.add(new Compound(copper, 3)); bronze.compounds.add(new Compound(tin, 1)); System.out.println(bronze); NBTTagCompound saved = bronze.save(new NBTTagCompound()); TestMetalImplementation newBronze = (TestMetalImplementation) new TestMetalImplementation().load(saved); System.out.println(newBronze); System.out.println("Bronze and new Bronze are " + (bronze.equals(newBronze) ? "" : "not ") + "equal"); } private String name; private List compounds = new ArrayList<>(); public TestMetalImplementation() {} public TestMetalImplementation(String name) { this.name = name; } @Override public String getName() { return name; } @Override public NBTTagCompound save(NBTTagCompound tag) { tag.setString("name", name); if (compounds.isEmpty()) return tag; NBTTagCompound comps = new NBTTagCompound(); for (int i = 0; i < compounds.size(); i++) comps.setTag("compound" + i, compounds.get(i).save(new NBTTagCompound())); tag.setTag("compounds", comps); return tag; } @Override public IMetal load(NBTTagCompound nbt) { name = nbt.getString("name"); if (nbt.hasKey("compounds")) { int i = 0; List list = new ArrayList<>(); NBTTagCompound compounds = nbt.getCompoundTag("compounds"); NBTTagCompound tag; while (!(tag = compounds.getCompoundTag("compound" + i)).hasNoTags()) { list.add(new Compound().load(tag)); i++; } this.compounds = list; } return this; } @Override public List getCompounds() { return compounds; } @Override public String toString() { return name + " " + compounds; } @Override public boolean equals(Object obj) { if (!(obj instanceof IMetal)) return false; TestMetalImplementation m = (TestMetalImplementation) obj; if (!name.equals(m.name)) return false; if (compounds.size() == 0 && m.compounds.size() == 0) return true; if (compounds.size() != m.compounds.size()) return false; for (Compound these : compounds) { boolean foundMatch = false; for (Compound theirs : m.compounds) { if (these.equals(theirs)) { foundMatch = true; break; } } if (!foundMatch) return false; } return true; } } class Compound implements NBTSaveable, NBTLoadable { public IMetal metal; public int count; public Compound() {} public Compound(IMetal metal, int count) { this.metal = metal; this.count = count; } @Override public NBTTagCompound save(NBTTagCompound nbt) { nbt.setString("class", metal.getClass().getName()); nbt.setTag("metal", metal.save(new NBTTagCompound())); nbt.setInteger("count", count); return nbt; } @Override public Compound load(NBTTagCompound nbt) { try { ClassLoader cl = ClassLoader.getSystemClassLoader(); @SuppressWarnings("unchecked") Class clazz = (Class) cl.loadClass(nbt.getString("class")); metal = clazz.newInstance().load(nbt.getCompoundTag("metal")); count = nbt.getInteger("count"); } catch (Exception e) { return null; } return this; } @Override public String toString() { return count + "x " + metal.getName(); } @Override public boolean equals(Object obj) { if (!(obj instanceof Compound)) return false; Compound c = (Compound) obj; return count == c.count && metal.equals(c.metal); } } interface IMetal extends NBTSaveable, NBTLoadable { public String getName(); public List getCompounds(); } interface NBTLoadable { public T load(NBTTagCompound nbt); } interface NBTSaveable { public NBTTagCompound save(NBTTagCompound tag); }