From d6ce7695a1fbecb7c3617cda3fd54f2db9437f6b Mon Sep 17 00:00:00 2001 From: Hourier <66951241+Hourier@users.noreply.github.com> Date: Sat, 16 Oct 2021 23:38:01 +0900 Subject: [PATCH] =?utf8?q?[Refactor]=20#1796=20ItemLoaderBase=E3=80=81Item?= =?utf8?q?LoaderFactory=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92=E4=BD=9C?= =?utf8?q?=E3=81=A3=E3=81=A6=E3=82=A2=E3=82=A4=E3=83=86=E3=83=A0=E8=AA=AD?= =?utf8?q?=E3=81=BF=E8=BE=BC=E3=81=BF=E5=87=A6=E7=90=86=E7=94=A8=E3=81=AE?= =?utf8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92=E5=88=86=E9=9B=A2=E3=81=97?= =?utf8?q?=E3=82=84=E3=81=99=E3=81=8F=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Hengband/Hengband/Hengband.vcxproj | 5 +++ Hengband/Hengband/Hengband.vcxproj.filters | 18 +++++++++++ src/Makefile.am | 4 +++ src/load/floor-loader.cpp | 16 ++++----- src/load/inventory-loader.cpp | 22 ++++++------- src/load/item/item-loader-base.cpp | 44 +++++++++++++++++++++++++ src/load/item/item-loader-base.h | 15 +++++++++ src/load/item/item-loader-factory.cpp | 52 ++++++++++++++++++++++++++++++ src/load/item/item-loader-factory.h | 14 ++++++++ src/load/item/item-loader-version-types.h | 6 ++++ src/load/load.cpp | 6 ++-- src/load/old/item-loader-savefile10.cpp | 41 +---------------------- src/load/old/item-loader-savefile10.h | 10 ++++-- src/load/old/load-v1-5-0.cpp | 9 +++--- src/load/store-loader.cpp | 15 ++++----- 15 files changed, 200 insertions(+), 77 deletions(-) create mode 100644 src/load/item/item-loader-base.cpp create mode 100644 src/load/item/item-loader-base.h create mode 100644 src/load/item/item-loader-factory.cpp create mode 100644 src/load/item/item-loader-factory.h create mode 100644 src/load/item/item-loader-version-types.h diff --git a/Hengband/Hengband/Hengband.vcxproj b/Hengband/Hengband/Hengband.vcxproj index 4f25020dd..0c7d4a4c5 100644 --- a/Hengband/Hengband/Hengband.vcxproj +++ b/Hengband/Hengband/Hengband.vcxproj @@ -269,6 +269,8 @@ + + @@ -922,6 +924,9 @@ + + + diff --git a/Hengband/Hengband/Hengband.vcxproj.filters b/Hengband/Hengband/Hengband.vcxproj.filters index 376fbde91..108595987 100644 --- a/Hengband/Hengband/Hengband.vcxproj.filters +++ b/Hengband/Hengband/Hengband.vcxproj.filters @@ -2364,6 +2364,12 @@ load\old + + load\item + + + load\item + @@ -5124,6 +5130,15 @@ load\old + + load\item + + + load\item + + + load\item + @@ -5349,6 +5364,9 @@ {46523373-91fb-436b-89c6-14ad74b88f5d} + + {346bc9ba-a477-404f-bc72-2ad9c1ec6daf} + diff --git a/src/Makefile.am b/src/Makefile.am index aa017bdd4..eb56fba8b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/load/floor-loader.cpp b/src/load/floor-loader.cpp index 398418f82..de6ad831f 100644 --- a/src/load/floor-loader.cpp +++ b/src/load/floor-loader.cpp @@ -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(); diff --git a/src/load/inventory-loader.cpp b/src/load/inventory-loader.cpp index 0f5118a57..ec3ca09af 100644 --- a/src/load/inventory-loader.cpp +++ b/src/load/inventory-loader.cpp @@ -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 index 000000000..f4854d142 --- /dev/null +++ b/src/load/item/item-loader-base.cpp @@ -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 index 000000000..606d1284a --- /dev/null +++ b/src/load/item/item-loader-base.h @@ -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 index 000000000..d0526e65c --- /dev/null +++ b/src/load/item/item-loader-factory.cpp @@ -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 ItemLoaderFactory::get_item_loader() +{ + auto version = get_version(); + switch (version) { + case ItemLoaderVersionType::LOAD10: + return std::make_shared(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 index 000000000..74d580711 --- /dev/null +++ b/src/load/item/item-loader-factory.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +enum class ItemLoaderVersionType; +class ItemLoaderBase; +class ItemLoaderFactory { +public: + static std::shared_ptr 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 index 000000000..8ff76ef09 --- /dev/null +++ b/src/load/item/item-loader-version-types.h @@ -0,0 +1,6 @@ +#pragma once + +enum class ItemLoaderVersionType { + LOAD10, + LOAD11, +}; diff --git a/src/load/load.cpp b/src/load/load.cpp index 9e9cc012b..193b3fd46 100644 --- a/src/load/load.cpp +++ b/src/load/load.cpp @@ -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) diff --git a/src/load/old/item-loader-savefile10.cpp b/src/load/old/item-loader-savefile10.cpp index f215961d9..11b7d77a6 100644 --- a/src/load/old/item-loader-savefile10.cpp +++ b/src/load/old/item-loader-savefile10.cpp @@ -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")); -} diff --git a/src/load/old/item-loader-savefile10.h b/src/load/old/item-loader-savefile10.h index 5cd358f6c..cb218c0f5 100644 --- a/src/load/old/item-loader-savefile10.h +++ b/src/load/old/item-loader-savefile10.h @@ -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; +}; diff --git a/src/load/old/load-v1-5-0.cpp b/src/load/old/load-v1-5-0.cpp index 09e0d731d..9d12b60f4 100644 --- a/src/load/old/load-v1-5-0.cpp +++ b/src/load/old/load-v1-5-0.cpp @@ -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); } diff --git a/src/load/store-loader.cpp b/src/load/store-loader.cpp index 97044ed2b..b9cb28828 100644 --- a/src/load/store-loader.cpp +++ b/src/load/store-loader.cpp @@ -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(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); } } -- 2.11.0