diff --git a/excel/annotation-processor/src/main/java/com/riiablo/excel/TableGenerator.java b/excel/annotation-processor/src/main/java/com/riiablo/excel/TableGenerator.java index 82099311..d069ef43 100644 --- a/excel/annotation-processor/src/main/java/com/riiablo/excel/TableGenerator.java +++ b/excel/annotation-processor/src/main/java/com/riiablo/excel/TableGenerator.java @@ -12,10 +12,16 @@ import java.util.List; import javax.annotation.Generated; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.Modifier; +import javax.lang.model.element.VariableElement; import javax.lang.model.util.Elements; +import javax.tools.Diagnostic; import org.apache.commons.lang3.time.DateFormatUtils; +import com.riiablo.excel.annotation.PrimaryKey; + public class TableGenerator { static final ClassName tableName = ClassName.get(Table.class); @@ -46,9 +52,52 @@ public class TableGenerator { JavaFile generateFile(SchemaAnnotatedElement schema) { String comments = schema.name.canonicalName(); List fields = new ArrayList<>(256); + VariableElement primaryKey = null, firstField = null; + for (Element element : schema.element.getEnclosedElements()) { + try { + PrimaryKeyAnnotatedElement annotatedElement = PrimaryKeyAnnotatedElement.get(element); + if (annotatedElement != null) { + if (schema.annotation.indexed()) { + throw new GenerationException( + String.format("indexed schema defines a @%s", + PrimaryKey.class.getCanonicalName()), + element) + .kind(Diagnostic.Kind.WARNING); + } else if (primaryKey == null) { + primaryKey = annotatedElement.element; + } else { + throw new GenerationException( + String.format("%s has already been set as the @%s", + primaryKey.getSimpleName(), + PrimaryKey.class.getCanonicalName()), + element, annotatedElement.mirror); + } + } else if (firstField == null && element.getKind() == ElementKind.FIELD) { + firstField = (VariableElement) element; + } + } catch (GenerationException t) { + t.printMessage(messager); + } + } - TypeSpec.Builder tableType = newTable(schemaName, fields) + if (primaryKey == null && firstField != null) { + messager.printMessage(Diagnostic.Kind.WARNING, + String.format("%s does not declare a @%s, using %s", + schema.name, PrimaryKey.class.getCanonicalName(), firstField.getSimpleName()), + schema.element); + primaryKey = firstField; + } + + MethodSpec constructor = MethodSpec + .constructorBuilder() + .addStatement("super($T.class)", schema.element) + .build(); + + TypeSpec.Builder tableType = newTable(schema, fields) .addAnnotation(newGenerated(comments)) + .addMethod(constructor) + .addMethod(offset(schema)) + .addMethod(primaryKey(primaryKey)) ; return JavaFile @@ -76,4 +125,24 @@ public class TableGenerator { .addModifiers(Modifier.PUBLIC, Modifier.FINAL) ; } + + MethodSpec offset(SchemaAnnotatedElement schema) { + return MethodSpec + .methodBuilder("offset") + .addAnnotation(Override.class) + .addModifiers(Modifier.PROTECTED) + .returns(int.class) + .addStatement("return $L", schema.annotation.offset()) + .build(); + } + + MethodSpec primaryKey(VariableElement primaryKey) { + return MethodSpec + .methodBuilder("primaryKey") + .addAnnotation(Override.class) + .addModifiers(Modifier.PROTECTED) + .returns(String.class) + .addStatement("return $S", primaryKey) + .build(); + } } diff --git a/excel/core/src/main/java/com/riiablo/excel/Table.java b/excel/core/src/main/java/com/riiablo/excel/Table.java index 5300b030..b51ed6e4 100644 --- a/excel/core/src/main/java/com/riiablo/excel/Table.java +++ b/excel/core/src/main/java/com/riiablo/excel/Table.java @@ -1,22 +1,77 @@ package com.riiablo.excel; +import java.util.Iterator; + +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.IntMap; +import com.badlogic.gdx.utils.ObjectIntMap; + /** * @param type of records stored in this table */ -public abstract class Table { - public R get(String id) { - throw new UnsupportedOperationException(); +public abstract class Table implements Iterable { + protected final Class recordClass; + protected ObjectIntMap lookup; + protected IntMap records; + protected Array ordered; + + protected Table(Class recordClass) { + this(recordClass, 53); + } + + protected Table(Class recordClass, int initialCapacity) { + this(recordClass, initialCapacity, 0.8f); + } + + protected Table(Class recordClass, int initialCapacity, float loadFactor) { + this.recordClass = recordClass; + records = new IntMap<>(initialCapacity, loadFactor); + ordered = new Array<>(true, (int) (initialCapacity * loadFactor), recordClass); + lookup = null; + } + + @SuppressWarnings("unchecked") + public Class> tableClass() { + return (Class >) getClass(); + } + + public Class recordClass() { + return recordClass; + } + + protected void put(int id, R record) { + records.put(id, record); + ordered.add(record); } public R get(int id) { - throw new UnsupportedOperationException(); + return records.get(id); } public int index(String id) { - throw new UnsupportedOperationException(); + return lookup == null ? -1 : lookup.get(id, -1); + } + + public R get(String id) { + return get(index(id)); } public int size() { - throw new UnsupportedOperationException(); + return records.size; + } + + protected int offset() { + return 0; + } + + protected String primaryKey() { + return null; + } + + protected void init() {} + + @Override + public Iterator iterator() { + return ordered.iterator(); } } diff --git a/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStats.java b/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStats.java index a66bf7f2..a6310836 100644 --- a/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStats.java +++ b/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStats.java @@ -9,6 +9,11 @@ import com.riiablo.excel.annotation.Schema; // @SerializedWith(MonStatsSerializerImpl.class) @SuppressWarnings("unused") public class MonStats { + @Override + public String toString() { + return NameStr; + } + @PrimaryKey public String Id; public int hcIdx; @@ -41,9 +46,179 @@ public class MonStats { public int Velocity; public int Run; public int Rarity; + public String MonSound; + public String UMonSound; + public int threat; + public String MissA1; + public String MissA2; + public String MissS1; + public String MissS2; + public String MissS3; + public String MissS4; + public String MissC; + public String MissSQ; + public int Align; + public boolean isSpawn; + public boolean isMelee; + public boolean npc; + public boolean interact; + public boolean inventory; + public boolean inTown; + public boolean lUndead; + public boolean hUndead; + public boolean demon; + public boolean flying; + public boolean opendoors; + public boolean boss; + public boolean primeevil; + public boolean killable; + public boolean switchai; + public boolean noAura; + public boolean nomultishot; + public boolean neverCount; + public boolean petIgnore; + public boolean deathDmg; + public boolean genericSpawn; + public boolean zoo; + public int SendSkills; + public String Skill1; + public String Sk1mode; + public int Sk1lvl; + public String Skill2; + public String Sk2mode; + public int Sk2lvl; + public String Skill3; + public String Sk3mode; + public int Sk3lvl; + public String Skill4; + public String Sk4mode; + public int Sk4lvl; + public String Skill5; + public String Sk5mode; + public int Sk5lvl; + public String Skill6; + public String Sk6mode; + public int Sk6lvl; + public String Skill7; + public String Sk7mode; + public int Sk7lvl; + public String Skill8; + public String Sk8mode; + public int Sk8lvl; + public int DamageRegen; + public String SkillDamage; + public boolean noRatio; + public boolean NoShldBlock; + public int Crit; + public String El1Mode; + public String El1Type; + public String El2Mode; + public String El2Type; + public String El3Mode; + public String El3Type; + public int TCQuestId; + public int TCQuestCP; + public int SplEndDeath; + public boolean SplGetModeChart; + public boolean SplEndGeneric; + public boolean SplClientEnd; @Format(format = "Level%s", values = {"", "(N)", "(H)"}, endIndex = 3) public int[] Level; - - + @Format(format = "aidel%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aidel; + @Format(format = "aidist%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aidist; + @Format(format = "aip1%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip1; + @Format(format = "aip2%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip2; + @Format(format = "aip3%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip3; + @Format(format = "aip4%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip4; + @Format(format = "aip5%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip5; + @Format(format = "aip6%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip6; + @Format(format = "aip7%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip7; + @Format(format = "aip8%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] aip8; + @Format(format = "Drain%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] Drain; + @Format(format = "coldeffect%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] coldeffect; + @Format(format = "ResDm%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] ResDm; + @Format(format = "ResMa%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] ResMa; + @Format(format = "ResFi%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] ResFi; + @Format(format = "ResLi%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] ResLi; + @Format(format = "ResCo%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] ResCo; + @Format(format = "ResPo%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] ResPo; + @Format(format = "ToBlock%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] ToBlock; + @Format(format = "minHP%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] minHP; + @Format(format = "maxHP%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] maxHP; + @Format(format = "AC%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] AC; + @Format(format = "Exp%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] Exp; + @Format(format = "A1MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] A1MinD; + @Format(format = "A1MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] A1MaxD; + @Format(format = "A1TH%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] A1TH; + @Format(format = "A2MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] A2MinD; + @Format(format = "A2MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] A2MaxD; + @Format(format = "A2TH%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] A2TH; + @Format(format = "S1MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] S1MinD; + @Format(format = "S1MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] S1MaxD; + @Format(format = "S1TH%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] S1TH; + @Format(format = "El1Pct%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El1Pct; + @Format(format = "El1MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El1MinD; + @Format(format = "El1MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El1MaxD; + @Format(format = "El1Dur%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El1Dur; + @Format(format = "El2Pct%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El2Pct; + @Format(format = "El2MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El2MinD; + @Format(format = "El2MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El2MaxD; + @Format(format = "El2Dur%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El2Dur; + @Format(format = "El3Pct%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El3Pct; + @Format(format = "El3MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El3MinD; + @Format(format = "El3MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El3MaxD; + @Format(format = "El3Dur%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public int[] El3Dur; + @Format(format = "TreasureClass1%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public String[] TreasureClass1; + @Format(format = "TreasureClass2%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public String[] TreasureClass2; + @Format(format = "TreasureClass3%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public String[] TreasureClass3; + @Format(format = "TreasureClass4%s", values = {"", "(N)", "(H)"}, endIndex = 3) + public String[] TreasureClass4; } diff --git a/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStatsTableImpl.java b/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStatsTableImpl.java index 57a740c5..67271d1b 100644 --- a/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStatsTableImpl.java +++ b/excel/excel-test/src/main/java/com/riiablo/excel/txt/MonStatsTableImpl.java @@ -3,5 +3,7 @@ package com.riiablo.excel.txt; import com.riiablo.excel.Table; public class MonStatsTableImpl extends Table { - private MonStatsTableImpl() {} + private MonStatsTableImpl() { + super(MonStats.class); + } }