OSDN Git Service

[Refactor] #1796 ItemLoaderBase、ItemLoaderFactoryクラスを作ってアイテム読み込み処理用のクラスを分離しやすくした
authorHourier <66951241+Hourier@users.noreply.github.com>
Sat, 16 Oct 2021 14:38:01 +0000 (23:38 +0900)
committerHourier <66951241+Hourier@users.noreply.github.com>
Sun, 17 Oct 2021 05:44:05 +0000 (14:44 +0900)
15 files changed:
Hengband/Hengband/Hengband.vcxproj
Hengband/Hengband/Hengband.vcxproj.filters
src/Makefile.am
src/load/floor-loader.cpp
src/load/inventory-loader.cpp
src/load/item/item-loader-base.cpp [new file with mode: 0644]
src/load/item/item-loader-base.h [new file with mode: 0644]
src/load/item/item-loader-factory.cpp [new file with mode: 0644]
src/load/item/item-loader-factory.h [new file with mode: 0644]
src/load/item/item-loader-version-types.h [new file with mode: 0644]
src/load/load.cpp
src/load/old/item-loader-savefile10.cpp
src/load/old/item-loader-savefile10.h
src/load/old/load-v1-5-0.cpp
src/load/store-loader.cpp

index 4f25020..0c7d4a4 100644 (file)
     <ClCompile Include="..\..\src\cmd-action\cmd-tunnel.cpp" />\r
     <ClCompile Include="..\..\src\action\movement-execution.cpp" />\r
     <ClCompile Include="..\..\src\core\score-util.cpp" />\r
+    <ClCompile Include="..\..\src\load\item\item-loader-base.cpp" />\r
+    <ClCompile Include="..\..\src\load\item\item-loader-factory.cpp" />\r
     <ClCompile Include="..\..\src\load\player-class-specific-data-loader.cpp" />\r
     <ClCompile Include="..\..\src\object-enchant\object-smith.cpp" />\r
     <ClCompile Include="..\..\src\object-enchant\smith-info.cpp" />\r
     <ClInclude Include="..\..\src\action\open-close-execution.h" />\r
     <ClInclude Include="..\..\src\action\open-util.h" />\r
     <ClInclude Include="..\..\src\action\run-execution.h" />\r
+    <ClInclude Include="..\..\src\load\item\item-loader-version-types.h" />\r
+    <ClInclude Include="..\..\src\load\item\item-loader-base.h" />\r
+    <ClInclude Include="..\..\src\load\item\item-loader-factory.h" />\r
     <ClInclude Include="..\..\src\load\old\savedata10-monster-flag-types.h" />\r
     <ClInclude Include="..\..\src\load\player-class-specific-data-loader.h" />\r
     <ClInclude Include="..\..\src\load\savedata-old-flag-types.h" />\r
index 376fbde..1085959 100644 (file)
     <ClCompile Include="..\..\src\load\old\monster-loader-savefile10.cpp">\r
       <Filter>load\old</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\src\load\item\item-loader-base.cpp">\r
+      <Filter>load\item</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\src\load\item\item-loader-factory.cpp">\r
+      <Filter>load\item</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\..\src\combat\shoot.h">\r
     <ClInclude Include="..\..\src\load\old\savedata10-monster-flag-types.h">\r
       <Filter>load\old</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\src\load\item\item-loader-base.h">\r
+      <Filter>load\item</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\src\load\item\item-loader-factory.h">\r
+      <Filter>load\item</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\src\load\item\item-loader-version-types.h">\r
+      <Filter>load\item</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="..\..\src\wall.bmp" />\r
     <Filter Include="load\old">\r
       <UniqueIdentifier>{46523373-91fb-436b-89c6-14ad74b88f5d}</UniqueIdentifier>\r
     </Filter>\r
+    <Filter Include="load\item">\r
+      <UniqueIdentifier>{346bc9ba-a477-404f-bc72-2ad9c1ec6daf}</UniqueIdentifier>\r
+    </Filter>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="..\..\src\angband.rc" />\r
index aa017bd..eb56fba 100644 (file)
@@ -358,6 +358,10 @@ hengband_SOURCES = \
        load/store-loader.cpp load/store-loader.h \
        load/world-loader.cpp load/world-loader.h \
        \
+       load/item/item-loader-base.cpp load/item/item-loader-base.h \
+       load/item/item-loader-factory.cpp load/item/item-loader-factory.h \
+       load/item/item-loader-version-types.h \
+       \
        load/old/item-loader-savefile10.cpp load/old/item-loader-savefile10.h \
        load/old/load-v1-5-0.cpp load/old/load-v1-5-0.h \
        load/old/load-v1-7-0.cpp load/old/load-v1-7-0.h \
index 398418f..de6ad83 100644 (file)
@@ -8,6 +8,7 @@
 #include "io/files-util.h"
 #include "io/uid-checker.h"
 #include "load/angband-version-comparer.h"
+#include "load/item/item-loader-factory.h"
 #include "load/load-util.h"
 #include "load/old-feature-types.h"
 #include "load/old/item-loader-savefile10.h"
@@ -155,17 +156,16 @@ errr rd_saved_floor(player_type *player_ptr, saved_floor_type *sf_ptr)
     if (limit > w_ptr->max_o_idx)
         return 151;
     for (int i = 1; i < limit; i++) {
-        OBJECT_IDX o_idx;
-        object_type *o_ptr;
-        o_idx = o_pop(floor_ptr);
-        if (i != o_idx)
+        auto o_idx = o_pop(floor_ptr);
+        if (i != o_idx) {
             return 152;
+        }
 
-        o_ptr = &floor_ptr->o_list[o_idx];
-        rd_item(o_ptr);
-
+        auto &item = floor_ptr->o_list[o_idx];
+        auto item_loader = ItemLoaderFactory::get_item_loader();
+        item_loader->rd_item(&item);
         auto &list = get_o_idx_list_contains(floor_ptr, o_idx);
-        list.add(floor_ptr, o_idx, o_ptr->stack_idx);
+        list.add(floor_ptr, o_idx, item.stack_idx);
     }
 
     limit = rd_u16b();
index 0f5118a..ec3ca09 100644 (file)
@@ -1,5 +1,6 @@
 #include "load/inventory-loader.h"
 #include "inventory/inventory-slot-types.h"
+#include "load/item/item-loader-factory.h"
 #include "load/load-util.h"
 #include "load/old/item-loader-savefile10.h"
 #include "object/object-mark-types.h"
@@ -30,20 +31,19 @@ static errr rd_inventory(player_type *player_ptr)
     while (true) {
         auto n = rd_u16b();
 
-        if (n == 0xFFFF)
+        if (n == 0xFFFF) {
             break;
-        object_type forge;
-        object_type *q_ptr;
-        q_ptr = &forge;
-        q_ptr->wipe();
+        }
 
-        rd_item(q_ptr);
-        if (!q_ptr->k_idx)
+        object_type item;
+        auto item_loader = ItemLoaderFactory::get_item_loader();
+        item_loader->rd_item(&item);
+        if (!item.k_idx)
             return (53);
 
         if (n >= INVEN_MAIN_HAND) {
-            q_ptr->marked |= OM_TOUCHED;
-            (&player_ptr->inventory_list[n])->copy_from(q_ptr);
+            item.marked |= OM_TOUCHED;
+            player_ptr->inventory_list[n].copy_from(&item);
             player_ptr->equip_cnt++;
             continue;
         }
@@ -54,8 +54,8 @@ static errr rd_inventory(player_type *player_ptr)
         }
 
         n = slot++;
-        q_ptr->marked |= OM_TOUCHED;
-        (&player_ptr->inventory_list[n])->copy_from(q_ptr);
+        item.marked |= OM_TOUCHED;
+        player_ptr->inventory_list[n].copy_from(&item);
         player_ptr->inven_cnt++;
     }
 
diff --git a/src/load/item/item-loader-base.cpp b/src/load/item/item-loader-base.cpp
new file mode 100644 (file)
index 0000000..f4854d1
--- /dev/null
@@ -0,0 +1,44 @@
+#include "load/item/item-loader-base.h"
+#include "load/angband-version-comparer.h"
+#include "load/load-util.h"
+#include "object/object-kind.h"
+#include "system/artifact-type-definition.h"
+#include "util/bit-flags-calculator.h"
+
+/*!
+ * @brief アイテムオブジェクトの鑑定情報をロードする.
+ */
+void ItemLoaderBase::load_item(void)
+{
+    auto loading_max_k_idx = rd_u16b();
+    object_kind dummy;
+    for (auto i = 0U; i < loading_max_k_idx; i++) {
+        auto *k_ptr = i < k_info.size() ? &k_info[i] : &dummy;
+        auto tmp8u = rd_byte();
+        k_ptr->aware = any_bits(tmp8u, 0x01);
+        k_ptr->tried = any_bits(tmp8u, 0x02);
+    }
+
+    load_note(_("アイテムの記録をロードしました", "Loaded Object Memory"));
+}
+
+/*!
+ * @brief 固定アーティファクトの出現情報をロードする.
+ */
+void ItemLoaderBase::load_artifact(void)
+{
+    auto loading_max_a_idx = rd_u16b();
+    artifact_type dummy;
+    for (auto i = 0U; i < loading_max_a_idx; i++) {
+        auto *a_ptr = i < a_info.size() ? &a_info[i] : &dummy;
+        a_ptr->cur_num = rd_byte();
+        if (h_older_than(1, 5, 0, 0)) {
+            a_ptr->floor_id = 0;
+            strip_bytes(3);
+        } else {
+            a_ptr->floor_id = rd_s16b();
+        }
+    }
+
+    load_note(_("伝説のアイテムをロードしました", "Loaded Artifacts"));
+}
diff --git a/src/load/item/item-loader-base.h b/src/load/item/item-loader-base.h
new file mode 100644 (file)
index 0000000..606d128
--- /dev/null
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "system/object-type-definition.h"
+
+class ItemLoaderBase {
+public:
+    virtual ~ItemLoaderBase() = default;
+
+    virtual void rd_item(object_type *o_ptr) = 0;
+    void load_item(void);
+    void load_artifact(void);
+
+protected:
+    ItemLoaderBase() = default;
+};
diff --git a/src/load/item/item-loader-factory.cpp b/src/load/item/item-loader-factory.cpp
new file mode 100644 (file)
index 0000000..d0526e6
--- /dev/null
@@ -0,0 +1,52 @@
+/*!
+ * @brief アイテム情報をセーブデータから読み込むクラスを選択するファクトリクラス
+ * @date 2021/10/16
+ * @author Hourier
+ */
+
+#include "load/item/item-loader-factory.h"
+#include "load/item/item-loader-base.h"
+#include "load/item/item-loader-version-types.h"
+#include "load/load-util.h"
+#include "load/old/item-loader-savefile10.h"
+
+/*!
+ * @brief アイテム読み込みクラスを返却する.
+ * @return アイテム読み込みクラスへの参照ポインタ.
+ * @details ItemLoaderBaseは純粋仮想関数を含むので参照を返す必要がある.
+ * (値を返す設計はコンパイルエラー)
+ */
+std::shared_ptr<ItemLoaderBase> ItemLoaderFactory::get_item_loader()
+{
+    auto version = get_version();
+    switch (version) {
+    case ItemLoaderVersionType::LOAD10:
+        return std::make_shared<ItemLoader10>(ItemLoader10());
+    case ItemLoaderVersionType::LOAD11:
+        // dummy yet.
+    default:
+        throw("Invalid loader version was specified!");
+    }
+}
+
+/*!
+ * @brief ItemLoaderのバージョン切り替え.
+ * @return セーブファイルバージョン群の中で互換性のある最古のバージョン.
+ * @details (備忘録)例えばバージョン15で更に変更された場合、以下のように書き換えること.
+ * 
+ * if (loading_savefile_version_is_older_than(15)) {
+ *   return ItemLoaderVersionType::LOAD11;
+ * } else if (loading_savefile_version_is_older_than(11)) {
+ *   return ItemLoaderVersionType::LOAD10;
+ * } else {
+ *   return ItemLoaderVersionType::LOAD15;
+ * }
+ */
+ItemLoaderVersionType ItemLoaderFactory::get_version()
+{
+    if (loading_savefile_version_is_older_than(11)) {
+        return ItemLoaderVersionType::LOAD10;
+    } else {
+        return ItemLoaderVersionType::LOAD11;
+    }
+}
diff --git a/src/load/item/item-loader-factory.h b/src/load/item/item-loader-factory.h
new file mode 100644 (file)
index 0000000..74d5807
--- /dev/null
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <memory>
+
+enum class ItemLoaderVersionType;
+class ItemLoaderBase;
+class ItemLoaderFactory {
+public:
+    static std::shared_ptr<ItemLoaderBase> get_item_loader();
+
+private:
+    ItemLoaderFactory() = delete;
+    static ItemLoaderVersionType get_version();
+};
diff --git a/src/load/item/item-loader-version-types.h b/src/load/item/item-loader-version-types.h
new file mode 100644 (file)
index 0000000..8ff76ef
--- /dev/null
@@ -0,0 +1,6 @@
+#pragma once
+
+enum class ItemLoaderVersionType {
+       LOAD10,
+       LOAD11,
+};
index 9e9cc01..193b3fd 100644 (file)
@@ -22,6 +22,7 @@
 #include "load/extra-loader.h"
 #include "load/info-loader.h"
 #include "load/inventory-loader.h"
+#include "load/item/item-loader-factory.h"
 #include "load/load-util.h"
 #include "load/load-zangband.h"
 #include "load/lore-loader.h"
@@ -184,13 +185,14 @@ static errr exe_reading_savefile(player_type *player_ptr)
     rd_dummy3();
     rd_system_info();
     load_lore();
-    load_item();
+    auto item_loader = ItemLoaderFactory::get_item_loader();
+    item_loader->load_item();
     errr load_town_quest_result = load_town_quest(player_ptr);
     if (load_town_quest_result != 0)
         return load_town_quest_result;
 
     load_note(_("クエスト情報をロードしました", "Loaded Quests"));
-    load_artifact();
+    item_loader->load_artifact();
     load_player_world(player_ptr);
     errr load_hp_result = load_hp(player_ptr);
     if (load_hp_result != 0)
index f215961..11b7d77 100644 (file)
@@ -12,7 +12,6 @@
 #include "object/object-kind.h"
 #include "sv-definition/sv-lite-types.h"
 #include "system/angband.h"
-#include "system/artifact-type-definition.h"
 #include "system/object-type-definition.h"
 #include "system/player-type-definition.h"
 #include "util/bit-flags-calculator.h"
@@ -23,7 +22,7 @@
  * @brief アイテムオブジェクトを読み込む(v3.0.0 Savefile ver10まで)
  * @param o_ptr アイテムオブジェクト保存先ポインタ
  */
-void rd_item(object_type *o_ptr)
+void ItemLoader10::rd_item(object_type *o_ptr)
 {
     if (h_older_than(1, 5, 0, 0)) {
         rd_item_old(o_ptr);
@@ -194,41 +193,3 @@ void rd_item(object_type *o_ptr)
         }
     }
 }
-
-/*!
- * @brief アイテムオブジェクトの鑑定情報をロードする.
- */
-void load_item(void)
-{
-    auto loading_max_k_idx = rd_u16b();
-    object_kind dummy;
-    for (auto i = 0U; i < loading_max_k_idx; i++) {
-        auto *k_ptr = i < k_info.size() ? &k_info[i] : &dummy;
-        auto tmp8u = rd_byte();
-        k_ptr->aware = any_bits(tmp8u, 0x01);
-        k_ptr->tried = any_bits(tmp8u, 0x02);
-    }
-
-    load_note(_("アイテムの記録をロードしました", "Loaded Object Memory"));
-}
-
-/*!
- * @brief 固定アーティファクトの出現情報をロードする.
- */
-void load_artifact(void)
-{
-    auto loading_max_a_idx = rd_u16b();
-    artifact_type dummy;
-    for (auto i = 0U; i < loading_max_a_idx; i++) {
-        auto *a_ptr = i < a_info.size() ? &a_info[i] : &dummy;
-        a_ptr->cur_num = rd_byte();
-        if (h_older_than(1, 5, 0, 0)) {
-            a_ptr->floor_id = 0;
-            strip_bytes(3);
-        } else {
-            a_ptr->floor_id = rd_s16b();
-        }
-    }
-
-    load_note(_("伝説のアイテムをロードしました", "Loaded Artifacts"));
-}
index 5cd358f..cb218c0 100644 (file)
@@ -1,6 +1,10 @@
 #pragma once
 
+#include "load/item/item-loader-base.h"
+
 struct object_type;
-void rd_item(object_type *o_ptr);
-void load_item(void);
-void load_artifact(void);
+class ItemLoader10 : public ItemLoaderBase {
+public:
+    ItemLoader10() = default;
+    void rd_item(object_type *o_ptr) override;
+};
index 09e0d73..9d12b60 100644 (file)
@@ -13,6 +13,8 @@
 #include "grid/grid.h"
 #include "grid/trap.h"
 #include "load/angband-version-comparer.h"
+#include "load/item/item-loader-factory.h"
+#include "load/item/item-loader-version-types.h"
 #include "load/load-util.h"
 #include "load/old-feature-types.h"
 #include "load/old/item-loader-savefile10.h"
@@ -686,10 +688,9 @@ errr rd_dungeon_old(player_type *player_ptr)
             return (152);
         }
 
-        object_type *o_ptr;
-        o_ptr = &floor_ptr->o_list[o_idx];
-        rd_item(o_ptr);
-
+        auto &item = floor_ptr->o_list[o_idx];
+        auto item_loader = ItemLoaderFactory::get_item_loader();
+        item_loader->rd_item(&item);
         auto &list = get_o_idx_list_contains(floor_ptr, o_idx);
         list.add(floor_ptr, o_idx);
     }
index 97044ed..b9cb288 100644 (file)
@@ -2,6 +2,7 @@
 #include "avatar/avatar.h"
 #include "floor/floor-town.h"
 #include "load/angband-version-comparer.h"
+#include "load/item/item-loader-factory.h"
 #include "load/load-util.h"
 #include "load/old/item-loader-savefile10.h"
 #include "object/object-stack.h"
@@ -90,22 +91,18 @@ static errr rd_store(player_type *player_ptr, int town_number, int store_number)
     store_ptr->last_visit = rd_s32b();
 
     for (int j = 0; j < inven_num; j++) {
-        object_type forge;
-        object_type *q_ptr;
-        q_ptr = &forge;
-        q_ptr->wipe();
-
-        rd_item(q_ptr);
-
+        object_type item;
+        auto item_loader = ItemLoaderFactory::get_item_loader();
+        item_loader->rd_item(&item);
         auto stock_max = store_get_stock_max(i2enum<StoreSaleType>(store_number));
         if (store_ptr->stock_num >= stock_max)
             continue;
 
         if (sort) {
-            home_carry_load(player_ptr, store_ptr, q_ptr);
+            home_carry_load(player_ptr, store_ptr, &item);
         } else {
             int k = store_ptr->stock_num++;
-            (&store_ptr->stock[k])->copy_from(q_ptr);
+            (&store_ptr->stock[k])->copy_from(&item);
         }
     }