diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-04-01 11:40:37 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-04-01 11:40:41 +0200 |
commit | ce60630c42e232bf81f22019e3499d6036a68f7e (patch) | |
tree | 08c7615faf264149229fbc681b708d5bd14d2259 /src | |
parent | 1d41d71eff082bb3232962ac6c4c68051f771da0 (diff) | |
download | mana-ce60630c42e232bf81f22019e3499d6036a68f7e.tar.gz mana-ce60630c42e232bf81f22019e3499d6036a68f7e.tar.bz2 mana-ce60630c42e232bf81f22019e3499d6036a68f7e.tar.xz mana-ce60630c42e232bf81f22019e3499d6036a68f7e.zip |
Fixed crash on exit when CharCreateDialog is open
* Displayed Being was deleting its SpeechBubble after the
WindowContainer had already deleted it. Resolved by registering a
DeathListener.
* On dialog deletion, the CharHandler had become a roaming pointer but
was still accessed.
Diffstat (limited to 'src')
-rw-r--r-- | src/being.cpp | 10 | ||||
-rw-r--r-- | src/being.h | 7 | ||||
-rw-r--r-- | src/gui/charcreatedialog.cpp | 3 | ||||
-rw-r--r-- | src/net/net.cpp | 24 |
4 files changed, 34 insertions, 10 deletions
diff --git a/src/being.cpp b/src/being.cpp index bbecf712..d239b9e8 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -70,6 +70,7 @@ Being::Being(int id, Type type, int subtype, Map *map) setType(type, subtype); mSpeechBubble = new SpeechBubble; + mSpeechBubble->addDeathListener(this); mMoveSpeed = Net::getPlayerHandler()->getDefaultMoveSpeed(); @@ -82,9 +83,6 @@ Being::~Being() delete mSpeechBubble; delete mDispName; delete mText; - mSpeechBubble = nullptr; - mDispName = nullptr; - mText = nullptr; } /** @@ -1395,6 +1393,12 @@ void Being::event(Event::Channel channel, const Event &event) } } +void Being::death(const gcn::Event &event) +{ + if (event.getSource() == mSpeechBubble) + mSpeechBubble = nullptr; +} + void Being::setMap(Map *map) { for (auto &spriteState : mSpriteStates) diff --git a/src/being.h b/src/being.h index 6cc0575f..38f5f149 100644 --- a/src/being.h +++ b/src/being.h @@ -31,6 +31,7 @@ #include "utils/time.h" #include <guichan/color.hpp> +#include <guichan/deathlistener.hpp> #include <cstdint> #include <map> @@ -61,7 +62,7 @@ enum class Gender HIDDEN = 3 }; -class Being : public ActorSprite, public EventListener +class Being : public ActorSprite, public EventListener, public gcn::DeathListener { public: /** @@ -438,8 +439,12 @@ class Being : public ActorSprite, public EventListener void talkTo(); + // EventListener void event(Event::Channel channel, const Event &event) override; + // gcn::DeathListener + void death(const gcn::Event &event) override; + void setMap(Map *map) final; /** diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index fb834933..d5bdf3ca 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -167,7 +167,8 @@ CharCreateDialog::~CharCreateDialog() delete mPlayer; // Make sure the char server handler knows that we're gone - Net::getCharHandler()->setCharCreateDialog(nullptr); + if (auto charHandler = Net::getCharHandler()) + charHandler->setCharCreateDialog(nullptr); } void CharCreateDialog::action(const gcn::ActionEvent &event) diff --git a/src/net/net.cpp b/src/net/net.cpp index dc86bc89..a2771244 100644 --- a/src/net/net.cpp +++ b/src/net/net.cpp @@ -176,11 +176,25 @@ void connectToServer(ServerInfo &server) void unload() { - if (generalHandler) - { - generalHandler->unload(); - delete generalHandler; - } + if (!generalHandler) + return; + + generalHandler->unload(); + delete generalHandler; + + adminHandler = nullptr; + charHandler = nullptr; + chatHandler = nullptr; + generalHandler = nullptr; + inventoryHandler = nullptr; + loginHandler = nullptr; + gameHandler = nullptr; + guildHandler = nullptr; + npcHandler = nullptr; + partyHandler = nullptr; + playerHandler = nullptr; + abilityHandler = nullptr; + tradeHandler = nullptr; } ServerType getNetworkType() |