Remove unnecessary pointer in savegame_newmenu_items

The pointer is only used by the constructor, so there is no need to
store it in the object.

Rework the allocation of the trailing storage to avoid the use of
placement new on a uint8_t[].
This commit is contained in:
Kp 2023-05-14 18:41:36 +00:00
parent 26d8c2881e
commit da39846514

View file

@ -162,7 +162,6 @@ struct savegame_newmenu_items
}; };
static constexpr unsigned decorative_item_count = 1; static constexpr unsigned decorative_item_count = 1;
using imenu_description_buffers_array = std::array<ntstring<NM_MAX_TEXT_LEN>, NUM_SAVES>; using imenu_description_buffers_array = std::array<ntstring<NM_MAX_TEXT_LEN>, NUM_SAVES>;
imenu_description_buffers_array *const user_entered_savegame_descriptions;
d_game_unique_state::savegame_description *const caller_savegame_description; d_game_unique_state::savegame_description *const caller_savegame_description;
d_game_unique_state::savegame_file_path &savegame_file_path; d_game_unique_state::savegame_file_path &savegame_file_path;
enumerated_array<d_game_unique_state::savegame_file_path, NUM_SAVES, d_game_unique_state::save_slot> savegame_file_paths; enumerated_array<d_game_unique_state::savegame_file_path, NUM_SAVES, d_game_unique_state::save_slot> savegame_file_paths;
@ -182,7 +181,7 @@ struct savegame_newmenu_items
* savegame slot in use, return true. This does not test whether * savegame slot in use, return true. This does not test whether
* there currently exists a savegame in the specified slot. * there currently exists a savegame in the specified slot.
*/ */
static unsigned valid_savegame_index(void *const user_entered_savegame_descriptions, const d_game_unique_state::save_slot selection) static unsigned valid_savegame_index(const d_game_unique_state::savegame_description *const user_entered_savegame_descriptions, const d_game_unique_state::save_slot selection)
{ {
return user_entered_savegame_descriptions return user_entered_savegame_descriptions
? GameUniqueState.valid_save_slot(selection) ? GameUniqueState.valid_save_slot(selection)
@ -190,7 +189,7 @@ struct savegame_newmenu_items
} }
unsigned valid_savegame_index(const d_game_unique_state::save_slot selection) const unsigned valid_savegame_index(const d_game_unique_state::save_slot selection) const
{ {
return valid_savegame_index(user_entered_savegame_descriptions, selection); return valid_savegame_index(caller_savegame_description, selection);
} }
std::size_t get_count_valid_menuitem_entries(d_game_unique_state::savegame_description *const savegame_description) const std::size_t get_count_valid_menuitem_entries(d_game_unique_state::savegame_description *const savegame_description) const
{ {
@ -198,14 +197,30 @@ struct savegame_newmenu_items
} }
}; };
struct savegame_chooser_newmenu : savegame_newmenu_items, newmenu struct savegame_chooser_newmenu final : savegame_newmenu_items, newmenu
{ {
enum class trailing_storage_size : std::size_t
{
};
static void *operator new(std::size_t bytes) = delete;
static void *operator new(std::size_t bytes, const trailing_storage_size extra_bytes)
{
return ::operator new(bytes + static_cast<std::size_t>(extra_bytes));
}
static void operator delete(void *p)
{
::operator delete(p);
}
static void operator delete(void *p, trailing_storage_size)
{
::operator delete(p);
}
virtual window_event_result event_handler(const d_event &) override; virtual window_event_result event_handler(const d_event &) override;
static std::unique_ptr<savegame_chooser_newmenu> create(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path); static std::unique_ptr<savegame_chooser_newmenu> create(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path);
private: private:
void draw_handler(grs_canvas &canvas, const grs_bitmap &bmp); void draw_handler(grs_canvas &canvas, const grs_bitmap &bmp);
void draw_handler(); void draw_handler();
savegame_chooser_newmenu(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *, d_game_unique_state::savegame_file_path &, imenu_description_buffers_array *); savegame_chooser_newmenu(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *, d_game_unique_state::savegame_file_path &);
d_game_unique_state::save_slot build_save_slot_from_citem() const d_game_unique_state::save_slot build_save_slot_from_citem() const
{ {
if (citem < decorative_item_count) if (citem < decorative_item_count)
@ -216,18 +231,18 @@ private:
std::unique_ptr<savegame_chooser_newmenu> savegame_chooser_newmenu::create(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path) std::unique_ptr<savegame_chooser_newmenu> savegame_chooser_newmenu::create(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path)
{ {
std::unique_ptr<uint8_t[]> p(savegame_description /* If savegame_description is not nullptr, then this is a request to
/* request to create a "Save game" menu */ * create a "Save game" menu. Otherwise, it is a request to create a
? reinterpret_cast<uint8_t *>(new typename std::aligned_union<sizeof(savegame_chooser_newmenu) + sizeof(savegame_chooser_newmenu::imenu_description_buffers_array), savegame_chooser_newmenu>::type) * "Load game" menu.
/* request to create a "Load game" menu */ */
: reinterpret_cast<uint8_t *>(new typename std::aligned_union<0 /* no extra storage needed, and aligned_union will ensure the value is sufficient for the aligned type */, savegame_chooser_newmenu>::type) const savegame_chooser_newmenu::trailing_storage_size extra_bytes{
); savegame_description ? sizeof(savegame_chooser_newmenu::imenu_description_buffers_array) : 0
new (p.get()) savegame_chooser_newmenu(caption, src, savegame_description, savegame_file_path, savegame_description ? reinterpret_cast<imenu_description_buffers_array *>(p.get() + sizeof(savegame_chooser_newmenu)) : nullptr); };
return std::unique_ptr<savegame_chooser_newmenu>(reinterpret_cast<savegame_chooser_newmenu *>(p.release())); return std::unique_ptr<savegame_chooser_newmenu>(new (extra_bytes) savegame_chooser_newmenu(caption, src, savegame_description, savegame_file_path));
} }
savegame_chooser_newmenu::savegame_chooser_newmenu(menu_subtitle subtitle, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path, imenu_description_buffers_array *const user_entered_savegame_descriptions) : savegame_chooser_newmenu::savegame_chooser_newmenu(menu_subtitle subtitle, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path) :
savegame_newmenu_items(savegame_description, savegame_file_path, user_entered_savegame_descriptions), savegame_newmenu_items(savegame_description, savegame_file_path, savegame_description ? reinterpret_cast<savegame_newmenu_items::imenu_description_buffers_array *>(this + 1) : nullptr),
newmenu(menu_title{nullptr}, subtitle, menu_filename{nullptr}, tiny_mode_flag::normal, tab_processing_flag::ignore, adjusted_citem::create(unchecked_partial_range(m, get_count_valid_menuitem_entries(savegame_description)), decorative_item_count), src) newmenu(menu_title{nullptr}, subtitle, menu_filename{nullptr}, tiny_mode_flag::normal, tab_processing_flag::ignore, adjusted_citem::create(unchecked_partial_range(m, get_count_valid_menuitem_entries(savegame_description)), decorative_item_count), src)
{ {
} }
@ -975,7 +990,6 @@ uint8_t read_savegame_properties(const std::size_t savegame_index, d_game_unique
} }
savegame_newmenu_items::savegame_newmenu_items(d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path, imenu_description_buffers_array *const user_entered_savegame_descriptions) : savegame_newmenu_items::savegame_newmenu_items(d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path, imenu_description_buffers_array *const user_entered_savegame_descriptions) :
user_entered_savegame_descriptions(user_entered_savegame_descriptions),
caller_savegame_description(savegame_description), caller_savegame_description(savegame_description),
savegame_file_path(savegame_file_path) savegame_file_path(savegame_file_path)
{ {