From dfe7fde7e3c5063af206c408ec4f5130a3501d23 Mon Sep 17 00:00:00 2001 From: Oskar Wiksten Date: Mon, 15 Jul 2013 16:38:28 +0200 Subject: [PATCH] Refactor JSON array parser to not create as many "new ArrayList<>" instances --- .../rpg/AndorsTrail/model/item/DropList.java | 3 -- .../parsers/ConversationListParser.java | 20 ++++------ .../resource/parsers/DropListParser.java | 18 +++------ .../resource/parsers/ItemTraitsParser.java | 40 +++++++------------ .../resource/parsers/QuestParser.java | 15 +++---- .../parsers/json/JsonArrayParserFor.java | 25 ++++++++++++ 6 files changed, 59 insertions(+), 62 deletions(-) create mode 100644 AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonArrayParserFor.java diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/DropList.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/DropList.java index 8cafe1f4d..19e0256f6 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/DropList.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/DropList.java @@ -13,9 +13,6 @@ public final class DropList { public DropList(DropItem[] items) { this.items = items; } - public DropList(Collection items) { - this.items = items.toArray(new DropItem[items.size()]); - } public void createRandomLoot(Loot loot, Player player) { for (DropItem item : items) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java index e1129f1c2..320d74fc4 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ConversationListParser.java @@ -6,21 +6,19 @@ import com.gpl.rpg.AndorsTrail.conversation.Phrase.Reply; import com.gpl.rpg.AndorsTrail.conversation.Phrase.Reward; import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; +import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonParserFor; import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.Pair; import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; - public final class ConversationListParser extends JsonCollectionParserFor { private final TranslationLoader translationLoader; - private final JsonParserFor replyParser = new JsonParserFor() { + private final JsonArrayParserFor replyParser = new JsonArrayParserFor(Reply.class) { @Override protected Reply parseObject(JSONObject o) throws JSONException { JSONObject requires = o.optJSONObject(JsonFieldNames.Reply.requires); @@ -48,7 +46,7 @@ public final class ConversationListParser extends JsonCollectionParserFor rewardParser = new JsonParserFor() { + private final JsonArrayParserFor rewardParser = new JsonArrayParserFor(Reward.class) { @Override protected Reward parseObject(JSONObject o) throws JSONException { return new Reward( @@ -67,21 +65,17 @@ public final class ConversationListParser extends JsonCollectionParserFor parseObject(JSONObject o) throws JSONException { final String id = o.getString(JsonFieldNames.Phrase.phraseID); - final ArrayList replies = new ArrayList(); - final ArrayList rewards = new ArrayList(); + Reply[] _replies = null; + Reward[] _rewards = null; try { - replyParser.parseRows(o.optJSONArray(JsonFieldNames.Phrase.replies), replies); - rewardParser.parseRows(o.optJSONArray(JsonFieldNames.Phrase.rewards), rewards); + _replies = replyParser.parseArray(o.optJSONArray(JsonFieldNames.Phrase.replies)); + _rewards = rewardParser.parseArray(o.optJSONArray(JsonFieldNames.Phrase.rewards)); } catch (JSONException e) { if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) { L.log("ERROR: parsing phrase " + id + " : " + e.getMessage()); } } - final Reply[] _replies = replies.toArray(new Reply[replies.size()]); - Reward[] _rewards = rewards.toArray(new Reward[rewards.size()]); - if (_rewards.length == 0) _rewards = null; - return new Pair(id, new Phrase( translationLoader.translateConversationPhrase(o.optString(JsonFieldNames.Phrase.message, null)) , _replies diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java index 341bc6091..a770013ac 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/DropListParser.java @@ -1,26 +1,23 @@ package com.gpl.rpg.AndorsTrail.resource.parsers; -import java.util.ArrayList; - import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.model.item.DropList; -import com.gpl.rpg.AndorsTrail.model.item.ItemTypeCollection; import com.gpl.rpg.AndorsTrail.model.item.DropList.DropItem; +import com.gpl.rpg.AndorsTrail.model.item.ItemTypeCollection; +import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonParserFor; import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.Pair; -import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public final class DropListParser extends JsonCollectionParserFor { - private final JsonParserFor dropItemParser; + private final JsonArrayParserFor dropItemParser; public DropListParser(final ItemTypeCollection itemTypes) { - this.dropItemParser = new JsonParserFor() { + this.dropItemParser = new JsonArrayParserFor(DropItem.class) { @Override protected DropItem parseObject(JSONObject o) throws JSONException { return new DropItem( @@ -35,13 +32,10 @@ public final class DropListParser extends JsonCollectionParserFor { @Override protected Pair parseObject(JSONObject o) throws JSONException { String droplistID = o.getString(JsonFieldNames.DropList.dropListID); - - JSONArray array = o.getJSONArray(JsonFieldNames.DropList.items); - final ArrayList items = new ArrayList(); - dropItemParser.parseRows(array, items); + DropItem[] items = dropItemParser.parseArray(o.getJSONArray(JsonFieldNames.DropList.items)); if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { - if (items.size() <= 0) { + if (items == null) { L.log("OPTIMIZE: Droplist \"" + droplistID + "\" has no dropped items."); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java index 7b515670a..69c693ee4 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java @@ -8,21 +8,19 @@ import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits; import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; +import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonParserFor; import com.gpl.rpg.AndorsTrail.util.ConstRange; import com.gpl.rpg.AndorsTrail.util.L; import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; - public final class ItemTraitsParser { - private final JsonParserFor actorConditionEffectParser_withDuration; - private final JsonParserFor actorConditionEffectParser_withoutDuration; + private final JsonArrayParserFor actorConditionEffectParser_withDuration; + private final JsonArrayParserFor actorConditionEffectParser_withoutDuration; public ItemTraitsParser(final ActorConditionTypeCollection actorConditionTypes) { - this.actorConditionEffectParser_withDuration = new JsonParserFor() { + this.actorConditionEffectParser_withDuration = new JsonArrayParserFor(ActorConditionEffect.class) { @Override protected ActorConditionEffect parseObject(JSONObject o) throws JSONException { return new ActorConditionEffect( @@ -33,7 +31,7 @@ public final class ItemTraitsParser { ); } }; - this.actorConditionEffectParser_withoutDuration = new JsonParserFor() { + this.actorConditionEffectParser_withoutDuration = new JsonArrayParserFor(ActorConditionEffect.class) { @Override protected ActorConditionEffect parseObject(JSONObject o) throws JSONException { return new ActorConditionEffect( @@ -51,14 +49,12 @@ public final class ItemTraitsParser { ConstRange boostCurrentHP = ResourceParserUtils.parseConstRange(o.optJSONObject(JsonFieldNames.ItemTraits_OnUse.increaseCurrentHP)); ConstRange boostCurrentAP = ResourceParserUtils.parseConstRange(o.optJSONObject(JsonFieldNames.ItemTraits_OnUse.increaseCurrentAP)); - final ArrayList addedConditions_source = new ArrayList(); - final ArrayList addedConditions_target = new ArrayList(); - actorConditionEffectParser_withDuration.parseRows(o.optJSONArray(JsonFieldNames.ItemTraits_OnUse.conditionsSource), addedConditions_source); - actorConditionEffectParser_withDuration.parseRows(o.optJSONArray(JsonFieldNames.ItemTraits_OnUse.conditionsTarget), addedConditions_target); + ActorConditionEffect[] addedConditions_source = actorConditionEffectParser_withDuration.parseArray(o.optJSONArray(JsonFieldNames.ItemTraits_OnUse.conditionsSource)); + ActorConditionEffect[] addedConditions_target = actorConditionEffectParser_withDuration.parseArray(o.optJSONArray(JsonFieldNames.ItemTraits_OnUse.conditionsTarget)); if ( boostCurrentHP == null && boostCurrentAP == null - && addedConditions_source.isEmpty() - && addedConditions_target.isEmpty() + && addedConditions_source == null + && addedConditions_target == null ) { if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { L.log("OPTIMIZE: Tried to parseItemTraits_OnUse , where hasEffect=" + o.toString() + ", but all data was empty."); @@ -71,8 +67,8 @@ public final class ItemTraitsParser { ,boostCurrentHP ,boostCurrentAP ) - ,listToArray(addedConditions_source) - ,listToArray(addedConditions_target) + ,addedConditions_source + ,addedConditions_target ); } } @@ -81,21 +77,15 @@ public final class ItemTraitsParser { if (o == null) return null; AbilityModifierTraits stats = ResourceParserUtils.parseAbilityModifierTraits(o); - final ArrayList addedConditions = new ArrayList(); - actorConditionEffectParser_withoutDuration.parseRows(o.optJSONArray(JsonFieldNames.ItemTraits_OnEquip.addedConditions), addedConditions); - - if (stats == null && addedConditions.isEmpty()) { + ActorConditionEffect[] addedConditions = actorConditionEffectParser_withoutDuration.parseArray(o.optJSONArray(JsonFieldNames.ItemTraits_OnEquip.addedConditions)); + + if (stats == null && addedConditions == null) { if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { L.log("OPTIMIZE: Tried to parseItemTraits_OnEquip , where hasEffect=" + o.toString() + ", but all data was empty."); } return null; } else { - return new ItemTraits_OnEquip(stats, listToArray(addedConditions)); + return new ItemTraits_OnEquip(stats, addedConditions); } } - - private static ActorConditionEffect[] listToArray(ArrayList list) { - if (list.isEmpty()) return null; - return list.toArray(new ActorConditionEffect[list.size()]); - } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java index 6b074c672..2ab18c6d9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/QuestParser.java @@ -3,22 +3,21 @@ package com.gpl.rpg.AndorsTrail.resource.parsers; import com.gpl.rpg.AndorsTrail.model.quest.Quest; import com.gpl.rpg.AndorsTrail.model.quest.QuestLogEntry; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; +import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; -import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonParserFor; import com.gpl.rpg.AndorsTrail.util.Pair; import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import java.util.Comparator; public final class QuestParser extends JsonCollectionParserFor { private final TranslationLoader translationLoader; private int sortOrder = 0; - private final JsonParserFor questLogEntryParser = new JsonParserFor() { + private final JsonArrayParserFor questLogEntryParser = new JsonArrayParserFor(QuestLogEntry.class) { @Override protected QuestLogEntry parseObject(JSONObject o) throws JSONException { return new QuestLogEntry( @@ -44,17 +43,15 @@ public final class QuestParser extends JsonCollectionParserFor { protected Pair parseObject(JSONObject o) throws JSONException { final String id = o.getString(JsonFieldNames.Quest.questID); - final ArrayList stages = new ArrayList(); - questLogEntryParser.parseRows(o.getJSONArray(JsonFieldNames.Quest.stages), stages); - Collections.sort(stages, sortByQuestProgress); - final QuestLogEntry[] stages_ = stages.toArray(new QuestLogEntry[stages.size()]); + QuestLogEntry[] stages = questLogEntryParser.parseArray(o.getJSONArray(JsonFieldNames.Quest.stages)); + Arrays.sort(stages, sortByQuestProgress); ++sortOrder; return new Pair(id, new Quest( id , translationLoader.translateQuestName(o.getString(JsonFieldNames.Quest.name)) - , stages_ + , stages , o.optInt(JsonFieldNames.Quest.showInLog, 0) > 0 , sortOrder )); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonArrayParserFor.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonArrayParserFor.java new file mode 100644 index 000000000..bca042c38 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/json/JsonArrayParserFor.java @@ -0,0 +1,25 @@ +package com.gpl.rpg.AndorsTrail.resource.parsers.json; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Array; +import java.util.ArrayList; + +public abstract class JsonArrayParserFor extends JsonParserFor { + private final Class classType; + + public JsonArrayParserFor(Class classType) { + if (classType == null) throw new IllegalArgumentException("classType for parseArray must not be null"); + this.classType = classType; + } + + public T[] parseArray(JSONArray array) throws JSONException { + if (array == null) return null; + final ArrayList arrayList = new ArrayList(array.length()); + parseRows(array, arrayList); + if (arrayList.isEmpty()) return null; + return arrayList.toArray((T[]) Array.newInstance(classType, arrayList.size())); + } +}