From c36a5b69964657328562d023dc1cb29e75a93cb4 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Mon, 16 Oct 2017 11:32:21 -0500 Subject: [PATCH 01/20] Simplified SaveAndLoadPerformer --- .../character/SaveAndLoadPerformer.java | 56 +------------------ 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java index b2d5754..5c1e591 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java @@ -40,9 +40,7 @@ public static String save(PlayerCharacter playerCharacter){ * @return json string of playerCharacter */ public static String save(int characterIndex) { - GsonBuilder gson = new GsonBuilder(); - gson.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); - return gson.create().toJson(Portfolio.get().getPlayerCharacter(characterIndex)); + return new Gson().toJson(Portfolio.get().getPlayerCharacter(characterIndex)); } /** @@ -51,56 +49,6 @@ public static String save(int characterIndex) { * @return the generated playerCharacter */ public static PlayerCharacter load(String jsonString){ - PlayerCharacter returnCharacter = new PlayerCharacter(); - JsonObject loadedData = (JsonObject) new Gson().fromJson(jsonString, JsonElement.class); - - for (Score score: Score.values()) { - int loadedScore = loadedData.getAsJsonObject("mScores").getAsJsonObject(score.toString()).get("mScore").getAsInt(); - returnCharacter.getScore(score).setScore(loadedScore); - } - Gson gson = new Gson(); - - returnCharacter.setAge(gson.fromJson(loadedData.get("mAge"), Integer.class)); - returnCharacter.setBreastplate(gson.fromJson(loadedData.get("mBreastplate"), Armor.class)); - returnCharacter.setCharClass(gson.fromJson(loadedData.get("mCharClass"), Barbarian.class)); - returnCharacter.setCurrentWeapon(gson.fromJson(loadedData.get("mCurrentWeapon"), Weapon.class)); - returnCharacter.setGender(gson.fromJson(loadedData.get("mGender"), Gender.class)); - returnCharacter.setHelmet(gson.fromJson(loadedData.get("mHelmet"), Armor.class)); - returnCharacter.setMoney(gson.fromJson(loadedData.get("mMoney"), HashMap.class)); - returnCharacter.setName(loadedData.get("mName").getAsString()); - returnCharacter.setInventory(gson.fromJson(loadedData.get("mInventory"), ArrayList.class)); - returnCharacter.setShield(gson.fromJson(loadedData.get("mShield"), Armor.class)); - - return returnCharacter; - } -} - -/** - * Custom serializer for transforming the PlayerCharacter class into json. - */ -class CharacterSerializer implements JsonSerializer { - @Override - public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializationContext context) { - BaseClass characterClass = src.getCharClass(); - characterClass.setCharacter(null); - - JsonObject rootObject = new JsonObject(); - rootObject.add("mScores", context.serialize(src.getScores())); - rootObject.add("mCharClass", context.serialize(src.getCharClass())); - rootObject.add("mGender", context.serialize(src.getGender())); - rootObject.add("mMoney", context.serialize(src.getMoney())); - rootObject.add("mAge", context.serialize(src.getAge())); - rootObject.add("mName",context.serialize(src.getName())); - rootObject.add("mInventory", context.serialize(src.getInventory())); - rootObject.add("mCurrentWeapon", context.serialize(src.getCurrentWeapon())); - rootObject.add("mHelmet", context.serialize(src.getHelmet())); - rootObject.add("mBreastplate", context.serialize(src.getBreastplate())); - rootObject.add("mShield",context.serialize(src.getShield())); - - JsonElement classJson = context.serialize(characterClass); - rootObject.add("mCharClass", classJson); - - characterClass.setCharacter(src); - return rootObject; + return new Gson().fromJson(jsonString, PlayerCharacter.class); } } From f7e8a9afd39edf7ce9a6ad5b98fc8b3976aa41ca Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Mon, 16 Oct 2017 12:06:07 -0500 Subject: [PATCH 02/20] Changed name to fit with conventions. --- .../layout/{spinner_weapon_item.xml => spinner_item_weapon.xml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename MazesAndMinotaurs/app/src/main/res/layout/{spinner_weapon_item.xml => spinner_item_weapon.xml} (100%) diff --git a/MazesAndMinotaurs/app/src/main/res/layout/spinner_weapon_item.xml b/MazesAndMinotaurs/app/src/main/res/layout/spinner_item_weapon.xml similarity index 100% rename from MazesAndMinotaurs/app/src/main/res/layout/spinner_weapon_item.xml rename to MazesAndMinotaurs/app/src/main/res/layout/spinner_item_weapon.xml From ae7ede85c077eb276610b03d59924dc26edfd7e4 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Mon, 16 Oct 2017 12:13:46 -0500 Subject: [PATCH 03/20] Added layout for character spinner items. --- .../res/layout/spinner_item_character.xml | 29 +++++++++++++++++++ .../app/src/main/res/values/strings.xml | 5 ++++ MazesAndMinotaurs/instapk.log | 4 +-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 MazesAndMinotaurs/app/src/main/res/layout/spinner_item_character.xml diff --git a/MazesAndMinotaurs/app/src/main/res/layout/spinner_item_character.xml b/MazesAndMinotaurs/app/src/main/res/layout/spinner_item_character.xml new file mode 100644 index 0000000..0a55923 --- /dev/null +++ b/MazesAndMinotaurs/app/src/main/res/layout/spinner_item_character.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/MazesAndMinotaurs/app/src/main/res/values/strings.xml b/MazesAndMinotaurs/app/src/main/res/values/strings.xml index e6d8cec..fcdeb0b 100644 --- a/MazesAndMinotaurs/app/src/main/res/values/strings.xml +++ b/MazesAndMinotaurs/app/src/main/res/values/strings.xml @@ -66,4 +66,9 @@ %s Old Value\n%2d New Value Enter a number + + + Name: %s + Class: %s + Level: %s diff --git a/MazesAndMinotaurs/instapk.log b/MazesAndMinotaurs/instapk.log index 6b941f2..3fa60df 100644 --- a/MazesAndMinotaurs/instapk.log +++ b/MazesAndMinotaurs/instapk.log @@ -1,2 +1,2 @@ -Oct 12, 2017 12:14:59 PM com.pytenlabs.instapk.helpers.LogHelper init -INFO: Windows 7, 6.1, amd64, Android Studio AI-162.2228.14 +Oct 16, 2017 11:15:14 AM com.pytenlabs.instapk.helpers.LogHelper init +INFO: Linux, 4.9.0-3-amd64, amd64, Android Studio AI-162.2228.14 From 7875580dcc127516ebfe1723b6dea2f894a31c37 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Mon, 16 Oct 2017 12:59:39 -0500 Subject: [PATCH 04/20] Added save icon. --- .../app/src/main/res/drawable-hdpi/ic_save.png | Bin 0 -> 446 bytes .../app/src/main/res/drawable-mdpi/ic_save.png | Bin 0 -> 320 bytes .../app/src/main/res/drawable-xhdpi/ic_save.png | Bin 0 -> 548 bytes .../app/src/main/res/drawable-xxhdpi/ic_save.png | Bin 0 -> 896 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 MazesAndMinotaurs/app/src/main/res/drawable-hdpi/ic_save.png create mode 100644 MazesAndMinotaurs/app/src/main/res/drawable-mdpi/ic_save.png create mode 100644 MazesAndMinotaurs/app/src/main/res/drawable-xhdpi/ic_save.png create mode 100644 MazesAndMinotaurs/app/src/main/res/drawable-xxhdpi/ic_save.png diff --git a/MazesAndMinotaurs/app/src/main/res/drawable-hdpi/ic_save.png b/MazesAndMinotaurs/app/src/main/res/drawable-hdpi/ic_save.png new file mode 100644 index 0000000000000000000000000000000000000000..897d25226cd854c6284aeee910aea14c4f6fbfd0 GIT binary patch literal 446 zcmV;v0YUzWP)J2=&=L9rvE?z;FukNO1qus`4Kw+ zsxS&imR*i3aHHV+fnyaK`o4czV)olC%jkR+KJe#ltqUGwzF4;sv=Wp~^i5E;AyJ9N z^IM&n*9Isa?&>sh)EAKqG;{+UfOjsfG$!C#82~A8Vf$vLoiJ o&A{m_>Xoj!}78VL5I{>ILheC@fa|F=m(?FVmbO(@5Cj(RF z2$)8o15(I|LW)CzMh+m}5j1oF*bxKmfSE(b0kp!S4j6R+RU81!A=5#*#K_3V7K&4W zcm};3Fa>D22D(0ADW?gNqqzfsK6S^V*Nf&3FfcF>z@^vB%uJZ(4hRhmWyVvLv(nrF zdU|>?xbzwt8p_k$0r=_&91RlcXG35@4Aa)uW`pTbQBh$B`aXgx*$~zwBc{CvRGSO5 zI2Xhwviz7z&;d{bX;KOT9gs!P0p{lBd>}`V5E8^#JPjCa*`Ox>Xvb$1paTG`Qy+JH S>Wj1h0000H2_B?~daqb|5Jb?sQ9C5oabilV3?QcA5i8jbUMz5WdQMElE>g<*J8sZ?fi3qFG2 zv~MzKV-RY!+Gf#$&lLhXzf;8EbAtc}FGU70b_fHUoF{J<#uP0jYAk3DY=R)c%OOjxb$ZDJ`5cNoCdjc~ m*oE)=8zqXOD2k$}A^HYRA7#KB#y_wC0000V0QO(aSW-r^>*&t?8^Zn?bfAQ zpJiDc1zSZ|vD{jcc}po&>&H?5rp>RGS%|P%IeysfRk}}MUxU^Cf6?a~AGCXxZ#FUC z={a9sW|!f$d2^mWyI!6D&Ns`nMZk$e5kgGL)azPgJl8K>ljpGb+p^!?NAiFE^_O(+ zdpLbhoVM#z+w-@zPwIJJx_>I_gQvifz*yP-$U577(uLQNOb_PBdMeGHEOb?GMVYJW!}IIh zUcNms;mPv2_2og2HmnY;vNlrr5twxF=|}IEZ!@kjisZR7Xx!*y2-qOYxFErr$>Crb zOGDFJ4u;##3=WM9CcrR)gMd@a8r5(fHpVKBgyP+Qxfo6uJo9!Ta9J z%kr=tk6L@}rAAlH&)c~A4F`qvCI&J}$Tk{4=w{U8~c_BXxd?dEZig|5b#+TKk{d=9@MX zLeK58^uPDnmO&`0|4W`;+T87RhRh0)uj`lEN^&!ZZRzG>Fm9N*_D<@W0)B=x?p+Cn z-x(O589!)Qd#CgW4^XZ$dgtp0JPd6Y>UOWavo)KW!MSAj-N)OCu5;Qj%+P(YXYC!< zJZ^?(5u2v&_Df|xP{X$8N_0}%+;SV=y^IYh0##yciPL9xdB{E1*=}Vj)$5#OpU<#i zbA^Vy`Eq`?xRXxc_~s0$GPWp3mwzCX2*Aw+ISS_Dr}p(b&vjq@K1~O z_ywL;ST*?x*Ub!*Te`0ApI>}Db7!ezVPO8N1Yh^9pQ>D@FMDy`s#~kjd-^(&oh8St z7%X4NyXx0nV!rx2{P=n83qRf+D&{s3f6ege)w!u(#Ezf;Y{49+@$HE512;JavDoPT zmmaVGuj(&e`BXvn#+sln|D*oD?P2RXskZHj^ZdXc^=s?z9%D(Gbo1!d$Zd;%cq*OV zDPG?#tNTiP^S8d37mJ>4RCkn5S~yMlasTF>H~HWxTtI8@Kc>dHcUrDzYJLHw4Nq4; Jmvv4FO#n% Date: Mon, 16 Oct 2017 13:27:37 -0500 Subject: [PATCH 05/20] Added action item, "Save Portfolio". --- MazesAndMinotaurs/app/src/main/res/menu/main.xml | 6 ++++++ MazesAndMinotaurs/app/src/main/res/values/strings.xml | 1 + 2 files changed, 7 insertions(+) diff --git a/MazesAndMinotaurs/app/src/main/res/menu/main.xml b/MazesAndMinotaurs/app/src/main/res/menu/main.xml index b62455b..43f3351 100644 --- a/MazesAndMinotaurs/app/src/main/res/menu/main.xml +++ b/MazesAndMinotaurs/app/src/main/res/menu/main.xml @@ -6,4 +6,10 @@ android:orderInCategory="100" android:title="@string/action_settings" app:showAsAction="never"/> + + diff --git a/MazesAndMinotaurs/app/src/main/res/values/strings.xml b/MazesAndMinotaurs/app/src/main/res/values/strings.xml index fcdeb0b..601bb01 100644 --- a/MazesAndMinotaurs/app/src/main/res/values/strings.xml +++ b/MazesAndMinotaurs/app/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ Create New Character Play Existing Character Delete A Character + Save Portfolio Web Resources From 6235abc01e75c5dca3dbb33299f9e42d15cdc008 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Mon, 16 Oct 2017 13:28:07 -0500 Subject: [PATCH 06/20] Added methods to serialize Portfolio. --- .../com/example/cis/mazeminotaurs/Portfolio.java | 2 ++ .../character/SaveAndLoadPerformer.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/Portfolio.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/Portfolio.java index a92cecb..13ff308 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/Portfolio.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/Portfolio.java @@ -10,6 +10,8 @@ */ public class Portfolio { + public static final String FILENAME = "SavedPortfolio"; + private static final String TAG = Portfolio.class.getName(); private ArrayList portfolio; private static Portfolio sPortfolio; diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java index 5c1e591..2daa552 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java @@ -12,6 +12,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; +import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.ArrayList; @@ -51,4 +52,19 @@ public static String save(int characterIndex) { public static PlayerCharacter load(String jsonString){ return new Gson().fromJson(jsonString, PlayerCharacter.class); } + + public static String savePortfolio() { + Gson gson = new Gson(); + Type listType = new TypeToken>() { + }.getType(); + return gson.toJson(Portfolio.get(), listType); + } + + public static void loadPortfolio(String jsonString) { + Gson gson = new Gson(); + Type listType = new TypeToken>() { + }.getType(); + Portfolio newPort = gson.fromJson(jsonString, listType); + Portfolio.get().setPortfolio(newPort.getPortfolio()); + } } From d739886888ee6169ac8257355c008e9686af909d Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Tue, 17 Oct 2017 11:22:37 -0500 Subject: [PATCH 07/20] Reverted SaveAndLoadPerformer --- .../character/SaveAndLoadPerformer.java | 62 +++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java index 2daa552..f92651b 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java @@ -41,7 +41,9 @@ public static String save(PlayerCharacter playerCharacter){ * @return json string of playerCharacter */ public static String save(int characterIndex) { - return new Gson().toJson(Portfolio.get().getPlayerCharacter(characterIndex)); + GsonBuilder gson = new GsonBuilder(); + gson.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); + return gson.create().toJson(Portfolio.get().getPlayerCharacter(characterIndex)); } /** @@ -50,21 +52,71 @@ public static String save(int characterIndex) { * @return the generated playerCharacter */ public static PlayerCharacter load(String jsonString){ - return new Gson().fromJson(jsonString, PlayerCharacter.class); + PlayerCharacter returnCharacter = new PlayerCharacter(); + JsonObject loadedData = (JsonObject) new Gson().fromJson(jsonString, JsonElement.class); + + for (Score score : Score.values()) { + int loadedScore = loadedData.getAsJsonObject("mScores").getAsJsonObject(score.toString()).get("mScore").getAsInt(); + returnCharacter.getScore(score).setScore(loadedScore); + } + Gson gson = new Gson(); + + returnCharacter.setAge(gson.fromJson(loadedData.get("mAge"), Integer.class)); + returnCharacter.setBreastplate(gson.fromJson(loadedData.get("mBreastplate"), Armor.class)); + returnCharacter.setCharClass(gson.fromJson(loadedData.get("mCharClass"), Barbarian.class)); + returnCharacter.setCurrentWeapon(gson.fromJson(loadedData.get("mCurrentWeapon"), Weapon.class)); + returnCharacter.setGender(gson.fromJson(loadedData.get("mGender"), Gender.class)); + returnCharacter.setHelmet(gson.fromJson(loadedData.get("mHelmet"), Armor.class)); + returnCharacter.setMoney(gson.fromJson(loadedData.get("mMoney"), HashMap.class)); + returnCharacter.setName(loadedData.get("mName").getAsString()); + returnCharacter.setInventory(gson.fromJson(loadedData.get("mInventory"), ArrayList.class)); + returnCharacter.setShield(gson.fromJson(loadedData.get("mShield"), Armor.class)); + + return returnCharacter; } public static String savePortfolio() { Gson gson = new Gson(); Type listType = new TypeToken>() { }.getType(); - return gson.toJson(Portfolio.get(), listType); + return gson.toJson(Portfolio.get().getPortfolio(), listType); } public static void loadPortfolio(String jsonString) { Gson gson = new Gson(); Type listType = new TypeToken>() { }.getType(); - Portfolio newPort = gson.fromJson(jsonString, listType); - Portfolio.get().setPortfolio(newPort.getPortfolio()); + ArrayList newPort = gson.fromJson(jsonString, listType); + Portfolio.get().setPortfolio(newPort); + } +} + +/** + * Custom serializer for transforming the PlayerCharacter class into json. + */ +class CharacterSerializer implements JsonSerializer { + @Override + public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializationContext context) { + BaseClass characterClass = src.getCharClass(); + characterClass.setCharacter(null); + + JsonObject rootObject = new JsonObject(); + rootObject.add("mScores", context.serialize(src.getScores())); + rootObject.add("mCharClass", context.serialize(src.getCharClass())); + rootObject.add("mGender", context.serialize(src.getGender())); + rootObject.add("mMoney", context.serialize(src.getMoney())); + rootObject.add("mAge", context.serialize(src.getAge())); + rootObject.add("mName", context.serialize(src.getName())); + rootObject.add("mInventory", context.serialize(src.getInventory())); + rootObject.add("mCurrentWeapon", context.serialize(src.getCurrentWeapon())); + rootObject.add("mHelmet", context.serialize(src.getHelmet())); + rootObject.add("mBreastplate", context.serialize(src.getBreastplate())); + rootObject.add("mShield", context.serialize(src.getShield())); + + JsonElement classJson = context.serialize(characterClass); + rootObject.add("mCharClass", classJson); + + characterClass.setCharacter(src); + return rootObject; } } From 1a8ba759712c0aa806158399d10fcf68916653f5 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Tue, 17 Oct 2017 12:20:34 -0500 Subject: [PATCH 08/20] Seperated SaveAndLoadPerformer and CharacterSerializer --- .../character/CharacterSerializer.java | 76 +++++++++++++++++++ .../character/SaveAndLoadPerformer.java | 38 +--------- 2 files changed, 79 insertions(+), 35 deletions(-) create mode 100644 MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java new file mode 100644 index 0000000..4a7cd8d --- /dev/null +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java @@ -0,0 +1,76 @@ +package com.example.cis.mazeminotaurs.character; + +/** + * Created by jsmith on 10/17/17. + */ + +import com.example.cis.mazeminotaurs.Armor; +import com.example.cis.mazeminotaurs.Equipment; +import com.example.cis.mazeminotaurs.Weapon; +import com.example.cis.mazeminotaurs.character.Gender; +import com.example.cis.mazeminotaurs.character.Money; +import com.example.cis.mazeminotaurs.character.PlayerCharacter; +import com.example.cis.mazeminotaurs.character.classes.BaseClass; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + * Custom serializer for transforming the PlayerCharacter class into json. + */ +public class CharacterSerializer implements JsonSerializer, JsonDeserializer { + @Override + public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializationContext context) { + BaseClass characterClass = src.getCharClass(); + characterClass.setCharacter(null); + + JsonObject rootObject = new JsonObject(); + rootObject.add("mScores", context.serialize(src.getScores())); + rootObject.add("mCharClass", context.serialize(src.getCharClass())); + rootObject.add("mGender", context.serialize(src.getGender())); + rootObject.add("mMoney", context.serialize(src.getMoney())); + rootObject.add("mAge", context.serialize(src.getAge())); + rootObject.add("mName", context.serialize(src.getName())); + rootObject.add("mInventory", context.serialize(src.getInventory())); + rootObject.add("mCurrentWeapon", context.serialize(src.getCurrentWeapon())); + rootObject.add("mHelmet", context.serialize(src.getHelmet())); + rootObject.add("mBreastplate", context.serialize(src.getBreastplate())); + rootObject.add("mShield", context.serialize(src.getShield())); + + JsonElement classJson = context.serialize(characterClass); + rootObject.add("mCharClass", classJson); + + characterClass.setCharacter(src); + return rootObject; + } + + @Override + public PlayerCharacter deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + final PlayerCharacter newCharacter = new PlayerCharacter(); + JsonObject loadedData = json.getAsJsonObject(); + for (Map.Entry e : loadedData.get("mCharClass").getAsJsonObject().entrySet()) { + System.out.println(e); + } + newCharacter.setAge((int) context.deserialize(loadedData.get("mAge"), Integer.class)); + newCharacter.setBreastplate((Armor) context.deserialize(loadedData.get("mBreastplate"), Armor.class)); + newCharacter.setCharClass((BaseClass) context.deserialize(loadedData.get("mCharClass"), BaseClass.class)); + newCharacter.setCurrentWeapon((Weapon) context.deserialize(loadedData.get("mCurrentWeapon"), Weapon.class)); + newCharacter.setGender((Gender) context.deserialize(loadedData.get("mGender"), Gender.class)); + newCharacter.setHelmet((Armor) context.deserialize(loadedData.get("mHelmet"), Armor.class)); + newCharacter.setMoney((HashMap) context.deserialize(loadedData.get("mMoney"), HashMap.class)); + newCharacter.setName(loadedData.get("mName").getAsString()); + newCharacter.setInventory((ArrayList) context.deserialize(loadedData.get("mInventory"), ArrayList.class)); + newCharacter.setShield((Armor) context.deserialize(loadedData.get("mShield"), Armor.class)); + + return newCharacter; + } +} diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java index f92651b..9cd9f46 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java @@ -4,14 +4,11 @@ import com.example.cis.mazeminotaurs.Portfolio; import com.example.cis.mazeminotaurs.Weapon; import com.example.cis.mazeminotaurs.character.classes.Barbarian; -import com.example.cis.mazeminotaurs.character.classes.BaseClass; import com.example.cis.mazeminotaurs.character.stats.Score; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; @@ -83,40 +80,11 @@ public static String savePortfolio() { } public static void loadPortfolio(String jsonString) { - Gson gson = new Gson(); + GsonBuilder builder = new GsonBuilder(); Type listType = new TypeToken>() { }.getType(); - ArrayList newPort = gson.fromJson(jsonString, listType); + builder.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); + ArrayList newPort = builder.create().fromJson(jsonString, listType); Portfolio.get().setPortfolio(newPort); } } - -/** - * Custom serializer for transforming the PlayerCharacter class into json. - */ -class CharacterSerializer implements JsonSerializer { - @Override - public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializationContext context) { - BaseClass characterClass = src.getCharClass(); - characterClass.setCharacter(null); - - JsonObject rootObject = new JsonObject(); - rootObject.add("mScores", context.serialize(src.getScores())); - rootObject.add("mCharClass", context.serialize(src.getCharClass())); - rootObject.add("mGender", context.serialize(src.getGender())); - rootObject.add("mMoney", context.serialize(src.getMoney())); - rootObject.add("mAge", context.serialize(src.getAge())); - rootObject.add("mName", context.serialize(src.getName())); - rootObject.add("mInventory", context.serialize(src.getInventory())); - rootObject.add("mCurrentWeapon", context.serialize(src.getCurrentWeapon())); - rootObject.add("mHelmet", context.serialize(src.getHelmet())); - rootObject.add("mBreastplate", context.serialize(src.getBreastplate())); - rootObject.add("mShield", context.serialize(src.getShield())); - - JsonElement classJson = context.serialize(characterClass); - rootObject.add("mCharClass", classJson); - - characterClass.setCharacter(src); - return rootObject; - } -} From fab7fafc1716369a3656b6c58de13a9b75a1c3fb Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Tue, 17 Oct 2017 12:38:11 -0500 Subject: [PATCH 09/20] Added RuntimeTypeAdapterFactory. --- .../RuntimeTypeAdapterFactory.java | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java diff --git a/MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java b/MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java new file mode 100644 index 0000000..1dd950d --- /dev/null +++ b/MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson.typeadapters; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.internal.Streams; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +/** + * Adapts values whose runtime type may differ from their declaration type. This + * is necessary when a field's type is not the same type that GSON should create + * when deserializing that field. For example, consider these types: + *
   {@code
+ *   abstract class Shape {
+ *     int x;
+ *     int y;
+ *   }
+ *   class Circle extends Shape {
+ *     int radius;
+ *   }
+ *   class Rectangle extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Diamond extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Drawing {
+ *     Shape bottomShape;
+ *     Shape topShape;
+ *   }
+ * }
+ *

Without additional type information, the serialized JSON is ambiguous. Is + * the bottom shape in this drawing a rectangle or a diamond?

   {@code
+ *   {
+ *     "bottomShape": {
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * This class addresses this problem by adding type information to the + * serialized JSON and honoring that type information when the JSON is + * deserialized:
   {@code
+ *   {
+ *     "bottomShape": {
+ *       "type": "Diamond",
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "type": "Circle",
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * Both the type field name ({@code "type"}) and the type labels ({@code + * "Rectangle"}) are configurable. + *

+ *

Registering Types

+ * Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field + * name to the {@link #of} factory method. If you don't supply an explicit type + * field name, {@code "type"} will be used.
   {@code
+ *   RuntimeTypeAdapterFactory shapeAdapterFactory
+ *       = RuntimeTypeAdapterFactory.of(Shape.class, "type");
+ * }
+ * Next register all of your subtypes. Every subtype must be explicitly + * registered. This protects your application from injection attacks. If you + * don't supply an explicit type label, the type's simple name will be used. + *
   {@code
+ *   shapeAdapter.registerSubtype(Rectangle.class, "Rectangle");
+ *   shapeAdapter.registerSubtype(Circle.class, "Circle");
+ *   shapeAdapter.registerSubtype(Diamond.class, "Diamond");
+ * }
+ * Finally, register the type adapter factory in your application's GSON builder: + *
   {@code
+ *   Gson gson = new GsonBuilder()
+ *       .registerTypeAdapterFactory(shapeAdapterFactory)
+ *       .create();
+ * }
+ * Like {@code GsonBuilder}, this API supports chaining:
   {@code
+ *   RuntimeTypeAdapterFactory shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
+ *       .registerSubtype(Rectangle.class)
+ *       .registerSubtype(Circle.class)
+ *       .registerSubtype(Diamond.class);
+ * }
+ */ +public final class RuntimeTypeAdapterFactory implements TypeAdapterFactory { + private final Class baseType; + private final String typeFieldName; + private final Map> labelToSubtype = new LinkedHashMap>(); + private final Map, String> subtypeToLabel = new LinkedHashMap, String>(); + + private RuntimeTypeAdapterFactory(Class baseType, String typeFieldName) { + if (typeFieldName == null || baseType == null) { + throw new NullPointerException(); + } + this.baseType = baseType; + this.typeFieldName = typeFieldName; + } + + /** + * Creates a new runtime type adapter using for {@code baseType} using {@code + * typeFieldName} as the type field name. Type field names are case sensitive. + */ + public static RuntimeTypeAdapterFactory of(Class baseType, String typeFieldName) { + return new RuntimeTypeAdapterFactory(baseType, typeFieldName); + } + + /** + * Creates a new runtime type adapter for {@code baseType} using {@code "type"} as + * the type field name. + */ + public static RuntimeTypeAdapterFactory of(Class baseType) { + return new RuntimeTypeAdapterFactory(baseType, "type"); + } + + /** + * Registers {@code type} identified by {@code label}. Labels are case + * sensitive. + * + * @throws IllegalArgumentException if either {@code type} or {@code label} + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type, String label) { + if (type == null || label == null) { + throw new NullPointerException(); + } + if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) { + throw new IllegalArgumentException("types and labels must be unique"); + } + labelToSubtype.put(label, type); + subtypeToLabel.put(type, label); + return this; + } + + /** + * Registers {@code type} identified by its {@link Class#getSimpleName simple + * name}. Labels are case sensitive. + * + * @throws IllegalArgumentException if either {@code type} or its simple name + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type) { + return registerSubtype(type, type.getSimpleName()); + } + + public TypeAdapter create(Gson gson, TypeToken type) { + if (type.getRawType() != baseType) { + return null; + } + + final Map> labelToDelegate + = new LinkedHashMap>(); + final Map, TypeAdapter> subtypeToDelegate + = new LinkedHashMap, TypeAdapter>(); + for (Map.Entry> entry : labelToSubtype.entrySet()) { + TypeAdapter delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue())); + labelToDelegate.put(entry.getKey(), delegate); + subtypeToDelegate.put(entry.getValue(), delegate); + } + + return new TypeAdapter() { + @Override + public R read(JsonReader in) throws IOException { + JsonElement jsonElement = Streams.parse(in); + JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName); + if (labelJsonElement == null) { + throw new JsonParseException("cannot deserialize " + baseType + + " because it does not define a field named " + typeFieldName); + } + String label = labelJsonElement.getAsString(); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) labelToDelegate.get(label); + if (delegate == null) { + throw new JsonParseException("cannot deserialize " + baseType + " subtype named " + + label + "; did you forget to register a subtype?"); + } + return delegate.fromJsonTree(jsonElement); + } + + @Override + public void write(JsonWriter out, R value) throws IOException { + Class srcType = value.getClass(); + String label = subtypeToLabel.get(srcType); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) subtypeToDelegate.get(srcType); + if (delegate == null) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + "; did you forget to register a subtype?"); + } + JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject(); + if (jsonObject.has(typeFieldName)) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + " because it already defines a field named " + typeFieldName); + } + JsonObject clone = new JsonObject(); + clone.add(typeFieldName, new JsonPrimitive(label)); + for (Map.Entry e : jsonObject.entrySet()) { + clone.add(e.getKey(), e.getValue()); + } + Streams.write(clone, out); + } + }.nullSafe(); + } +} \ No newline at end of file From 1128db70abecfe01e1f79d780ab32b5433b8ce60 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Tue, 17 Oct 2017 12:50:49 -0500 Subject: [PATCH 10/20] Fixed with solution located at https://github.com/google/gson/issues/712 --- .../com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java b/MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java index 1dd950d..c4d8202 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java +++ b/MazesAndMinotaurs/app/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java @@ -182,7 +182,7 @@ public RuntimeTypeAdapterFactory registerSubtype(Class type) { } public TypeAdapter create(Gson gson, TypeToken type) { - if (type.getRawType() != baseType) { + if (null == type || !baseType.isAssignableFrom(type.getRawType())) { return null; } From 63f1f2f85cfb3eff79cdead41868349673e7f1de Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 11:36:46 -0500 Subject: [PATCH 11/20] Serialization should finally work as intended aside from issue #34. --- .../mazeminotaurs/CharacterSheetFragment.java | 1 + .../example/cis/mazeminotaurs/MainMazes.java | 38 +++++++++++ .../character/CharacterSerializer.java | 28 ++++++-- .../character/SaveAndLoadPerformer.java | 65 +++++++++++++++---- MazesAndMinotaurs/instapk.log | 2 +- 5 files changed, 115 insertions(+), 19 deletions(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java index bfb63fe..875e223 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java @@ -208,6 +208,7 @@ public void onClick(View v){ }); mEquippedWeaponSpinner = (Spinner) rootView.findViewById(R.id.equipped_weapon_spinner); + System.out.println(mSheetPlayerCharacter.getInventory()); DetailedWeaponAdapter weaponAdapter = new DetailedWeaponAdapter(getContext(), mSheetPlayerCharacter.getWeapons()); mEquippedWeaponSpinner.setAdapter(weaponAdapter); //Get equipped weapon from character Class diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java index 23999a9..da66fba 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java @@ -1,5 +1,6 @@ package com.example.cis.mazeminotaurs; +import android.content.Context; import android.os.Bundle; import android.support.design.widget.NavigationView; import android.support.v4.app.Fragment; @@ -12,13 +13,24 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.widget.Toast; import com.example.cis.mazeminotaurs.NewCharacter.CharacterCreationFragment; import com.example.cis.mazeminotaurs.character.PlayerCharacter; +import com.example.cis.mazeminotaurs.character.SaveAndLoadPerformer; import com.example.cis.mazeminotaurs.web_resources.CompanionFragment; import com.example.cis.mazeminotaurs.web_resources.PlayerManualFragment; import com.example.cis.mazeminotaurs.web_resources.WebsiteFragment; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; + public class MainMazes extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @@ -28,6 +40,21 @@ public class MainMazes extends AppCompatActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + try { + String basePath = getApplicationContext().getFilesDir().getPath() + "/"; + FileInputStream fis = new FileInputStream(basePath + Portfolio.FILENAME); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(fis))); + + StringBuilder builder = new StringBuilder(); + String line = bufferedReader.readLine(); + while (line != null && !line.equals("")) { + builder.append(line); + line = bufferedReader.readLine(); + } + SaveAndLoadPerformer.loadPortfolio(builder.toString()); + } catch (IOException e) { + e.printStackTrace(); + } mPortfolio = Portfolio.get(); mEquipment = EquipmentDB.getInstance(); @@ -85,6 +112,17 @@ public boolean onOptionsItemSelected(MenuItem item) { //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; + } else if (id == R.id.action_save_portfolio) { + try { + FileOutputStream fos = getApplicationContext().openFileOutput(Portfolio.FILENAME, Context.MODE_PRIVATE); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos); + outputStreamWriter.write(SaveAndLoadPerformer.savePortfolio()); + outputStreamWriter.close(); + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return true; } return super.onOptionsItemSelected(item); diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java index 4a7cd8d..fb15f17 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java @@ -11,6 +11,7 @@ import com.example.cis.mazeminotaurs.character.Money; import com.example.cis.mazeminotaurs.character.PlayerCharacter; import com.example.cis.mazeminotaurs.character.classes.BaseClass; +import com.example.cis.mazeminotaurs.character.stats.Score; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -18,6 +19,7 @@ import com.google.gson.JsonParseException; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; +import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.ArrayList; @@ -33,14 +35,19 @@ public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializat BaseClass characterClass = src.getCharClass(); characterClass.setCharacter(null); + Type equipListType = new TypeToken>() { + }.getType(); + Type moneyMapType = new TypeToken>() { + }.getType(); + JsonObject rootObject = new JsonObject(); rootObject.add("mScores", context.serialize(src.getScores())); - rootObject.add("mCharClass", context.serialize(src.getCharClass())); + rootObject.add("mCharClass", context.serialize(src.getCharClass(), BaseClass.class)); rootObject.add("mGender", context.serialize(src.getGender())); - rootObject.add("mMoney", context.serialize(src.getMoney())); + rootObject.add("mMoney", context.serialize(src.getMoney(), moneyMapType)); rootObject.add("mAge", context.serialize(src.getAge())); rootObject.add("mName", context.serialize(src.getName())); - rootObject.add("mInventory", context.serialize(src.getInventory())); + rootObject.add("mInventory", context.serialize(src.getInventory(), equipListType)); rootObject.add("mCurrentWeapon", context.serialize(src.getCurrentWeapon())); rootObject.add("mHelmet", context.serialize(src.getHelmet())); rootObject.add("mBreastplate", context.serialize(src.getBreastplate())); @@ -57,18 +64,25 @@ public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializat public PlayerCharacter deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { final PlayerCharacter newCharacter = new PlayerCharacter(); JsonObject loadedData = json.getAsJsonObject(); - for (Map.Entry e : loadedData.get("mCharClass").getAsJsonObject().entrySet()) { - System.out.println(e); + for (Score score : Score.values()) { + int loadedScore = loadedData.getAsJsonObject("mScores").getAsJsonObject(score.toString()).get("mScore").getAsInt(); + newCharacter.getScore(score).setScore(loadedScore); } + + Type equipListType = new TypeToken>() { + }.getType(); + Type moneyMapType = new TypeToken>() { + }.getType(); + newCharacter.setAge((int) context.deserialize(loadedData.get("mAge"), Integer.class)); newCharacter.setBreastplate((Armor) context.deserialize(loadedData.get("mBreastplate"), Armor.class)); newCharacter.setCharClass((BaseClass) context.deserialize(loadedData.get("mCharClass"), BaseClass.class)); newCharacter.setCurrentWeapon((Weapon) context.deserialize(loadedData.get("mCurrentWeapon"), Weapon.class)); newCharacter.setGender((Gender) context.deserialize(loadedData.get("mGender"), Gender.class)); newCharacter.setHelmet((Armor) context.deserialize(loadedData.get("mHelmet"), Armor.class)); - newCharacter.setMoney((HashMap) context.deserialize(loadedData.get("mMoney"), HashMap.class)); + newCharacter.setMoney((HashMap) context.deserialize(loadedData.get("mMoney"), moneyMapType)); newCharacter.setName(loadedData.get("mName").getAsString()); - newCharacter.setInventory((ArrayList) context.deserialize(loadedData.get("mInventory"), ArrayList.class)); + newCharacter.setInventory((ArrayList) context.deserialize(loadedData.get("mInventory"), equipListType)); newCharacter.setShield((Armor) context.deserialize(loadedData.get("mShield"), Armor.class)); return newCharacter; diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java index 9cd9f46..625903a 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java @@ -1,15 +1,30 @@ package com.example.cis.mazeminotaurs.character; import com.example.cis.mazeminotaurs.Armor; +import com.example.cis.mazeminotaurs.Equipment; import com.example.cis.mazeminotaurs.Portfolio; import com.example.cis.mazeminotaurs.Weapon; +import com.example.cis.mazeminotaurs.character.classes.Amazon; import com.example.cis.mazeminotaurs.character.classes.Barbarian; +import com.example.cis.mazeminotaurs.character.classes.BaseClass; +import com.example.cis.mazeminotaurs.character.classes.Centaur; +import com.example.cis.mazeminotaurs.character.classes.Elementalist; +import com.example.cis.mazeminotaurs.character.classes.Hunter; +import com.example.cis.mazeminotaurs.character.classes.Lyrist; +import com.example.cis.mazeminotaurs.character.classes.Magician; +import com.example.cis.mazeminotaurs.character.classes.Noble; +import com.example.cis.mazeminotaurs.character.classes.Nymph; +import com.example.cis.mazeminotaurs.character.classes.Priest; +import com.example.cis.mazeminotaurs.character.classes.Sorcerer; +import com.example.cis.mazeminotaurs.character.classes.Spearman; +import com.example.cis.mazeminotaurs.character.classes.Thief; import com.example.cis.mazeminotaurs.character.stats.Score; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; +import com.google.gson.typeadapters.RuntimeTypeAdapterFactory; import java.lang.reflect.Type; import java.util.ArrayList; @@ -21,6 +36,34 @@ */ public class SaveAndLoadPerformer { + + /** + * Generates a gson that has all of the common features loaded in. + * @return a gson object + */ + private static Gson getGson() { + GsonBuilder builder = new GsonBuilder(); + RuntimeTypeAdapterFactory adapter = RuntimeTypeAdapterFactory + .of(BaseClass.class) + .registerSubtype(Amazon.class) + .registerSubtype(Barbarian.class) + .registerSubtype(Centaur.class) + .registerSubtype(Elementalist.class) + .registerSubtype(Hunter.class) + .registerSubtype(Lyrist.class) + .registerSubtype(Magician.class) + .registerSubtype(Noble.class) + .registerSubtype(Nymph.class) + .registerSubtype(Priest.class) + .registerSubtype(Sorcerer.class) + .registerSubtype(Spearman.class) + .registerSubtype(Thief.class); + builder.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); + builder.registerTypeAdapterFactory(adapter); + builder.setPrettyPrinting(); + return builder.create(); + } + /** * Takes the player character parameter and transforms it into a json string. * @param playerCharacter the player character that needs to be serialized. @@ -38,9 +81,7 @@ public static String save(PlayerCharacter playerCharacter){ * @return json string of playerCharacter */ public static String save(int characterIndex) { - GsonBuilder gson = new GsonBuilder(); - gson.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); - return gson.create().toJson(Portfolio.get().getPlayerCharacter(characterIndex)); + return getGson().toJson(Portfolio.get().getPlayerCharacter(characterIndex)); } /** @@ -56,7 +97,12 @@ public static PlayerCharacter load(String jsonString){ int loadedScore = loadedData.getAsJsonObject("mScores").getAsJsonObject(score.toString()).get("mScore").getAsInt(); returnCharacter.getScore(score).setScore(loadedScore); } - Gson gson = new Gson(); + Gson gson = getGson(); + + Type equipListType = new TypeToken>() { + }.getType(); + Type moneyMapType = new TypeToken>() { + }.getType(); returnCharacter.setAge(gson.fromJson(loadedData.get("mAge"), Integer.class)); returnCharacter.setBreastplate(gson.fromJson(loadedData.get("mBreastplate"), Armor.class)); @@ -64,27 +110,24 @@ public static PlayerCharacter load(String jsonString){ returnCharacter.setCurrentWeapon(gson.fromJson(loadedData.get("mCurrentWeapon"), Weapon.class)); returnCharacter.setGender(gson.fromJson(loadedData.get("mGender"), Gender.class)); returnCharacter.setHelmet(gson.fromJson(loadedData.get("mHelmet"), Armor.class)); - returnCharacter.setMoney(gson.fromJson(loadedData.get("mMoney"), HashMap.class)); + returnCharacter.setMoney((HashMap) gson.fromJson(loadedData.get("mMoney"), moneyMapType)); returnCharacter.setName(loadedData.get("mName").getAsString()); - returnCharacter.setInventory(gson.fromJson(loadedData.get("mInventory"), ArrayList.class)); + returnCharacter.setInventory((ArrayList) gson.fromJson(loadedData.get("mInventory"), equipListType)); returnCharacter.setShield(gson.fromJson(loadedData.get("mShield"), Armor.class)); return returnCharacter; } public static String savePortfolio() { - Gson gson = new Gson(); Type listType = new TypeToken>() { }.getType(); - return gson.toJson(Portfolio.get().getPortfolio(), listType); + return getGson().toJson(Portfolio.get().getPortfolio(), listType); } public static void loadPortfolio(String jsonString) { - GsonBuilder builder = new GsonBuilder(); Type listType = new TypeToken>() { }.getType(); - builder.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); - ArrayList newPort = builder.create().fromJson(jsonString, listType); + ArrayList newPort = getGson().fromJson(jsonString, listType); Portfolio.get().setPortfolio(newPort); } } diff --git a/MazesAndMinotaurs/instapk.log b/MazesAndMinotaurs/instapk.log index 3fa60df..d47f4db 100644 --- a/MazesAndMinotaurs/instapk.log +++ b/MazesAndMinotaurs/instapk.log @@ -1,2 +1,2 @@ -Oct 16, 2017 11:15:14 AM com.pytenlabs.instapk.helpers.LogHelper init +Oct 18, 2017 11:12:24 AM com.pytenlabs.instapk.helpers.LogHelper init INFO: Linux, 4.9.0-3-amd64, amd64, Android Studio AI-162.2228.14 From 35f5d356be3085f0be91c0b954e922e56f020e9e Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 12:13:39 -0500 Subject: [PATCH 12/20] Added ability to handle failed load. --- .../com/example/cis/mazeminotaurs/MainMazes.java | 5 +++++ .../com/example/cis/mazeminotaurs/util/Util.java | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java index da66fba..3283be4 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java @@ -18,6 +18,7 @@ import com.example.cis.mazeminotaurs.NewCharacter.CharacterCreationFragment; import com.example.cis.mazeminotaurs.character.PlayerCharacter; import com.example.cis.mazeminotaurs.character.SaveAndLoadPerformer; +import com.example.cis.mazeminotaurs.util.Util; import com.example.cis.mazeminotaurs.web_resources.CompanionFragment; import com.example.cis.mazeminotaurs.web_resources.PlayerManualFragment; import com.example.cis.mazeminotaurs.web_resources.WebsiteFragment; @@ -57,6 +58,10 @@ protected void onCreate(Bundle savedInstanceState) { } mPortfolio = Portfolio.get(); + if (mPortfolio.getPortfolio() == null) { + mPortfolio.resetPortfolio(); + mPortfolio.addPlayerCharacter(Util.createDummyCharacter()); + } mEquipment = EquipmentDB.getInstance(); try{ diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/util/Util.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/util/Util.java index 5a7ebeb..ab874b7 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/util/Util.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/util/Util.java @@ -3,12 +3,24 @@ import com.example.cis.mazeminotaurs.EquipmentDB; import com.example.cis.mazeminotaurs.R; import com.example.cis.mazeminotaurs.Weapon; +import com.example.cis.mazeminotaurs.character.PlayerCharacter; +import com.example.cis.mazeminotaurs.character.classes.Barbarian; /** * Created by jusmith on 9/28/2017. */ public class Util { + public static PlayerCharacter createDummyCharacter() { + PlayerCharacter pc = new PlayerCharacter(); + Barbarian barbarian = new Barbarian(pc, EquipmentDB.getInstance().getWeapon(R.string.barb_axe), + EquipmentDB.getInstance().getWeapon(R.string.barb_axe)); + pc.setCharClass(barbarian); + pc.initializeClass(); + + return pc; + } + /** * Returns the ammo used for a specified missile weapon. */ From d5428f4795cde6b2e5253dfa7869802b04a6972d Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 12:26:13 -0500 Subject: [PATCH 13/20] Labeled certain methods and classes as deprecated --- .../example/cis/mazeminotaurs/character/SaveAndLoadDialog.java | 1 + .../cis/mazeminotaurs/character/SaveAndLoadPerformer.java | 1 + 2 files changed, 2 insertions(+) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadDialog.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadDialog.java index f68982f..5b1dc51 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadDialog.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadDialog.java @@ -24,6 +24,7 @@ import java.io.OutputStreamWriter; /** + * @deprecated * Created by jusmith on 4/26/17. */ diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java index 625903a..9385902 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java @@ -86,6 +86,7 @@ public static String save(int characterIndex) { /** * Returns a playerCharacter based on the json string given. + * @deprecated * @param jsonString the playerCharacter in json * @return the generated playerCharacter */ From b6a6baa28602779dd59a5597087da8ece24ca25c Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 12:26:37 -0500 Subject: [PATCH 14/20] Added the ability to handle polymorphism in Equipment objects. --- .../character/CharacterSerializer.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java index fb15f17..51b3b7e 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java @@ -6,12 +6,15 @@ import com.example.cis.mazeminotaurs.Armor; import com.example.cis.mazeminotaurs.Equipment; +import com.example.cis.mazeminotaurs.Mythics; import com.example.cis.mazeminotaurs.Weapon; import com.example.cis.mazeminotaurs.character.Gender; import com.example.cis.mazeminotaurs.character.Money; import com.example.cis.mazeminotaurs.character.PlayerCharacter; import com.example.cis.mazeminotaurs.character.classes.BaseClass; import com.example.cis.mazeminotaurs.character.stats.Score; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -20,6 +23,7 @@ import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import com.google.gson.reflect.TypeToken; +import com.google.gson.typeadapters.RuntimeTypeAdapterFactory; import java.lang.reflect.Type; import java.util.ArrayList; @@ -30,6 +34,19 @@ * Custom serializer for transforming the PlayerCharacter class into json. */ public class CharacterSerializer implements JsonSerializer, JsonDeserializer { + private static Gson getGson() { + GsonBuilder builder = new GsonBuilder(); + RuntimeTypeAdapterFactory adapter = RuntimeTypeAdapterFactory + .of(Equipment.class) + .registerSubtype(Equipment.class) + .registerSubtype(Weapon.class) + .registerSubtype(Armor.class) + .registerSubtype(Mythics.class); + builder.registerTypeAdapterFactory(adapter); + builder.setPrettyPrinting(); + return builder.create(); + } + @Override public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializationContext context) { BaseClass characterClass = src.getCharClass(); @@ -47,7 +64,8 @@ public JsonElement serialize(PlayerCharacter src, Type typeOfSrc, JsonSerializat rootObject.add("mMoney", context.serialize(src.getMoney(), moneyMapType)); rootObject.add("mAge", context.serialize(src.getAge())); rootObject.add("mName", context.serialize(src.getName())); - rootObject.add("mInventory", context.serialize(src.getInventory(), equipListType)); + System.out.println(getGson().toJsonTree(src.getInventory(), equipListType)); + rootObject.add("mInventory", getGson().toJsonTree(src.getInventory(), equipListType)); rootObject.add("mCurrentWeapon", context.serialize(src.getCurrentWeapon())); rootObject.add("mHelmet", context.serialize(src.getHelmet())); rootObject.add("mBreastplate", context.serialize(src.getBreastplate())); @@ -82,7 +100,7 @@ public PlayerCharacter deserialize(JsonElement json, Type typeOfT, JsonDeseriali newCharacter.setHelmet((Armor) context.deserialize(loadedData.get("mHelmet"), Armor.class)); newCharacter.setMoney((HashMap) context.deserialize(loadedData.get("mMoney"), moneyMapType)); newCharacter.setName(loadedData.get("mName").getAsString()); - newCharacter.setInventory((ArrayList) context.deserialize(loadedData.get("mInventory"), equipListType)); + newCharacter.setInventory((ArrayList) getGson().fromJson(loadedData.get("mInventory"), equipListType)); newCharacter.setShield((Armor) context.deserialize(loadedData.get("mShield"), Armor.class)); return newCharacter; From 5662b12bbb7c7f6982a2fc576703bffcaee09167 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 12:31:32 -0500 Subject: [PATCH 15/20] Replaced multiple gson creations with static one(s). --- .../character/CharacterSerializer.java | 26 ++++++----- .../character/SaveAndLoadPerformer.java | 45 ++++++++++--------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java index 51b3b7e..69b577c 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/CharacterSerializer.java @@ -34,17 +34,23 @@ * Custom serializer for transforming the PlayerCharacter class into json. */ public class CharacterSerializer implements JsonSerializer, JsonDeserializer { + + private static Gson sGson = null; + private static Gson getGson() { - GsonBuilder builder = new GsonBuilder(); - RuntimeTypeAdapterFactory adapter = RuntimeTypeAdapterFactory - .of(Equipment.class) - .registerSubtype(Equipment.class) - .registerSubtype(Weapon.class) - .registerSubtype(Armor.class) - .registerSubtype(Mythics.class); - builder.registerTypeAdapterFactory(adapter); - builder.setPrettyPrinting(); - return builder.create(); + if (sGson == null) { + GsonBuilder builder = new GsonBuilder(); + RuntimeTypeAdapterFactory adapter = RuntimeTypeAdapterFactory + .of(Equipment.class) + .registerSubtype(Equipment.class) + .registerSubtype(Weapon.class) + .registerSubtype(Armor.class) + .registerSubtype(Mythics.class); + builder.registerTypeAdapterFactory(adapter); + builder.setPrettyPrinting(); + sGson = builder.create(); + } + return sGson; } @Override diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java index 9385902..fb13dd9 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/character/SaveAndLoadPerformer.java @@ -37,31 +37,36 @@ public class SaveAndLoadPerformer { + private static Gson sGson = null; + /** * Generates a gson that has all of the common features loaded in. * @return a gson object */ private static Gson getGson() { - GsonBuilder builder = new GsonBuilder(); - RuntimeTypeAdapterFactory adapter = RuntimeTypeAdapterFactory - .of(BaseClass.class) - .registerSubtype(Amazon.class) - .registerSubtype(Barbarian.class) - .registerSubtype(Centaur.class) - .registerSubtype(Elementalist.class) - .registerSubtype(Hunter.class) - .registerSubtype(Lyrist.class) - .registerSubtype(Magician.class) - .registerSubtype(Noble.class) - .registerSubtype(Nymph.class) - .registerSubtype(Priest.class) - .registerSubtype(Sorcerer.class) - .registerSubtype(Spearman.class) - .registerSubtype(Thief.class); - builder.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); - builder.registerTypeAdapterFactory(adapter); - builder.setPrettyPrinting(); - return builder.create(); + if (sGson == null) { + GsonBuilder builder = new GsonBuilder(); + RuntimeTypeAdapterFactory adapter = RuntimeTypeAdapterFactory + .of(BaseClass.class) + .registerSubtype(Amazon.class) + .registerSubtype(Barbarian.class) + .registerSubtype(Centaur.class) + .registerSubtype(Elementalist.class) + .registerSubtype(Hunter.class) + .registerSubtype(Lyrist.class) + .registerSubtype(Magician.class) + .registerSubtype(Noble.class) + .registerSubtype(Nymph.class) + .registerSubtype(Priest.class) + .registerSubtype(Sorcerer.class) + .registerSubtype(Spearman.class) + .registerSubtype(Thief.class); + builder.registerTypeAdapter(PlayerCharacter.class, new CharacterSerializer()); + builder.registerTypeAdapterFactory(adapter); + builder.setPrettyPrinting(); + sGson = builder.create(); + } + return sGson; } /** From 64923d564d77d98b2e63b99d2bf582ffceb55793 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 12:35:34 -0500 Subject: [PATCH 16/20] Created CharacterAdapter --- .../com/example/cis/mazeminotaurs/CharacterAdapter.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java new file mode 100644 index 0000000..d4343a0 --- /dev/null +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java @@ -0,0 +1,8 @@ +package com.example.cis.mazeminotaurs; + +/** + * Created by jsmith on 10/18/17. + */ + +public class CharacterAdapter { +} From 4c0978d88043d5b443074a16b14e064ed5eaba7e Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 12:43:49 -0500 Subject: [PATCH 17/20] Added functionality to CharacterAdapter --- .../cis/mazeminotaurs/CharacterAdapter.java | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java index d4343a0..1ad990b 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java @@ -1,8 +1,53 @@ package com.example.cis.mazeminotaurs; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import com.example.cis.mazeminotaurs.character.PlayerCharacter; + +import java.util.ArrayList; + /** * Created by jsmith on 10/18/17. */ -public class CharacterAdapter { +public class CharacterAdapter extends BaseAdapter { + private ArrayList mDataset; + private Context mContext; + + @Override + public int getCount() { + return mDataset.size(); + } + + @Override + public PlayerCharacter getItem(int i) { + return mDataset.get(i); + } + + @Override + public long getItemId(int i) { + return mDataset.get(i).getCharClass().getResId(); + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + if (view == null) { + view = LayoutInflater.from(mContext) + .inflate(R.layout.spinner_item_character, viewGroup, false); + } + + TextView nameView = (TextView) view.findViewById(R.id.character_name_view); + TextView classView = (TextView) view.findViewById(R.id.character_class_view); + TextView levelView = (TextView) view.findViewById(R.id.character_level_view); + + nameView.setText(mDataset.get(i).getName()); + classView.setText(mDataset.get(i).getCharClass().getResId()); + levelView.setText(mDataset.get(i).getCharClass().getLevel()); + return view; + } } From 89af54283f7f37f8e607a510bafe63bcc54eb5eb Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Wed, 18 Oct 2017 13:01:12 -0500 Subject: [PATCH 18/20] Added a character select screen. --- .../CharacerSelectionFragment.java | 33 +++++++++++++++++++ .../cis/mazeminotaurs/CharacterAdapter.java | 7 +++- .../mazeminotaurs/CharacterSheetFragment.java | 2 ++ .../example/cis/mazeminotaurs/MainMazes.java | 2 ++ .../layout/fragment_character_selection.xml | 12 +++++++ .../main/res/menu/activity_main_drawer.xml | 4 +++ .../app/src/main/res/values/strings.xml | 1 + 7 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java create mode 100644 MazesAndMinotaurs/app/src/main/res/layout/fragment_character_selection.xml diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java new file mode 100644 index 0000000..bf39d98 --- /dev/null +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java @@ -0,0 +1,33 @@ +package com.example.cis.mazeminotaurs; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; + +/** + * Created by jsmith on 10/18/17. + */ + +public class CharacerSelectionFragment extends Fragment { + @Override + public View onCreateView(LayoutInflater li, ViewGroup vg, Bundle b) { + super.onCreateView(li, vg, b); + View view = li.inflate(R.layout.fragment_character_selection, vg, false); + + ListView charListView = (ListView) view.findViewById(R.id.character_list_view); + charListView.setAdapter(new CharacterAdapter(getContext(), Portfolio.get().getPortfolio())); + + charListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + Portfolio.get().setActiveCharacterIndex(i); + } + }); + + return view; + } +} diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java index 1ad990b..f4b18b7 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java @@ -19,6 +19,11 @@ public class CharacterAdapter extends BaseAdapter { private ArrayList mDataset; private Context mContext; + public CharacterAdapter(Context context, ArrayList dataset) { + mContext = context; + mDataset = dataset; + } + @Override public int getCount() { return mDataset.size(); @@ -47,7 +52,7 @@ public View getView(int i, View view, ViewGroup viewGroup) { nameView.setText(mDataset.get(i).getName()); classView.setText(mDataset.get(i).getCharClass().getResId()); - levelView.setText(mDataset.get(i).getCharClass().getLevel()); + levelView.setText(String.valueOf(mDataset.get(i).getCharClass().getLevel())); return view; } } diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java index 875e223..176e7c3 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterSheetFragment.java @@ -3,6 +3,7 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -77,6 +78,7 @@ public View onCreateView(LayoutInflater li, ViewGroup vg, Bundle b){ View rootView = li.inflate(R.layout.fragment_character_sheet, vg, false); mCurrentCharacterIndex = mPortfolio.getActiveCharacterIndex(); + Log.d(TAG, String.valueOf(mPortfolio.getActiveCharacterIndex())); mSheetPlayerCharacter = mPortfolio.getPlayerCharacter(mCurrentCharacterIndex); mCharacterLevelView = (TextView) rootView.findViewById(R.id.character_level_view); diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java index 3283be4..2d1bd25 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java @@ -148,6 +148,8 @@ public boolean onNavigationItemSelected(MenuItem item) { contentFragment = new CharacterCreationFragment(); } else if (id == R.id.play_character) { contentFragment = new CharacterSheetFragment(); + } else if (id == R.id.select_character) { + contentFragment = new CharacerSelectionFragment(); } else if (id == R.id.delete_character) { } else if (id == R.id.player_manual) { diff --git a/MazesAndMinotaurs/app/src/main/res/layout/fragment_character_selection.xml b/MazesAndMinotaurs/app/src/main/res/layout/fragment_character_selection.xml new file mode 100644 index 0000000..d70dca8 --- /dev/null +++ b/MazesAndMinotaurs/app/src/main/res/layout/fragment_character_selection.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/MazesAndMinotaurs/app/src/main/res/menu/activity_main_drawer.xml b/MazesAndMinotaurs/app/src/main/res/menu/activity_main_drawer.xml index db240ee..62363a3 100644 --- a/MazesAndMinotaurs/app/src/main/res/menu/activity_main_drawer.xml +++ b/MazesAndMinotaurs/app/src/main/res/menu/activity_main_drawer.xml @@ -10,6 +10,10 @@ android:id="@+id/play_character" android:icon="@drawable/ic_people_black_24dp" android:title="@string/play_character"/> + Create New Character Play Existing Character Delete A Character + Select Active Character Save Portfolio Web Resources From 4202de5acacc76ddb9998af068c2308b10596e10 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Thu, 19 Oct 2017 11:35:36 -0500 Subject: [PATCH 19/20] Added a character delete screen. --- .../CharacterDeletionFragment.java | 39 +++++++++++++++++++ .../example/cis/mazeminotaurs/MainMazes.java | 2 +- .../app/src/main/res/values/strings.xml | 1 + MazesAndMinotaurs/instapk.log | 14 ++++++- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java new file mode 100644 index 0000000..42a0d82 --- /dev/null +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java @@ -0,0 +1,39 @@ +package com.example.cis.mazeminotaurs; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.Toast; + +/** + * Created by jsmith on 10/19/17. + */ + +public class CharacterDeletionFragment extends Fragment { + @Override + public View onCreateView(LayoutInflater li, ViewGroup vg, Bundle b) { + super.onCreateView(li, vg, b); + View view = li.inflate(R.layout.fragment_character_selection, vg, false); + + ListView charListView = (ListView) view.findViewById(R.id.character_list_view); + charListView.setAdapter(new CharacterAdapter(getContext(), Portfolio.get().getPortfolio())); + + charListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + Portfolio port = Portfolio.get(); + if (port.getPortfolio().size() > 1) { + port.deletePlayerCharacter(port.getPlayerCharacter(i)); + } else { + Toast.makeText(getContext(), R.string.error_delete_character, Toast.LENGTH_SHORT).show(); + } + } + }); + + return view; + } +} diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java index 2d1bd25..aa5eebb 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/MainMazes.java @@ -151,7 +151,7 @@ public boolean onNavigationItemSelected(MenuItem item) { } else if (id == R.id.select_character) { contentFragment = new CharacerSelectionFragment(); } else if (id == R.id.delete_character) { - + contentFragment = new CharacterDeletionFragment(); } else if (id == R.id.player_manual) { contentFragment = new PlayerManualFragment(); } else if (id == R.id.player_comapanion) { diff --git a/MazesAndMinotaurs/app/src/main/res/values/strings.xml b/MazesAndMinotaurs/app/src/main/res/values/strings.xml index e3fdf3b..0f6216f 100644 --- a/MazesAndMinotaurs/app/src/main/res/values/strings.xml +++ b/MazesAndMinotaurs/app/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ Create New Character Play Existing Character Delete A Character + Must have one character at all times! Select Active Character Save Portfolio Web Resources diff --git a/MazesAndMinotaurs/instapk.log b/MazesAndMinotaurs/instapk.log index d47f4db..3c19f9e 100644 --- a/MazesAndMinotaurs/instapk.log +++ b/MazesAndMinotaurs/instapk.log @@ -1,2 +1,14 @@ -Oct 18, 2017 11:12:24 AM com.pytenlabs.instapk.helpers.LogHelper init +Oct 19, 2017 11:11:42 AM com.pytenlabs.instapk.helpers.LogHelper init INFO: Linux, 4.9.0-3-amd64, amd64, Android Studio AI-162.2228.14 +Oct 19, 2017 11:20:31 AM com.pytenlabs.instapk.helpers.ApiHelper uploadApk +INFO: versionCode : 1 +Oct 19, 2017 11:20:31 AM com.pytenlabs.instapk.helpers.ApiHelper uploadApk +INFO: versionName : 1.0 +Oct 19, 2017 11:20:31 AM com.pytenlabs.instapk.helpers.ApiHelper uploadApk +INFO: packageName : com.example.cis.mazeminotaurs +Oct 19, 2017 11:20:31 AM com.pytenlabs.instapk.helpers.ApiHelper uploadApk +INFO: release_note : Prototype of character saving +Oct 19, 2017 11:20:40 AM com.pytenlabs.instapk.helpers.ApiHelper$1 run +INFO: RES CODE: 201 +Oct 19, 2017 11:20:40 AM com.pytenlabs.instapk.helpers.ApiHelper$1 run +INFO: RES: {"id":3776,"release_note":"Prototype of character saving","created_time":"2017-10-19T16:22:26.845507Z"} From f8290a285bc9aa824c30e0e5b2bd3de0b3e3f338 Mon Sep 17 00:00:00 2001 From: JayTSmith Date: Thu, 19 Oct 2017 11:51:02 -0500 Subject: [PATCH 20/20] The list nows updates when a character is deleted. --- .../CharacerSelectionFragment.java | 2 +- .../cis/mazeminotaurs/CharacterAdapter.java | 22 +++++++++++-------- .../CharacterDeletionFragment.java | 9 ++++---- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java index bf39d98..cc541cb 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacerSelectionFragment.java @@ -19,7 +19,7 @@ public View onCreateView(LayoutInflater li, ViewGroup vg, Bundle b) { View view = li.inflate(R.layout.fragment_character_selection, vg, false); ListView charListView = (ListView) view.findViewById(R.id.character_list_view); - charListView.setAdapter(new CharacterAdapter(getContext(), Portfolio.get().getPortfolio())); + charListView.setAdapter(new CharacterAdapter(getContext())); charListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java index f4b18b7..864471a 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterAdapter.java @@ -16,27 +16,31 @@ */ public class CharacterAdapter extends BaseAdapter { - private ArrayList mDataset; + private Portfolio mPortfolio = Portfolio.get(); private Context mContext; - public CharacterAdapter(Context context, ArrayList dataset) { + public CharacterAdapter(Context context) { mContext = context; - mDataset = dataset; + } + + public void removeCharacter(int i) { + mPortfolio.deletePlayerCharacter(mPortfolio.getPlayerCharacter(i)); + notifyDataSetChanged(); } @Override public int getCount() { - return mDataset.size(); + return mPortfolio.getPortfolio().size(); } @Override public PlayerCharacter getItem(int i) { - return mDataset.get(i); + return mPortfolio.getPlayerCharacter(i); } @Override public long getItemId(int i) { - return mDataset.get(i).getCharClass().getResId(); + return getItem(i).getCharClass().getResId(); } @Override @@ -50,9 +54,9 @@ public View getView(int i, View view, ViewGroup viewGroup) { TextView classView = (TextView) view.findViewById(R.id.character_class_view); TextView levelView = (TextView) view.findViewById(R.id.character_level_view); - nameView.setText(mDataset.get(i).getName()); - classView.setText(mDataset.get(i).getCharClass().getResId()); - levelView.setText(String.valueOf(mDataset.get(i).getCharClass().getLevel())); + nameView.setText(getItem(i).getName()); + classView.setText(getItem(i).getCharClass().getResId()); + levelView.setText(String.valueOf(getItem(i).getCharClass().getLevel())); return view; } } diff --git a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java index 42a0d82..d7057bf 100644 --- a/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java +++ b/MazesAndMinotaurs/app/src/main/java/com/example/cis/mazeminotaurs/CharacterDeletionFragment.java @@ -19,15 +19,14 @@ public View onCreateView(LayoutInflater li, ViewGroup vg, Bundle b) { super.onCreateView(li, vg, b); View view = li.inflate(R.layout.fragment_character_selection, vg, false); - ListView charListView = (ListView) view.findViewById(R.id.character_list_view); - charListView.setAdapter(new CharacterAdapter(getContext(), Portfolio.get().getPortfolio())); + final ListView charListView = (ListView) view.findViewById(R.id.character_list_view); + charListView.setAdapter(new CharacterAdapter(getContext())); charListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { - Portfolio port = Portfolio.get(); - if (port.getPortfolio().size() > 1) { - port.deletePlayerCharacter(port.getPlayerCharacter(i)); + if (charListView.getAdapter().getCount() > 1) { + ((CharacterAdapter) charListView.getAdapter()).removeCharacter(i); } else { Toast.makeText(getContext(), R.string.error_delete_character, Toast.LENGTH_SHORT).show(); }