Fix memory management (take 2)

This commit is contained in:
Gregor Parzefall 2024-04-13 16:51:46 +02:00
parent df07777390
commit 16e3161d30
2 changed files with 35 additions and 13 deletions

View File

@ -271,7 +271,7 @@ AutoHideButtonBar::AutoHideButtonBar(IrrlichtDevice *device, ISimpleTextureSourc
load_button_texture(starter_gui_button, starter_img, starter_rect,
m_texturesource, m_driver);
m_starter.grab(starter_gui_button);
m_starter = grab_gui_element<IGUIButton>(starter_gui_button);
m_dir = dir;
}
@ -325,7 +325,7 @@ void AutoHideButtonBar::addButton(touch_gui_button_id id, const std::string &ima
button_info btn{};
btn.keycode = id_to_keycode(id);
btn.gui_button.grab(btn_gui_button);
btn.gui_button = grab_gui_element<IGUIButton>(btn_gui_button);
m_buttons.push_back(btn);
}
@ -437,26 +437,26 @@ TouchScreenGUI::TouchScreenGUI(IrrlichtDevice *device, ISimpleTextureSource *tsr
// Initialize joystick display "button".
// Joystick is placed on the bottom left of screen.
if (m_fixed_joystick) {
m_joystick_btn_off.grab(makeJoystickButton(joystick_off_id,
m_joystick_btn_off = grab_gui_element<IGUIButton>(makeJoystickButton(joystick_off_id,
recti(m_button_size,
m_screensize.Y - m_button_size * 4,
m_button_size * 4,
m_screensize.Y - m_button_size), true));
} else {
m_joystick_btn_off.grab(makeJoystickButton(joystick_off_id,
m_joystick_btn_off = grab_gui_element<IGUIButton>(makeJoystickButton(joystick_off_id,
recti(m_button_size,
m_screensize.Y - m_button_size * 3,
m_button_size * 3,
m_screensize.Y - m_button_size), true));
}
m_joystick_btn_bg.grab(makeJoystickButton(joystick_bg_id,
m_joystick_btn_bg = grab_gui_element<IGUIButton>(makeJoystickButton(joystick_bg_id,
recti(m_button_size,
m_screensize.Y - m_button_size * 4,
m_button_size * 4,
m_screensize.Y - m_button_size), false));
m_joystick_btn_center.grab(makeJoystickButton(joystick_center_id,
m_joystick_btn_center = grab_gui_element<IGUIButton>(makeJoystickButton(joystick_center_id,
recti(0, 0, m_button_size, m_button_size), false));
// init jump button
@ -539,7 +539,7 @@ void TouchScreenGUI::addButton(touch_gui_button_id id, const std::string &image,
button_info &btn = m_buttons.emplace_back();
btn.keycode = id_to_keycode(id);
btn.gui_button.grab(btn_gui_button);
btn.gui_button = grab_gui_element<IGUIButton>(btn_gui_button);
}
IGUIButton *TouchScreenGUI::makeJoystickButton(touch_gui_button_id id,

View File

@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include "irr_ptr.h"
#include "irrlichttypes.h"
#include <IEventReceiver.h>
#include <IGUIButton.h>
@ -39,6 +38,29 @@ using namespace irr;
using namespace irr::core;
using namespace irr::gui;
// We cannot use irr_ptr for Irrlicht GUI elements we own.
// Option 1: Pass IGUIElement* returned by IGUIEnvironment::add* into irr_ptr
// constructor.
// -> We steal the reference owned by IGUIEnvironment and drop it later,
// causing the IGUIElement to be deleted while IGUIEnvironment still
// references it.
// Option 2: Pass IGUIElement* returned by IGUIEnvironment::add* into irr_ptr::grab.
// -> We add another reference and drop it later, but since IGUIEnvironment
// still references the IGUIElement, it is never deleted.
// To make IGUIEnvironment drop its reference to the IGUIElement, we have to call
// IGUIElement::remove, so that's what we'll do.
template <typename T>
std::shared_ptr<T> grab_gui_element(T *element)
{
static_assert(std::is_base_of_v<IGUIElement, T>,
"grab_gui_element only works for IGUIElement");
return std::shared_ptr<T>(element, [](T *e) {
e->remove();
});
}
enum class TapState
{
None,
@ -101,7 +123,7 @@ struct button_info
float repeat_counter;
EKEY_CODE keycode;
std::vector<size_t> pointer_ids;
irr_ptr<IGUIButton> gui_button = nullptr;
std::shared_ptr<IGUIButton> gui_button = nullptr;
enum {
NOT_TOGGLEABLE,
@ -144,7 +166,7 @@ private:
IGUIEnvironment *m_guienv = nullptr;
IEventReceiver *m_receiver = nullptr;
ISimpleTextureSource *m_texturesource = nullptr;
irr_ptr<IGUIButton> m_starter;
std::shared_ptr<IGUIButton> m_starter;
std::vector<button_info> m_buttons;
v2s32 m_upper_left;
@ -244,9 +266,9 @@ private:
bool m_fixed_joystick = false;
bool m_joystick_triggers_aux1 = false;
bool m_draw_crosshair = false;
irr_ptr<IGUIButton> m_joystick_btn_off;
irr_ptr<IGUIButton> m_joystick_btn_bg;
irr_ptr<IGUIButton> m_joystick_btn_center;
std::shared_ptr<IGUIButton> m_joystick_btn_off;
std::shared_ptr<IGUIButton> m_joystick_btn_bg;
std::shared_ptr<IGUIButton> m_joystick_btn_center;
std::vector<button_info> m_buttons;